ActivityManagerService.java revision 6ba042b51496b9763d721b6dca8a591c323d648c
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    if (!showBackground && UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1211                            && proc.pid != MY_PID) {
1212                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1213                        if (res != null) {
1214                            res.set(0);
1215                        }
1216                        return;
1217                    }
1218                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1219                        Dialog d = new AppErrorDialog(mContext,
1220                                ActivityManagerService.this, res, proc);
1221                        d.show();
1222                        proc.crashDialog = d;
1223                    } else {
1224                        // The device is asleep, so just pretend that the user
1225                        // saw a crash dialog and hit "force quit".
1226                        if (res != null) {
1227                            res.set(0);
1228                        }
1229                    }
1230                }
1231
1232                ensureBootCompleted();
1233            } break;
1234            case SHOW_NOT_RESPONDING_MSG: {
1235                synchronized (ActivityManagerService.this) {
1236                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1237                    ProcessRecord proc = (ProcessRecord)data.get("app");
1238                    if (proc != null && proc.anrDialog != null) {
1239                        Slog.e(TAG, "App already has anr dialog: " + proc);
1240                        return;
1241                    }
1242
1243                    Intent intent = new Intent("android.intent.action.ANR");
1244                    if (!mProcessesReady) {
1245                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1246                                | Intent.FLAG_RECEIVER_FOREGROUND);
1247                    }
1248                    broadcastIntentLocked(null, null, intent,
1249                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1250                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1251
1252                    if (mShowDialogs) {
1253                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1254                                mContext, proc, (ActivityRecord)data.get("activity"),
1255                                msg.arg1 != 0);
1256                        d.show();
1257                        proc.anrDialog = d;
1258                    } else {
1259                        // Just kill the app if there is no dialog to be shown.
1260                        killAppAtUsersRequest(proc, null);
1261                    }
1262                }
1263
1264                ensureBootCompleted();
1265            } break;
1266            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1267                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord proc = (ProcessRecord) data.get("app");
1270                    if (proc == null) {
1271                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1272                        break;
1273                    }
1274                    if (proc.crashDialog != null) {
1275                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1276                        return;
1277                    }
1278                    AppErrorResult res = (AppErrorResult) data.get("result");
1279                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1280                        Dialog d = new StrictModeViolationDialog(mContext,
1281                                ActivityManagerService.this, res, proc);
1282                        d.show();
1283                        proc.crashDialog = d;
1284                    } else {
1285                        // The device is asleep, so just pretend that the user
1286                        // saw a crash dialog and hit "force quit".
1287                        res.set(0);
1288                    }
1289                }
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_FACTORY_ERROR_MSG: {
1293                Dialog d = new FactoryErrorDialog(
1294                    mContext, msg.getData().getCharSequence("msg"));
1295                d.show();
1296                ensureBootCompleted();
1297            } break;
1298            case UPDATE_CONFIGURATION_MSG: {
1299                final ContentResolver resolver = mContext.getContentResolver();
1300                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1301            } break;
1302            case GC_BACKGROUND_PROCESSES_MSG: {
1303                synchronized (ActivityManagerService.this) {
1304                    performAppGcsIfAppropriateLocked();
1305                }
1306            } break;
1307            case WAIT_FOR_DEBUGGER_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    ProcessRecord app = (ProcessRecord)msg.obj;
1310                    if (msg.arg1 != 0) {
1311                        if (!app.waitedForDebugger) {
1312                            Dialog d = new AppWaitingForDebuggerDialog(
1313                                    ActivityManagerService.this,
1314                                    mContext, app);
1315                            app.waitDialog = d;
1316                            app.waitedForDebugger = true;
1317                            d.show();
1318                        }
1319                    } else {
1320                        if (app.waitDialog != null) {
1321                            app.waitDialog.dismiss();
1322                            app.waitDialog = null;
1323                        }
1324                    }
1325                }
1326            } break;
1327            case SERVICE_TIMEOUT_MSG: {
1328                if (mDidDexOpt) {
1329                    mDidDexOpt = false;
1330                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1331                    nmsg.obj = msg.obj;
1332                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1333                    return;
1334                }
1335                mServices.serviceTimeout((ProcessRecord)msg.obj);
1336            } break;
1337            case UPDATE_TIME_ZONE: {
1338                synchronized (ActivityManagerService.this) {
1339                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1340                        ProcessRecord r = mLruProcesses.get(i);
1341                        if (r.thread != null) {
1342                            try {
1343                                r.thread.updateTimeZone();
1344                            } catch (RemoteException ex) {
1345                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1346                            }
1347                        }
1348                    }
1349                }
1350            } break;
1351            case CLEAR_DNS_CACHE_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1354                        ProcessRecord r = mLruProcesses.get(i);
1355                        if (r.thread != null) {
1356                            try {
1357                                r.thread.clearDnsCache();
1358                            } catch (RemoteException ex) {
1359                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1360                            }
1361                        }
1362                    }
1363                }
1364            } break;
1365            case UPDATE_HTTP_PROXY_MSG: {
1366                ProxyInfo proxy = (ProxyInfo)msg.obj;
1367                String host = "";
1368                String port = "";
1369                String exclList = "";
1370                Uri pacFileUrl = Uri.EMPTY;
1371                if (proxy != null) {
1372                    host = proxy.getHost();
1373                    port = Integer.toString(proxy.getPort());
1374                    exclList = proxy.getExclusionListAsString();
1375                    pacFileUrl = proxy.getPacFileUrl();
1376                }
1377                synchronized (ActivityManagerService.this) {
1378                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1379                        ProcessRecord r = mLruProcesses.get(i);
1380                        if (r.thread != null) {
1381                            try {
1382                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1383                            } catch (RemoteException ex) {
1384                                Slog.w(TAG, "Failed to update http proxy for: " +
1385                                        r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case SHOW_UID_ERROR_MSG: {
1392                String title = "System UIDs Inconsistent";
1393                String text = "UIDs on the system are inconsistent, you need to wipe your"
1394                        + " data partition or your device will be unstable.";
1395                Log.e(TAG, title + ": " + text);
1396                if (mShowDialogs) {
1397                    // XXX This is a temporary dialog, no need to localize.
1398                    AlertDialog d = new BaseErrorDialog(mContext);
1399                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1400                    d.setCancelable(false);
1401                    d.setTitle(title);
1402                    d.setMessage(text);
1403                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1404                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1405                    mUidAlert = d;
1406                    d.show();
1407                }
1408            } break;
1409            case IM_FEELING_LUCKY_MSG: {
1410                if (mUidAlert != null) {
1411                    mUidAlert.dismiss();
1412                    mUidAlert = null;
1413                }
1414            } break;
1415            case PROC_START_TIMEOUT_MSG: {
1416                if (mDidDexOpt) {
1417                    mDidDexOpt = false;
1418                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1419                    nmsg.obj = msg.obj;
1420                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1421                    return;
1422                }
1423                ProcessRecord app = (ProcessRecord)msg.obj;
1424                synchronized (ActivityManagerService.this) {
1425                    processStartTimedOutLocked(app);
1426                }
1427            } break;
1428            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1429                synchronized (ActivityManagerService.this) {
1430                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1431                }
1432            } break;
1433            case KILL_APPLICATION_MSG: {
1434                synchronized (ActivityManagerService.this) {
1435                    int appid = msg.arg1;
1436                    boolean restart = (msg.arg2 == 1);
1437                    Bundle bundle = (Bundle)msg.obj;
1438                    String pkg = bundle.getString("pkg");
1439                    String reason = bundle.getString("reason");
1440                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1441                            false, UserHandle.USER_ALL, reason);
1442                }
1443            } break;
1444            case FINALIZE_PENDING_INTENT_MSG: {
1445                ((PendingIntentRecord)msg.obj).completeFinalize();
1446            } break;
1447            case POST_HEAVY_NOTIFICATION_MSG: {
1448                INotificationManager inm = NotificationManager.getService();
1449                if (inm == null) {
1450                    return;
1451                }
1452
1453                ActivityRecord root = (ActivityRecord)msg.obj;
1454                ProcessRecord process = root.app;
1455                if (process == null) {
1456                    return;
1457                }
1458
1459                try {
1460                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1461                    String text = mContext.getString(R.string.heavy_weight_notification,
1462                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1463                    Notification notification = new Notification();
1464                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1465                    notification.when = 0;
1466                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1467                    notification.tickerText = text;
1468                    notification.defaults = 0; // please be quiet
1469                    notification.sound = null;
1470                    notification.vibrate = null;
1471                    notification.setLatestEventInfo(context, text,
1472                            mContext.getText(R.string.heavy_weight_notification_detail),
1473                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1474                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1475                                    new UserHandle(root.userId)));
1476
1477                    try {
1478                        int[] outId = new int[1];
1479                        inm.enqueueNotificationWithTag("android", "android", null,
1480                                R.string.heavy_weight_notification,
1481                                notification, outId, root.userId);
1482                    } catch (RuntimeException e) {
1483                        Slog.w(ActivityManagerService.TAG,
1484                                "Error showing notification for heavy-weight app", e);
1485                    } catch (RemoteException e) {
1486                    }
1487                } catch (NameNotFoundException e) {
1488                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1489                }
1490            } break;
1491            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1492                INotificationManager inm = NotificationManager.getService();
1493                if (inm == null) {
1494                    return;
1495                }
1496                try {
1497                    inm.cancelNotificationWithTag("android", null,
1498                            R.string.heavy_weight_notification,  msg.arg1);
1499                } catch (RuntimeException e) {
1500                    Slog.w(ActivityManagerService.TAG,
1501                            "Error canceling notification for service", e);
1502                } catch (RemoteException e) {
1503                }
1504            } break;
1505            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1506                synchronized (ActivityManagerService.this) {
1507                    checkExcessivePowerUsageLocked(true);
1508                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1510                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1511                }
1512            } break;
1513            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1514                synchronized (ActivityManagerService.this) {
1515                    ActivityRecord ar = (ActivityRecord)msg.obj;
1516                    if (mCompatModeDialog != null) {
1517                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1518                                ar.info.applicationInfo.packageName)) {
1519                            return;
1520                        }
1521                        mCompatModeDialog.dismiss();
1522                        mCompatModeDialog = null;
1523                    }
1524                    if (ar != null && false) {
1525                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1526                                ar.packageName)) {
1527                            int mode = mCompatModePackages.computeCompatModeLocked(
1528                                    ar.info.applicationInfo);
1529                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1530                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1531                                mCompatModeDialog = new CompatModeDialog(
1532                                        ActivityManagerService.this, mContext,
1533                                        ar.info.applicationInfo);
1534                                mCompatModeDialog.show();
1535                            }
1536                        }
1537                    }
1538                }
1539                break;
1540            }
1541            case DISPATCH_PROCESSES_CHANGED: {
1542                dispatchProcessesChanged();
1543                break;
1544            }
1545            case DISPATCH_PROCESS_DIED: {
1546                final int pid = msg.arg1;
1547                final int uid = msg.arg2;
1548                dispatchProcessDied(pid, uid);
1549                break;
1550            }
1551            case REPORT_MEM_USAGE_MSG: {
1552                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1553                Thread thread = new Thread() {
1554                    @Override public void run() {
1555                        final SparseArray<ProcessMemInfo> infoMap
1556                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1557                        for (int i=0, N=memInfos.size(); i<N; i++) {
1558                            ProcessMemInfo mi = memInfos.get(i);
1559                            infoMap.put(mi.pid, mi);
1560                        }
1561                        updateCpuStatsNow();
1562                        synchronized (mProcessCpuThread) {
1563                            final int N = mProcessCpuTracker.countStats();
1564                            for (int i=0; i<N; i++) {
1565                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1566                                if (st.vsize > 0) {
1567                                    long pss = Debug.getPss(st.pid, null);
1568                                    if (pss > 0) {
1569                                        if (infoMap.indexOfKey(st.pid) < 0) {
1570                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1571                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1572                                            mi.pss = pss;
1573                                            memInfos.add(mi);
1574                                        }
1575                                    }
1576                                }
1577                            }
1578                        }
1579
1580                        long totalPss = 0;
1581                        for (int i=0, N=memInfos.size(); i<N; i++) {
1582                            ProcessMemInfo mi = memInfos.get(i);
1583                            if (mi.pss == 0) {
1584                                mi.pss = Debug.getPss(mi.pid, null);
1585                            }
1586                            totalPss += mi.pss;
1587                        }
1588                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1589                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1590                                if (lhs.oomAdj != rhs.oomAdj) {
1591                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1592                                }
1593                                if (lhs.pss != rhs.pss) {
1594                                    return lhs.pss < rhs.pss ? 1 : -1;
1595                                }
1596                                return 0;
1597                            }
1598                        });
1599
1600                        StringBuilder tag = new StringBuilder(128);
1601                        StringBuilder stack = new StringBuilder(128);
1602                        tag.append("Low on memory -- ");
1603                        appendMemBucket(tag, totalPss, "total", false);
1604                        appendMemBucket(stack, totalPss, "total", true);
1605
1606                        StringBuilder logBuilder = new StringBuilder(1024);
1607                        logBuilder.append("Low on memory:\n");
1608
1609                        boolean firstLine = true;
1610                        int lastOomAdj = Integer.MIN_VALUE;
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613
1614                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1615                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1616                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1617                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1618                                if (lastOomAdj != mi.oomAdj) {
1619                                    lastOomAdj = mi.oomAdj;
1620                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1621                                        tag.append(" / ");
1622                                    }
1623                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1624                                        if (firstLine) {
1625                                            stack.append(":");
1626                                            firstLine = false;
1627                                        }
1628                                        stack.append("\n\t at ");
1629                                    } else {
1630                                        stack.append("$");
1631                                    }
1632                                } else {
1633                                    tag.append(" ");
1634                                    stack.append("$");
1635                                }
1636                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1637                                    appendMemBucket(tag, mi.pss, mi.name, false);
1638                                }
1639                                appendMemBucket(stack, mi.pss, mi.name, true);
1640                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1641                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1642                                    stack.append("(");
1643                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1644                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1645                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1646                                            stack.append(":");
1647                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1648                                        }
1649                                    }
1650                                    stack.append(")");
1651                                }
1652                            }
1653
1654                            logBuilder.append("  ");
1655                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1656                            logBuilder.append(' ');
1657                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1658                            logBuilder.append(' ');
1659                            ProcessList.appendRamKb(logBuilder, mi.pss);
1660                            logBuilder.append(" kB: ");
1661                            logBuilder.append(mi.name);
1662                            logBuilder.append(" (");
1663                            logBuilder.append(mi.pid);
1664                            logBuilder.append(") ");
1665                            logBuilder.append(mi.adjType);
1666                            logBuilder.append('\n');
1667                            if (mi.adjReason != null) {
1668                                logBuilder.append("                      ");
1669                                logBuilder.append(mi.adjReason);
1670                                logBuilder.append('\n');
1671                            }
1672                        }
1673
1674                        logBuilder.append("           ");
1675                        ProcessList.appendRamKb(logBuilder, totalPss);
1676                        logBuilder.append(" kB: TOTAL\n");
1677
1678                        long[] infos = new long[Debug.MEMINFO_COUNT];
1679                        Debug.getMemInfo(infos);
1680                        logBuilder.append("  MemInfo: ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1685                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1686                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1687                            logBuilder.append("  ZRAM: ");
1688                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1689                            logBuilder.append(" kB RAM, ");
1690                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1691                            logBuilder.append(" kB swap total, ");
1692                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1693                            logBuilder.append(" kB swap free\n");
1694                        }
1695                        Slog.i(TAG, logBuilder.toString());
1696
1697                        StringBuilder dropBuilder = new StringBuilder(1024);
1698                        /*
1699                        StringWriter oomSw = new StringWriter();
1700                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1701                        StringWriter catSw = new StringWriter();
1702                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1703                        String[] emptyArgs = new String[] { };
1704                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1705                        oomPw.flush();
1706                        String oomString = oomSw.toString();
1707                        */
1708                        dropBuilder.append(stack);
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append('\n');
1711                        dropBuilder.append(logBuilder);
1712                        dropBuilder.append('\n');
1713                        /*
1714                        dropBuilder.append(oomString);
1715                        dropBuilder.append('\n');
1716                        */
1717                        StringWriter catSw = new StringWriter();
1718                        synchronized (ActivityManagerService.this) {
1719                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1720                            String[] emptyArgs = new String[] { };
1721                            catPw.println();
1722                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1723                            catPw.println();
1724                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1725                                    false, false, null);
1726                            catPw.println();
1727                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1728                            catPw.flush();
1729                        }
1730                        dropBuilder.append(catSw.toString());
1731                        addErrorToDropBox("lowmem", null, "system_server", null,
1732                                null, tag.toString(), dropBuilder.toString(), null, null);
1733                        //Slog.i(TAG, "Sent to dropbox:");
1734                        //Slog.i(TAG, dropBuilder.toString());
1735                        synchronized (ActivityManagerService.this) {
1736                            long now = SystemClock.uptimeMillis();
1737                            if (mLastMemUsageReportTime < now) {
1738                                mLastMemUsageReportTime = now;
1739                            }
1740                        }
1741                    }
1742                };
1743                thread.start();
1744                break;
1745            }
1746            case REPORT_USER_SWITCH_MSG: {
1747                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1748                break;
1749            }
1750            case CONTINUE_USER_SWITCH_MSG: {
1751                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case USER_SWITCH_TIMEOUT_MSG: {
1755                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case IMMERSIVE_MODE_LOCK_MSG: {
1759                final boolean nextState = (msg.arg1 != 0);
1760                if (mUpdateLock.isHeld() != nextState) {
1761                    if (DEBUG_IMMERSIVE) {
1762                        final ActivityRecord r = (ActivityRecord) msg.obj;
1763                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1764                    }
1765                    if (nextState) {
1766                        mUpdateLock.acquire();
1767                    } else {
1768                        mUpdateLock.release();
1769                    }
1770                }
1771                break;
1772            }
1773            case PERSIST_URI_GRANTS_MSG: {
1774                writeGrantedUriPermissions();
1775                break;
1776            }
1777            case REQUEST_ALL_PSS_MSG: {
1778                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1779                break;
1780            }
1781            case START_PROFILES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    startProfilesLocked();
1784                }
1785                break;
1786            }
1787            case UPDATE_TIME: {
1788                synchronized (ActivityManagerService.this) {
1789                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1790                        ProcessRecord r = mLruProcesses.get(i);
1791                        if (r.thread != null) {
1792                            try {
1793                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1794                            } catch (RemoteException ex) {
1795                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1796                            }
1797                        }
1798                    }
1799                }
1800                break;
1801            }
1802            case SYSTEM_USER_START_MSG: {
1803                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1804                        Integer.toString(msg.arg1), msg.arg1);
1805                mSystemServiceManager.startUser(msg.arg1);
1806                break;
1807            }
1808            case SYSTEM_USER_CURRENT_MSG: {
1809                mBatteryStatsService.noteEvent(
1810                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1811                        Integer.toString(msg.arg2), msg.arg2);
1812                mBatteryStatsService.noteEvent(
1813                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1814                        Integer.toString(msg.arg1), msg.arg1);
1815                mSystemServiceManager.switchUser(msg.arg1);
1816                break;
1817            }
1818            case ENTER_ANIMATION_COMPLETE_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1821                    if (r != null && r.app != null && r.app.thread != null) {
1822                        try {
1823                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1824                        } catch (RemoteException e) {
1825                        }
1826                    }
1827                }
1828                break;
1829            }
1830            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1831                enableScreenAfterBoot();
1832                break;
1833            }
1834            }
1835        }
1836    };
1837
1838    static final int COLLECT_PSS_BG_MSG = 1;
1839
1840    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1841        @Override
1842        public void handleMessage(Message msg) {
1843            switch (msg.what) {
1844            case COLLECT_PSS_BG_MSG: {
1845                long start = SystemClock.uptimeMillis();
1846                MemInfoReader memInfo = null;
1847                synchronized (ActivityManagerService.this) {
1848                    if (mFullPssPending) {
1849                        mFullPssPending = false;
1850                        memInfo = new MemInfoReader();
1851                    }
1852                }
1853                if (memInfo != null) {
1854                    updateCpuStatsNow();
1855                    long nativeTotalPss = 0;
1856                    synchronized (mProcessCpuThread) {
1857                        final int N = mProcessCpuTracker.countStats();
1858                        for (int j=0; j<N; j++) {
1859                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1860                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1861                                // This is definitely an application process; skip it.
1862                                continue;
1863                            }
1864                            synchronized (mPidsSelfLocked) {
1865                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1866                                    // This is one of our own processes; skip it.
1867                                    continue;
1868                                }
1869                            }
1870                            nativeTotalPss += Debug.getPss(st.pid, null);
1871                        }
1872                    }
1873                    memInfo.readMemInfo();
1874                    synchronized (this) {
1875                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1876                                + (SystemClock.uptimeMillis()-start) + "ms");
1877                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1878                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1879                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1880                                        +memInfo.getSlabSizeKb(),
1881                                nativeTotalPss);
1882                    }
1883                }
1884
1885                int i=0, num=0;
1886                long[] tmp = new long[1];
1887                do {
1888                    ProcessRecord proc;
1889                    int procState;
1890                    int pid;
1891                    synchronized (ActivityManagerService.this) {
1892                        if (i >= mPendingPssProcesses.size()) {
1893                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1894                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1895                            mPendingPssProcesses.clear();
1896                            return;
1897                        }
1898                        proc = mPendingPssProcesses.get(i);
1899                        procState = proc.pssProcState;
1900                        if (proc.thread != null && procState == proc.setProcState) {
1901                            pid = proc.pid;
1902                        } else {
1903                            proc = null;
1904                            pid = 0;
1905                        }
1906                        i++;
1907                    }
1908                    if (proc != null) {
1909                        long pss = Debug.getPss(pid, tmp);
1910                        synchronized (ActivityManagerService.this) {
1911                            if (proc.thread != null && proc.setProcState == procState
1912                                    && proc.pid == pid) {
1913                                num++;
1914                                proc.lastPssTime = SystemClock.uptimeMillis();
1915                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1916                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1917                                        + ": " + pss + " lastPss=" + proc.lastPss
1918                                        + " state=" + ProcessList.makeProcStateString(procState));
1919                                if (proc.initialIdlePss == 0) {
1920                                    proc.initialIdlePss = pss;
1921                                }
1922                                proc.lastPss = pss;
1923                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1924                                    proc.lastCachedPss = pss;
1925                                }
1926                            }
1927                        }
1928                    }
1929                } while (true);
1930            }
1931            }
1932        }
1933    };
1934
1935    /**
1936     * Monitor for package changes and update our internal state.
1937     */
1938    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1939        @Override
1940        public void onPackageRemoved(String packageName, int uid) {
1941            // Remove all tasks with activities in the specified package from the list of recent tasks
1942            synchronized (ActivityManagerService.this) {
1943                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1944                    TaskRecord tr = mRecentTasks.get(i);
1945                    ComponentName cn = tr.intent.getComponent();
1946                    if (cn != null && cn.getPackageName().equals(packageName)) {
1947                        // If the package name matches, remove the task and kill the process
1948                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1949                    }
1950                }
1951            }
1952        }
1953
1954        @Override
1955        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1956            onPackageModified(packageName);
1957            return true;
1958        }
1959
1960        @Override
1961        public void onPackageModified(String packageName) {
1962            final PackageManager pm = mContext.getPackageManager();
1963            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1964                    new ArrayList<Pair<Intent, Integer>>();
1965            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1966            // Copy the list of recent tasks so that we don't hold onto the lock on
1967            // ActivityManagerService for long periods while checking if components exist.
1968            synchronized (ActivityManagerService.this) {
1969                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1970                    TaskRecord tr = mRecentTasks.get(i);
1971                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1972                }
1973            }
1974            // Check the recent tasks and filter out all tasks with components that no longer exist.
1975            Intent tmpI = new Intent();
1976            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1977                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1978                ComponentName cn = p.first.getComponent();
1979                if (cn != null && cn.getPackageName().equals(packageName)) {
1980                    try {
1981                        // Add the task to the list to remove if the component no longer exists
1982                        tmpI.setComponent(cn);
1983                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1984                            tasksToRemove.add(p.second);
1985                        }
1986                    } catch (Exception e) {}
1987                }
1988            }
1989            // Prune all the tasks with removed components from the list of recent tasks
1990            synchronized (ActivityManagerService.this) {
1991                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1992                    // Remove the task but don't kill the process (since other components in that
1993                    // package may still be running and in the background)
1994                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1995                }
1996            }
1997        }
1998
1999        @Override
2000        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2001            // Force stop the specified packages
2002            if (packages != null) {
2003                for (String pkg : packages) {
2004                    synchronized (ActivityManagerService.this) {
2005                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2006                                "finished booting")) {
2007                            return true;
2008                        }
2009                    }
2010                }
2011            }
2012            return false;
2013        }
2014    };
2015
2016    public void setSystemProcess() {
2017        try {
2018            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2019            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2020            ServiceManager.addService("meminfo", new MemBinder(this));
2021            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2022            ServiceManager.addService("dbinfo", new DbBinder(this));
2023            if (MONITOR_CPU_USAGE) {
2024                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2025            }
2026            ServiceManager.addService("permission", new PermissionController(this));
2027
2028            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2029                    "android", STOCK_PM_FLAGS);
2030            mSystemThread.installSystemApplicationInfo(info);
2031
2032            synchronized (this) {
2033                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2034                app.persistent = true;
2035                app.pid = MY_PID;
2036                app.maxAdj = ProcessList.SYSTEM_ADJ;
2037                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2038                mProcessNames.put(app.processName, app.uid, app);
2039                synchronized (mPidsSelfLocked) {
2040                    mPidsSelfLocked.put(app.pid, app);
2041                }
2042                updateLruProcessLocked(app, false, null);
2043                updateOomAdjLocked();
2044            }
2045        } catch (PackageManager.NameNotFoundException e) {
2046            throw new RuntimeException(
2047                    "Unable to find android system package", e);
2048        }
2049    }
2050
2051    public void setWindowManager(WindowManagerService wm) {
2052        mWindowManager = wm;
2053        mStackSupervisor.setWindowManager(wm);
2054    }
2055
2056    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2057        mUsageStatsService = usageStatsManager;
2058    }
2059
2060    public void startObservingNativeCrashes() {
2061        final NativeCrashListener ncl = new NativeCrashListener(this);
2062        ncl.start();
2063    }
2064
2065    public IAppOpsService getAppOpsService() {
2066        return mAppOpsService;
2067    }
2068
2069    static class MemBinder extends Binder {
2070        ActivityManagerService mActivityManagerService;
2071        MemBinder(ActivityManagerService activityManagerService) {
2072            mActivityManagerService = activityManagerService;
2073        }
2074
2075        @Override
2076        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2077            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2078                    != PackageManager.PERMISSION_GRANTED) {
2079                pw.println("Permission Denial: can't dump meminfo from from pid="
2080                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2081                        + " without permission " + android.Manifest.permission.DUMP);
2082                return;
2083            }
2084
2085            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2086        }
2087    }
2088
2089    static class GraphicsBinder extends Binder {
2090        ActivityManagerService mActivityManagerService;
2091        GraphicsBinder(ActivityManagerService activityManagerService) {
2092            mActivityManagerService = activityManagerService;
2093        }
2094
2095        @Override
2096        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2097            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2098                    != PackageManager.PERMISSION_GRANTED) {
2099                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2100                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2101                        + " without permission " + android.Manifest.permission.DUMP);
2102                return;
2103            }
2104
2105            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2106        }
2107    }
2108
2109    static class DbBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        DbBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump dbinfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            mActivityManagerService.dumpDbInfo(fd, pw, args);
2126        }
2127    }
2128
2129    static class CpuBinder extends Binder {
2130        ActivityManagerService mActivityManagerService;
2131        CpuBinder(ActivityManagerService activityManagerService) {
2132            mActivityManagerService = activityManagerService;
2133        }
2134
2135        @Override
2136        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2137            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2138                    != PackageManager.PERMISSION_GRANTED) {
2139                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2140                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2141                        + " without permission " + android.Manifest.permission.DUMP);
2142                return;
2143            }
2144
2145            synchronized (mActivityManagerService.mProcessCpuThread) {
2146                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2147                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2148                        SystemClock.uptimeMillis()));
2149            }
2150        }
2151    }
2152
2153    public static final class Lifecycle extends SystemService {
2154        private final ActivityManagerService mService;
2155
2156        public Lifecycle(Context context) {
2157            super(context);
2158            mService = new ActivityManagerService(context);
2159        }
2160
2161        @Override
2162        public void onStart() {
2163            mService.start();
2164        }
2165
2166        public ActivityManagerService getService() {
2167            return mService;
2168        }
2169    }
2170
2171    // Note: This method is invoked on the main thread but may need to attach various
2172    // handlers to other threads.  So take care to be explicit about the looper.
2173    public ActivityManagerService(Context systemContext) {
2174        mContext = systemContext;
2175        mFactoryTest = FactoryTest.getMode();
2176        mSystemThread = ActivityThread.currentActivityThread();
2177
2178        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2179
2180        mHandlerThread = new ServiceThread(TAG,
2181                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2182        mHandlerThread.start();
2183        mHandler = new MainHandler(mHandlerThread.getLooper());
2184
2185        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2186                "foreground", BROADCAST_FG_TIMEOUT, false);
2187        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2188                "background", BROADCAST_BG_TIMEOUT, true);
2189        mBroadcastQueues[0] = mFgBroadcastQueue;
2190        mBroadcastQueues[1] = mBgBroadcastQueue;
2191
2192        mServices = new ActiveServices(this);
2193        mProviderMap = new ProviderMap(this);
2194
2195        // TODO: Move creation of battery stats service outside of activity manager service.
2196        File dataDir = Environment.getDataDirectory();
2197        File systemDir = new File(dataDir, "system");
2198        systemDir.mkdirs();
2199        mBatteryStatsService = new BatteryStatsService(new File(
2200                systemDir, "batterystats.bin").toString(), mHandler);
2201        mBatteryStatsService.getActiveStatistics().readLocked();
2202        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2203        mOnBattery = DEBUG_POWER ? true
2204                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2205        mBatteryStatsService.getActiveStatistics().setCallback(this);
2206
2207        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2208
2209        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2210
2211        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2212
2213        // User 0 is the first and only user that runs at boot.
2214        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2215        mUserLru.add(Integer.valueOf(0));
2216        updateStartedUserArrayLocked();
2217
2218        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2219            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2220
2221        mConfiguration.setToDefaults();
2222        mConfiguration.setLocale(Locale.getDefault());
2223
2224        mConfigurationSeq = mConfiguration.seq = 1;
2225        mProcessCpuTracker.init();
2226
2227        mHasRecents = mContext.getResources().getBoolean(
2228                com.android.internal.R.bool.config_hasRecents);
2229
2230        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2231        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2232        mStackSupervisor = new ActivityStackSupervisor(this);
2233        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2234
2235        mProcessCpuThread = new Thread("CpuTracker") {
2236            @Override
2237            public void run() {
2238                while (true) {
2239                    try {
2240                        try {
2241                            synchronized(this) {
2242                                final long now = SystemClock.uptimeMillis();
2243                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2244                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2245                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2246                                //        + ", write delay=" + nextWriteDelay);
2247                                if (nextWriteDelay < nextCpuDelay) {
2248                                    nextCpuDelay = nextWriteDelay;
2249                                }
2250                                if (nextCpuDelay > 0) {
2251                                    mProcessCpuMutexFree.set(true);
2252                                    this.wait(nextCpuDelay);
2253                                }
2254                            }
2255                        } catch (InterruptedException e) {
2256                        }
2257                        updateCpuStatsNow();
2258                    } catch (Exception e) {
2259                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2260                    }
2261                }
2262            }
2263        };
2264
2265        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2266
2267        Watchdog.getInstance().addMonitor(this);
2268        Watchdog.getInstance().addThread(mHandler);
2269    }
2270
2271    public void setSystemServiceManager(SystemServiceManager mgr) {
2272        mSystemServiceManager = mgr;
2273    }
2274
2275    private void start() {
2276        Process.removeAllProcessGroups();
2277        mProcessCpuThread.start();
2278
2279        mBatteryStatsService.publish(mContext);
2280        mAppOpsService.publish(mContext);
2281        Slog.d("AppOps", "AppOpsService published");
2282        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2283    }
2284
2285    public void initPowerManagement() {
2286        mStackSupervisor.initPowerManagement();
2287        mBatteryStatsService.initPowerManagement();
2288    }
2289
2290    @Override
2291    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2292            throws RemoteException {
2293        if (code == SYSPROPS_TRANSACTION) {
2294            // We need to tell all apps about the system property change.
2295            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2296            synchronized(this) {
2297                final int NP = mProcessNames.getMap().size();
2298                for (int ip=0; ip<NP; ip++) {
2299                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2300                    final int NA = apps.size();
2301                    for (int ia=0; ia<NA; ia++) {
2302                        ProcessRecord app = apps.valueAt(ia);
2303                        if (app.thread != null) {
2304                            procs.add(app.thread.asBinder());
2305                        }
2306                    }
2307                }
2308            }
2309
2310            int N = procs.size();
2311            for (int i=0; i<N; i++) {
2312                Parcel data2 = Parcel.obtain();
2313                try {
2314                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2315                } catch (RemoteException e) {
2316                }
2317                data2.recycle();
2318            }
2319        }
2320        try {
2321            return super.onTransact(code, data, reply, flags);
2322        } catch (RuntimeException e) {
2323            // The activity manager only throws security exceptions, so let's
2324            // log all others.
2325            if (!(e instanceof SecurityException)) {
2326                Slog.wtf(TAG, "Activity Manager Crash", e);
2327            }
2328            throw e;
2329        }
2330    }
2331
2332    void updateCpuStats() {
2333        final long now = SystemClock.uptimeMillis();
2334        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2335            return;
2336        }
2337        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2338            synchronized (mProcessCpuThread) {
2339                mProcessCpuThread.notify();
2340            }
2341        }
2342    }
2343
2344    void updateCpuStatsNow() {
2345        synchronized (mProcessCpuThread) {
2346            mProcessCpuMutexFree.set(false);
2347            final long now = SystemClock.uptimeMillis();
2348            boolean haveNewCpuStats = false;
2349
2350            if (MONITOR_CPU_USAGE &&
2351                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2352                mLastCpuTime.set(now);
2353                haveNewCpuStats = true;
2354                mProcessCpuTracker.update();
2355                //Slog.i(TAG, mProcessCpu.printCurrentState());
2356                //Slog.i(TAG, "Total CPU usage: "
2357                //        + mProcessCpu.getTotalCpuPercent() + "%");
2358
2359                // Slog the cpu usage if the property is set.
2360                if ("true".equals(SystemProperties.get("events.cpu"))) {
2361                    int user = mProcessCpuTracker.getLastUserTime();
2362                    int system = mProcessCpuTracker.getLastSystemTime();
2363                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2364                    int irq = mProcessCpuTracker.getLastIrqTime();
2365                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2366                    int idle = mProcessCpuTracker.getLastIdleTime();
2367
2368                    int total = user + system + iowait + irq + softIrq + idle;
2369                    if (total == 0) total = 1;
2370
2371                    EventLog.writeEvent(EventLogTags.CPU,
2372                            ((user+system+iowait+irq+softIrq) * 100) / total,
2373                            (user * 100) / total,
2374                            (system * 100) / total,
2375                            (iowait * 100) / total,
2376                            (irq * 100) / total,
2377                            (softIrq * 100) / total);
2378                }
2379            }
2380
2381            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2382            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2383            synchronized(bstats) {
2384                synchronized(mPidsSelfLocked) {
2385                    if (haveNewCpuStats) {
2386                        if (mOnBattery) {
2387                            int perc = bstats.startAddingCpuLocked();
2388                            int totalUTime = 0;
2389                            int totalSTime = 0;
2390                            final int N = mProcessCpuTracker.countStats();
2391                            for (int i=0; i<N; i++) {
2392                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2393                                if (!st.working) {
2394                                    continue;
2395                                }
2396                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2397                                int otherUTime = (st.rel_utime*perc)/100;
2398                                int otherSTime = (st.rel_stime*perc)/100;
2399                                totalUTime += otherUTime;
2400                                totalSTime += otherSTime;
2401                                if (pr != null) {
2402                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2403                                    if (ps == null || !ps.isActive()) {
2404                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2405                                                pr.info.uid, pr.processName);
2406                                    }
2407                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2408                                            st.rel_stime-otherSTime);
2409                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2410                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2411                                } else {
2412                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2413                                    if (ps == null || !ps.isActive()) {
2414                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2415                                                bstats.mapUid(st.uid), st.name);
2416                                    }
2417                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2418                                            st.rel_stime-otherSTime);
2419                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2420                                }
2421                            }
2422                            bstats.finishAddingCpuLocked(perc, totalUTime,
2423                                    totalSTime, cpuSpeedTimes);
2424                        }
2425                    }
2426                }
2427
2428                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2429                    mLastWriteTime = now;
2430                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2431                }
2432            }
2433        }
2434    }
2435
2436    @Override
2437    public void batteryNeedsCpuUpdate() {
2438        updateCpuStatsNow();
2439    }
2440
2441    @Override
2442    public void batteryPowerChanged(boolean onBattery) {
2443        // When plugging in, update the CPU stats first before changing
2444        // the plug state.
2445        updateCpuStatsNow();
2446        synchronized (this) {
2447            synchronized(mPidsSelfLocked) {
2448                mOnBattery = DEBUG_POWER ? true : onBattery;
2449            }
2450        }
2451    }
2452
2453    /**
2454     * Initialize the application bind args. These are passed to each
2455     * process when the bindApplication() IPC is sent to the process. They're
2456     * lazily setup to make sure the services are running when they're asked for.
2457     */
2458    private HashMap<String, IBinder> getCommonServicesLocked() {
2459        if (mAppBindArgs == null) {
2460            mAppBindArgs = new HashMap<String, IBinder>();
2461
2462            // Setup the application init args
2463            mAppBindArgs.put("package", ServiceManager.getService("package"));
2464            mAppBindArgs.put("window", ServiceManager.getService("window"));
2465            mAppBindArgs.put(Context.ALARM_SERVICE,
2466                    ServiceManager.getService(Context.ALARM_SERVICE));
2467        }
2468        return mAppBindArgs;
2469    }
2470
2471    final void setFocusedActivityLocked(ActivityRecord r) {
2472        if (mFocusedActivity != r) {
2473            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2474            mFocusedActivity = r;
2475            if (r.task != null && r.task.voiceInteractor != null) {
2476                startRunningVoiceLocked();
2477            } else {
2478                finishRunningVoiceLocked();
2479            }
2480            mStackSupervisor.setFocusedStack(r);
2481            if (r != null) {
2482                mWindowManager.setFocusedApp(r.appToken, true);
2483            }
2484            applyUpdateLockStateLocked(r);
2485        }
2486    }
2487
2488    final void clearFocusedActivity(ActivityRecord r) {
2489        if (mFocusedActivity == r) {
2490            mFocusedActivity = null;
2491        }
2492    }
2493
2494    @Override
2495    public void setFocusedStack(int stackId) {
2496        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2497        synchronized (ActivityManagerService.this) {
2498            ActivityStack stack = mStackSupervisor.getStack(stackId);
2499            if (stack != null) {
2500                ActivityRecord r = stack.topRunningActivityLocked(null);
2501                if (r != null) {
2502                    setFocusedActivityLocked(r);
2503                }
2504            }
2505        }
2506    }
2507
2508    @Override
2509    public void notifyActivityDrawn(IBinder token) {
2510        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2511        synchronized (this) {
2512            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2513            if (r != null) {
2514                r.task.stack.notifyActivityDrawnLocked(r);
2515            }
2516        }
2517    }
2518
2519    final void applyUpdateLockStateLocked(ActivityRecord r) {
2520        // Modifications to the UpdateLock state are done on our handler, outside
2521        // the activity manager's locks.  The new state is determined based on the
2522        // state *now* of the relevant activity record.  The object is passed to
2523        // the handler solely for logging detail, not to be consulted/modified.
2524        final boolean nextState = r != null && r.immersive;
2525        mHandler.sendMessage(
2526                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2527    }
2528
2529    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2530        Message msg = Message.obtain();
2531        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2532        msg.obj = r.task.askedCompatMode ? null : r;
2533        mHandler.sendMessage(msg);
2534    }
2535
2536    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2537            String what, Object obj, ProcessRecord srcApp) {
2538        app.lastActivityTime = now;
2539
2540        if (app.activities.size() > 0) {
2541            // Don't want to touch dependent processes that are hosting activities.
2542            return index;
2543        }
2544
2545        int lrui = mLruProcesses.lastIndexOf(app);
2546        if (lrui < 0) {
2547            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2548                    + what + " " + obj + " from " + srcApp);
2549            return index;
2550        }
2551
2552        if (lrui >= index) {
2553            // Don't want to cause this to move dependent processes *back* in the
2554            // list as if they were less frequently used.
2555            return index;
2556        }
2557
2558        if (lrui >= mLruProcessActivityStart) {
2559            // Don't want to touch dependent processes that are hosting activities.
2560            return index;
2561        }
2562
2563        mLruProcesses.remove(lrui);
2564        if (index > 0) {
2565            index--;
2566        }
2567        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2568                + " in LRU list: " + app);
2569        mLruProcesses.add(index, app);
2570        return index;
2571    }
2572
2573    final void removeLruProcessLocked(ProcessRecord app) {
2574        int lrui = mLruProcesses.lastIndexOf(app);
2575        if (lrui >= 0) {
2576            if (lrui <= mLruProcessActivityStart) {
2577                mLruProcessActivityStart--;
2578            }
2579            if (lrui <= mLruProcessServiceStart) {
2580                mLruProcessServiceStart--;
2581            }
2582            mLruProcesses.remove(lrui);
2583        }
2584    }
2585
2586    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2587            ProcessRecord client) {
2588        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2589                || app.treatLikeActivity;
2590        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2591        if (!activityChange && hasActivity) {
2592            // The process has activities, so we are only allowing activity-based adjustments
2593            // to move it.  It should be kept in the front of the list with other
2594            // processes that have activities, and we don't want those to change their
2595            // order except due to activity operations.
2596            return;
2597        }
2598
2599        mLruSeq++;
2600        final long now = SystemClock.uptimeMillis();
2601        app.lastActivityTime = now;
2602
2603        // First a quick reject: if the app is already at the position we will
2604        // put it, then there is nothing to do.
2605        if (hasActivity) {
2606            final int N = mLruProcesses.size();
2607            if (N > 0 && mLruProcesses.get(N-1) == app) {
2608                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2609                return;
2610            }
2611        } else {
2612            if (mLruProcessServiceStart > 0
2613                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2614                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2615                return;
2616            }
2617        }
2618
2619        int lrui = mLruProcesses.lastIndexOf(app);
2620
2621        if (app.persistent && lrui >= 0) {
2622            // We don't care about the position of persistent processes, as long as
2623            // they are in the list.
2624            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2625            return;
2626        }
2627
2628        /* In progress: compute new position first, so we can avoid doing work
2629           if the process is not actually going to move.  Not yet working.
2630        int addIndex;
2631        int nextIndex;
2632        boolean inActivity = false, inService = false;
2633        if (hasActivity) {
2634            // Process has activities, put it at the very tipsy-top.
2635            addIndex = mLruProcesses.size();
2636            nextIndex = mLruProcessServiceStart;
2637            inActivity = true;
2638        } else if (hasService) {
2639            // Process has services, put it at the top of the service list.
2640            addIndex = mLruProcessActivityStart;
2641            nextIndex = mLruProcessServiceStart;
2642            inActivity = true;
2643            inService = true;
2644        } else  {
2645            // Process not otherwise of interest, it goes to the top of the non-service area.
2646            addIndex = mLruProcessServiceStart;
2647            if (client != null) {
2648                int clientIndex = mLruProcesses.lastIndexOf(client);
2649                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2650                        + app);
2651                if (clientIndex >= 0 && addIndex > clientIndex) {
2652                    addIndex = clientIndex;
2653                }
2654            }
2655            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2656        }
2657
2658        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2659                + mLruProcessActivityStart + "): " + app);
2660        */
2661
2662        if (lrui >= 0) {
2663            if (lrui < mLruProcessActivityStart) {
2664                mLruProcessActivityStart--;
2665            }
2666            if (lrui < mLruProcessServiceStart) {
2667                mLruProcessServiceStart--;
2668            }
2669            /*
2670            if (addIndex > lrui) {
2671                addIndex--;
2672            }
2673            if (nextIndex > lrui) {
2674                nextIndex--;
2675            }
2676            */
2677            mLruProcesses.remove(lrui);
2678        }
2679
2680        /*
2681        mLruProcesses.add(addIndex, app);
2682        if (inActivity) {
2683            mLruProcessActivityStart++;
2684        }
2685        if (inService) {
2686            mLruProcessActivityStart++;
2687        }
2688        */
2689
2690        int nextIndex;
2691        if (hasActivity) {
2692            final int N = mLruProcesses.size();
2693            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2694                // Process doesn't have activities, but has clients with
2695                // activities...  move it up, but one below the top (the top
2696                // should always have a real activity).
2697                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2698                mLruProcesses.add(N-1, app);
2699                // To keep it from spamming the LRU list (by making a bunch of clients),
2700                // we will push down any other entries owned by the app.
2701                final int uid = app.info.uid;
2702                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2703                    ProcessRecord subProc = mLruProcesses.get(i);
2704                    if (subProc.info.uid == uid) {
2705                        // We want to push this one down the list.  If the process after
2706                        // it is for the same uid, however, don't do so, because we don't
2707                        // want them internally to be re-ordered.
2708                        if (mLruProcesses.get(i-1).info.uid != uid) {
2709                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2710                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2711                            ProcessRecord tmp = mLruProcesses.get(i);
2712                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2713                            mLruProcesses.set(i-1, tmp);
2714                            i--;
2715                        }
2716                    } else {
2717                        // A gap, we can stop here.
2718                        break;
2719                    }
2720                }
2721            } else {
2722                // Process has activities, put it at the very tipsy-top.
2723                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2724                mLruProcesses.add(app);
2725            }
2726            nextIndex = mLruProcessServiceStart;
2727        } else if (hasService) {
2728            // Process has services, put it at the top of the service list.
2729            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2730            mLruProcesses.add(mLruProcessActivityStart, app);
2731            nextIndex = mLruProcessServiceStart;
2732            mLruProcessActivityStart++;
2733        } else  {
2734            // Process not otherwise of interest, it goes to the top of the non-service area.
2735            int index = mLruProcessServiceStart;
2736            if (client != null) {
2737                // If there is a client, don't allow the process to be moved up higher
2738                // in the list than that client.
2739                int clientIndex = mLruProcesses.lastIndexOf(client);
2740                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2741                        + " when updating " + app);
2742                if (clientIndex <= lrui) {
2743                    // Don't allow the client index restriction to push it down farther in the
2744                    // list than it already is.
2745                    clientIndex = lrui;
2746                }
2747                if (clientIndex >= 0 && index > clientIndex) {
2748                    index = clientIndex;
2749                }
2750            }
2751            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2752            mLruProcesses.add(index, app);
2753            nextIndex = index-1;
2754            mLruProcessActivityStart++;
2755            mLruProcessServiceStart++;
2756        }
2757
2758        // If the app is currently using a content provider or service,
2759        // bump those processes as well.
2760        for (int j=app.connections.size()-1; j>=0; j--) {
2761            ConnectionRecord cr = app.connections.valueAt(j);
2762            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2763                    && cr.binding.service.app != null
2764                    && cr.binding.service.app.lruSeq != mLruSeq
2765                    && !cr.binding.service.app.persistent) {
2766                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2767                        "service connection", cr, app);
2768            }
2769        }
2770        for (int j=app.conProviders.size()-1; j>=0; j--) {
2771            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2772            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2773                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2774                        "provider reference", cpr, app);
2775            }
2776        }
2777    }
2778
2779    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2780        if (uid == Process.SYSTEM_UID) {
2781            // The system gets to run in any process.  If there are multiple
2782            // processes with the same uid, just pick the first (this
2783            // should never happen).
2784            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2785            if (procs == null) return null;
2786            final int N = procs.size();
2787            for (int i = 0; i < N; i++) {
2788                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2789            }
2790        }
2791        ProcessRecord proc = mProcessNames.get(processName, uid);
2792        if (false && proc != null && !keepIfLarge
2793                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2794                && proc.lastCachedPss >= 4000) {
2795            // Turn this condition on to cause killing to happen regularly, for testing.
2796            if (proc.baseProcessTracker != null) {
2797                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2798            }
2799            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2800                    + "k from cached");
2801        } else if (proc != null && !keepIfLarge
2802                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2803                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2804            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2805            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2806                if (proc.baseProcessTracker != null) {
2807                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2808                }
2809                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2810                        + "k from cached");
2811            }
2812        }
2813        return proc;
2814    }
2815
2816    void ensurePackageDexOpt(String packageName) {
2817        IPackageManager pm = AppGlobals.getPackageManager();
2818        try {
2819            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2820                mDidDexOpt = true;
2821            }
2822        } catch (RemoteException e) {
2823        }
2824    }
2825
2826    boolean isNextTransitionForward() {
2827        int transit = mWindowManager.getPendingAppTransition();
2828        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2829                || transit == AppTransition.TRANSIT_TASK_OPEN
2830                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2831    }
2832
2833    final ProcessRecord startProcessLocked(String processName,
2834            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2835            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2836            boolean isolated, boolean keepIfLarge) {
2837        ProcessRecord app;
2838        if (!isolated) {
2839            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2840        } else {
2841            // If this is an isolated process, it can't re-use an existing process.
2842            app = null;
2843        }
2844        // We don't have to do anything more if:
2845        // (1) There is an existing application record; and
2846        // (2) The caller doesn't think it is dead, OR there is no thread
2847        //     object attached to it so we know it couldn't have crashed; and
2848        // (3) There is a pid assigned to it, so it is either starting or
2849        //     already running.
2850        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2851                + " app=" + app + " knownToBeDead=" + knownToBeDead
2852                + " thread=" + (app != null ? app.thread : null)
2853                + " pid=" + (app != null ? app.pid : -1));
2854        if (app != null && app.pid > 0) {
2855            if (!knownToBeDead || app.thread == null) {
2856                // We already have the app running, or are waiting for it to
2857                // come up (we have a pid but not yet its thread), so keep it.
2858                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2859                // If this is a new package in the process, add the package to the list
2860                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2861                return app;
2862            }
2863
2864            // An application record is attached to a previous process,
2865            // clean it up now.
2866            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2867            Process.killProcessGroup(app.info.uid, app.pid);
2868            handleAppDiedLocked(app, true, true);
2869        }
2870
2871        String hostingNameStr = hostingName != null
2872                ? hostingName.flattenToShortString() : null;
2873
2874        if (!isolated) {
2875            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2876                // If we are in the background, then check to see if this process
2877                // is bad.  If so, we will just silently fail.
2878                if (mBadProcesses.get(info.processName, info.uid) != null) {
2879                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2880                            + "/" + info.processName);
2881                    return null;
2882                }
2883            } else {
2884                // When the user is explicitly starting a process, then clear its
2885                // crash count so that we won't make it bad until they see at
2886                // least one crash dialog again, and make the process good again
2887                // if it had been bad.
2888                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2889                        + "/" + info.processName);
2890                mProcessCrashTimes.remove(info.processName, info.uid);
2891                if (mBadProcesses.get(info.processName, info.uid) != null) {
2892                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2893                            UserHandle.getUserId(info.uid), info.uid,
2894                            info.processName);
2895                    mBadProcesses.remove(info.processName, info.uid);
2896                    if (app != null) {
2897                        app.bad = false;
2898                    }
2899                }
2900            }
2901        }
2902
2903        if (app == null) {
2904            app = newProcessRecordLocked(info, processName, isolated);
2905            if (app == null) {
2906                Slog.w(TAG, "Failed making new process record for "
2907                        + processName + "/" + info.uid + " isolated=" + isolated);
2908                return null;
2909            }
2910            mProcessNames.put(processName, app.uid, app);
2911            if (isolated) {
2912                mIsolatedProcesses.put(app.uid, app);
2913            }
2914        } else {
2915            // If this is a new package in the process, add the package to the list
2916            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2917        }
2918
2919        // If the system is not ready yet, then hold off on starting this
2920        // process until it is.
2921        if (!mProcessesReady
2922                && !isAllowedWhileBooting(info)
2923                && !allowWhileBooting) {
2924            if (!mProcessesOnHold.contains(app)) {
2925                mProcessesOnHold.add(app);
2926            }
2927            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2928            return app;
2929        }
2930
2931        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2932        return (app.pid != 0) ? app : null;
2933    }
2934
2935    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2936        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2937    }
2938
2939    private final void startProcessLocked(ProcessRecord app,
2940            String hostingType, String hostingNameStr, String abiOverride) {
2941        if (app.pid > 0 && app.pid != MY_PID) {
2942            synchronized (mPidsSelfLocked) {
2943                mPidsSelfLocked.remove(app.pid);
2944                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2945            }
2946            app.setPid(0);
2947        }
2948
2949        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2950                "startProcessLocked removing on hold: " + app);
2951        mProcessesOnHold.remove(app);
2952
2953        updateCpuStats();
2954
2955        try {
2956            int uid = app.uid;
2957
2958            int[] gids = null;
2959            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2960            if (!app.isolated) {
2961                int[] permGids = null;
2962                try {
2963                    final PackageManager pm = mContext.getPackageManager();
2964                    permGids = pm.getPackageGids(app.info.packageName);
2965
2966                    if (Environment.isExternalStorageEmulated()) {
2967                        if (pm.checkPermission(
2968                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2969                                app.info.packageName) == PERMISSION_GRANTED) {
2970                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2971                        } else {
2972                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2973                        }
2974                    }
2975                } catch (PackageManager.NameNotFoundException e) {
2976                    Slog.w(TAG, "Unable to retrieve gids", e);
2977                }
2978
2979                /*
2980                 * Add shared application and profile GIDs so applications can share some
2981                 * resources like shared libraries and access user-wide resources
2982                 */
2983                if (permGids == null) {
2984                    gids = new int[2];
2985                } else {
2986                    gids = new int[permGids.length + 2];
2987                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2988                }
2989                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2990                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2991            }
2992            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2993                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2994                        && mTopComponent != null
2995                        && app.processName.equals(mTopComponent.getPackageName())) {
2996                    uid = 0;
2997                }
2998                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2999                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3000                    uid = 0;
3001                }
3002            }
3003            int debugFlags = 0;
3004            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3005                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3006                // Also turn on CheckJNI for debuggable apps. It's quite
3007                // awkward to turn on otherwise.
3008                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3009            }
3010            // Run the app in safe mode if its manifest requests so or the
3011            // system is booted in safe mode.
3012            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3013                mSafeMode == true) {
3014                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3015            }
3016            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3017                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3018            }
3019            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3020                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3021            }
3022            if ("1".equals(SystemProperties.get("debug.assert"))) {
3023                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3024            }
3025
3026            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3027            if (requiredAbi == null) {
3028                requiredAbi = Build.SUPPORTED_ABIS[0];
3029            }
3030
3031            // Start the process.  It will either succeed and return a result containing
3032            // the PID of the new process, or else throw a RuntimeException.
3033            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3034                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3035                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3036
3037            if (app.isolated) {
3038                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3039            }
3040            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3041
3042            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3043                    UserHandle.getUserId(uid), startResult.pid, uid,
3044                    app.processName, hostingType,
3045                    hostingNameStr != null ? hostingNameStr : "");
3046
3047            if (app.persistent) {
3048                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3049            }
3050
3051            StringBuilder buf = mStringBuilder;
3052            buf.setLength(0);
3053            buf.append("Start proc ");
3054            buf.append(app.processName);
3055            buf.append(" for ");
3056            buf.append(hostingType);
3057            if (hostingNameStr != null) {
3058                buf.append(" ");
3059                buf.append(hostingNameStr);
3060            }
3061            buf.append(": pid=");
3062            buf.append(startResult.pid);
3063            buf.append(" uid=");
3064            buf.append(uid);
3065            buf.append(" gids={");
3066            if (gids != null) {
3067                for (int gi=0; gi<gids.length; gi++) {
3068                    if (gi != 0) buf.append(", ");
3069                    buf.append(gids[gi]);
3070
3071                }
3072            }
3073            buf.append("}");
3074            if (requiredAbi != null) {
3075                buf.append(" abi=");
3076                buf.append(requiredAbi);
3077            }
3078            Slog.i(TAG, buf.toString());
3079            app.setPid(startResult.pid);
3080            app.usingWrapper = startResult.usingWrapper;
3081            app.removed = false;
3082            app.killedByAm = false;
3083            synchronized (mPidsSelfLocked) {
3084                this.mPidsSelfLocked.put(startResult.pid, app);
3085                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3086                msg.obj = app;
3087                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3088                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3089            }
3090        } catch (RuntimeException e) {
3091            // XXX do better error recovery.
3092            app.setPid(0);
3093            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3094            if (app.isolated) {
3095                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3096            }
3097            Slog.e(TAG, "Failure starting process " + app.processName, e);
3098        }
3099    }
3100
3101    void updateUsageStats(ActivityRecord component, boolean resumed) {
3102        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3103        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3104        if (resumed) {
3105            if (mUsageStatsService != null) {
3106                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3107                        System.currentTimeMillis(),
3108                        UsageStats.Event.MOVE_TO_FOREGROUND);
3109            }
3110            synchronized (stats) {
3111                stats.noteActivityResumedLocked(component.app.uid);
3112            }
3113        } else {
3114            if (mUsageStatsService != null) {
3115                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3116                        System.currentTimeMillis(),
3117                        UsageStats.Event.MOVE_TO_BACKGROUND);
3118            }
3119            synchronized (stats) {
3120                stats.noteActivityPausedLocked(component.app.uid);
3121            }
3122        }
3123    }
3124
3125    Intent getHomeIntent() {
3126        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3127        intent.setComponent(mTopComponent);
3128        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3129            intent.addCategory(Intent.CATEGORY_HOME);
3130        }
3131        return intent;
3132    }
3133
3134    boolean startHomeActivityLocked(int userId) {
3135        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3136                && mTopAction == null) {
3137            // We are running in factory test mode, but unable to find
3138            // the factory test app, so just sit around displaying the
3139            // error message and don't try to start anything.
3140            return false;
3141        }
3142        Intent intent = getHomeIntent();
3143        ActivityInfo aInfo =
3144            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3145        if (aInfo != null) {
3146            intent.setComponent(new ComponentName(
3147                    aInfo.applicationInfo.packageName, aInfo.name));
3148            // Don't do this if the home app is currently being
3149            // instrumented.
3150            aInfo = new ActivityInfo(aInfo);
3151            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3152            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3153                    aInfo.applicationInfo.uid, true);
3154            if (app == null || app.instrumentationClass == null) {
3155                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3156                mStackSupervisor.startHomeActivity(intent, aInfo);
3157            }
3158        }
3159
3160        return true;
3161    }
3162
3163    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3164        ActivityInfo ai = null;
3165        ComponentName comp = intent.getComponent();
3166        try {
3167            if (comp != null) {
3168                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3169            } else {
3170                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3171                        intent,
3172                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3173                            flags, userId);
3174
3175                if (info != null) {
3176                    ai = info.activityInfo;
3177                }
3178            }
3179        } catch (RemoteException e) {
3180            // ignore
3181        }
3182
3183        return ai;
3184    }
3185
3186    /**
3187     * Starts the "new version setup screen" if appropriate.
3188     */
3189    void startSetupActivityLocked() {
3190        // Only do this once per boot.
3191        if (mCheckedForSetup) {
3192            return;
3193        }
3194
3195        // We will show this screen if the current one is a different
3196        // version than the last one shown, and we are not running in
3197        // low-level factory test mode.
3198        final ContentResolver resolver = mContext.getContentResolver();
3199        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3200                Settings.Global.getInt(resolver,
3201                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3202            mCheckedForSetup = true;
3203
3204            // See if we should be showing the platform update setup UI.
3205            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3206            List<ResolveInfo> ris = mContext.getPackageManager()
3207                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3208
3209            // We don't allow third party apps to replace this.
3210            ResolveInfo ri = null;
3211            for (int i=0; ris != null && i<ris.size(); i++) {
3212                if ((ris.get(i).activityInfo.applicationInfo.flags
3213                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3214                    ri = ris.get(i);
3215                    break;
3216                }
3217            }
3218
3219            if (ri != null) {
3220                String vers = ri.activityInfo.metaData != null
3221                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3222                        : null;
3223                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3224                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3225                            Intent.METADATA_SETUP_VERSION);
3226                }
3227                String lastVers = Settings.Secure.getString(
3228                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3229                if (vers != null && !vers.equals(lastVers)) {
3230                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3231                    intent.setComponent(new ComponentName(
3232                            ri.activityInfo.packageName, ri.activityInfo.name));
3233                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3234                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3235                }
3236            }
3237        }
3238    }
3239
3240    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3241        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3242    }
3243
3244    void enforceNotIsolatedCaller(String caller) {
3245        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3246            throw new SecurityException("Isolated process not allowed to call " + caller);
3247        }
3248    }
3249
3250    @Override
3251    public int getFrontActivityScreenCompatMode() {
3252        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3253        synchronized (this) {
3254            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3255        }
3256    }
3257
3258    @Override
3259    public void setFrontActivityScreenCompatMode(int mode) {
3260        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3261                "setFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3264        }
3265    }
3266
3267    @Override
3268    public int getPackageScreenCompatMode(String packageName) {
3269        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3270        synchronized (this) {
3271            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3272        }
3273    }
3274
3275    @Override
3276    public void setPackageScreenCompatMode(String packageName, int mode) {
3277        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3278                "setPackageScreenCompatMode");
3279        synchronized (this) {
3280            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3281        }
3282    }
3283
3284    @Override
3285    public boolean getPackageAskScreenCompat(String packageName) {
3286        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3287        synchronized (this) {
3288            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3289        }
3290    }
3291
3292    @Override
3293    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3294        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3295                "setPackageAskScreenCompat");
3296        synchronized (this) {
3297            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3298        }
3299    }
3300
3301    private void dispatchProcessesChanged() {
3302        int N;
3303        synchronized (this) {
3304            N = mPendingProcessChanges.size();
3305            if (mActiveProcessChanges.length < N) {
3306                mActiveProcessChanges = new ProcessChangeItem[N];
3307            }
3308            mPendingProcessChanges.toArray(mActiveProcessChanges);
3309            mAvailProcessChanges.addAll(mPendingProcessChanges);
3310            mPendingProcessChanges.clear();
3311            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3312        }
3313
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    for (int j=0; j<N; j++) {
3321                        ProcessChangeItem item = mActiveProcessChanges[j];
3322                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": "
3325                                    + item.foregroundActivities);
3326                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3327                                    item.foregroundActivities);
3328                        }
3329                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3332                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3333                        }
3334                    }
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    private void dispatchProcessDied(int pid, int uid) {
3343        int i = mProcessObservers.beginBroadcast();
3344        while (i > 0) {
3345            i--;
3346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3347            if (observer != null) {
3348                try {
3349                    observer.onProcessDied(pid, uid);
3350                } catch (RemoteException e) {
3351                }
3352            }
3353        }
3354        mProcessObservers.finishBroadcast();
3355    }
3356
3357    @Override
3358    public final int startActivity(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo,
3360            String resultWho, int requestCode, int startFlags,
3361            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3362        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3363                resultWho, requestCode,
3364                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3365    }
3366
3367    @Override
3368    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3369            Intent intent, String resolvedType, IBinder resultTo,
3370            String resultWho, int requestCode, int startFlags,
3371            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3372        enforceNotIsolatedCaller("startActivity");
3373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3374                false, ALLOW_FULL_ONLY, "startActivity", null);
3375        // TODO: Switch to user app stacks here.
3376        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3377                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3378                null, null, options, userId, null);
3379    }
3380
3381    @Override
3382    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3383            Intent intent, String resolvedType, IBinder resultTo,
3384            String resultWho, int requestCode, int startFlags, String profileFile,
3385            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3386        enforceNotIsolatedCaller("startActivityAndWait");
3387        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3388                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3389        WaitResult res = new WaitResult();
3390        // TODO: Switch to user app stacks here.
3391        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3392                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3393                res, null, options, userId, null);
3394        return res;
3395    }
3396
3397    @Override
3398    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3399            Intent intent, String resolvedType, IBinder resultTo,
3400            String resultWho, int requestCode, int startFlags, Configuration config,
3401            Bundle options, int userId) {
3402        enforceNotIsolatedCaller("startActivityWithConfig");
3403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3404                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3405        // TODO: Switch to user app stacks here.
3406        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3407                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3408                null, null, null, config, options, userId, null);
3409        return ret;
3410    }
3411
3412    @Override
3413    public int startActivityIntentSender(IApplicationThread caller,
3414            IntentSender intent, Intent fillInIntent, String resolvedType,
3415            IBinder resultTo, String resultWho, int requestCode,
3416            int flagsMask, int flagsValues, Bundle options) {
3417        enforceNotIsolatedCaller("startActivityIntentSender");
3418        // Refuse possible leaked file descriptors
3419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3420            throw new IllegalArgumentException("File descriptors passed in Intent");
3421        }
3422
3423        IIntentSender sender = intent.getTarget();
3424        if (!(sender instanceof PendingIntentRecord)) {
3425            throw new IllegalArgumentException("Bad PendingIntent object");
3426        }
3427
3428        PendingIntentRecord pir = (PendingIntentRecord)sender;
3429
3430        synchronized (this) {
3431            // If this is coming from the currently resumed activity, it is
3432            // effectively saying that app switches are allowed at this point.
3433            final ActivityStack stack = getFocusedStack();
3434            if (stack.mResumedActivity != null &&
3435                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3436                mAppSwitchesAllowedTime = 0;
3437            }
3438        }
3439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3440                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3441        return ret;
3442    }
3443
3444    @Override
3445    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3446            Intent intent, String resolvedType, IVoiceInteractionSession session,
3447            IVoiceInteractor interactor, int startFlags, String profileFile,
3448            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3449        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3450                != PackageManager.PERMISSION_GRANTED) {
3451            String msg = "Permission Denial: startVoiceActivity() from pid="
3452                    + Binder.getCallingPid()
3453                    + ", uid=" + Binder.getCallingUid()
3454                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3455            Slog.w(TAG, msg);
3456            throw new SecurityException(msg);
3457        }
3458        if (session == null || interactor == null) {
3459            throw new NullPointerException("null session or interactor");
3460        }
3461        userId = handleIncomingUser(callingPid, callingUid, userId,
3462                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3463        // TODO: Switch to user app stacks here.
3464        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3465                resolvedType, session, interactor, null, null, 0, startFlags,
3466                profileFile, profileFd, null, null, options, userId, null);
3467    }
3468
3469    @Override
3470    public boolean startNextMatchingActivity(IBinder callingActivity,
3471            Intent intent, Bundle options) {
3472        // Refuse possible leaked file descriptors
3473        if (intent != null && intent.hasFileDescriptors() == true) {
3474            throw new IllegalArgumentException("File descriptors passed in Intent");
3475        }
3476
3477        synchronized (this) {
3478            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3479            if (r == null) {
3480                ActivityOptions.abort(options);
3481                return false;
3482            }
3483            if (r.app == null || r.app.thread == null) {
3484                // The caller is not running...  d'oh!
3485                ActivityOptions.abort(options);
3486                return false;
3487            }
3488            intent = new Intent(intent);
3489            // The caller is not allowed to change the data.
3490            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3491            // And we are resetting to find the next component...
3492            intent.setComponent(null);
3493
3494            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3495
3496            ActivityInfo aInfo = null;
3497            try {
3498                List<ResolveInfo> resolves =
3499                    AppGlobals.getPackageManager().queryIntentActivities(
3500                            intent, r.resolvedType,
3501                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3502                            UserHandle.getCallingUserId());
3503
3504                // Look for the original activity in the list...
3505                final int N = resolves != null ? resolves.size() : 0;
3506                for (int i=0; i<N; i++) {
3507                    ResolveInfo rInfo = resolves.get(i);
3508                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3509                            && rInfo.activityInfo.name.equals(r.info.name)) {
3510                        // We found the current one...  the next matching is
3511                        // after it.
3512                        i++;
3513                        if (i<N) {
3514                            aInfo = resolves.get(i).activityInfo;
3515                        }
3516                        if (debug) {
3517                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3518                                    + "/" + r.info.name);
3519                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3520                                    + "/" + aInfo.name);
3521                        }
3522                        break;
3523                    }
3524                }
3525            } catch (RemoteException e) {
3526            }
3527
3528            if (aInfo == null) {
3529                // Nobody who is next!
3530                ActivityOptions.abort(options);
3531                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3532                return false;
3533            }
3534
3535            intent.setComponent(new ComponentName(
3536                    aInfo.applicationInfo.packageName, aInfo.name));
3537            intent.setFlags(intent.getFlags()&~(
3538                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3539                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3540                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3541                    Intent.FLAG_ACTIVITY_NEW_TASK));
3542
3543            // Okay now we need to start the new activity, replacing the
3544            // currently running activity.  This is a little tricky because
3545            // we want to start the new one as if the current one is finished,
3546            // but not finish the current one first so that there is no flicker.
3547            // And thus...
3548            final boolean wasFinishing = r.finishing;
3549            r.finishing = true;
3550
3551            // Propagate reply information over to the new activity.
3552            final ActivityRecord resultTo = r.resultTo;
3553            final String resultWho = r.resultWho;
3554            final int requestCode = r.requestCode;
3555            r.resultTo = null;
3556            if (resultTo != null) {
3557                resultTo.removeResultsLocked(r, resultWho, requestCode);
3558            }
3559
3560            final long origId = Binder.clearCallingIdentity();
3561            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3562                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3563                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3564                    options, false, null, null);
3565            Binder.restoreCallingIdentity(origId);
3566
3567            r.finishing = wasFinishing;
3568            if (res != ActivityManager.START_SUCCESS) {
3569                return false;
3570            }
3571            return true;
3572        }
3573    }
3574
3575    @Override
3576    public final int startActivityFromRecents(int taskId, Bundle options) {
3577        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3578            String msg = "Permission Denial: startActivityFromRecents called without " +
3579                    START_TASKS_FROM_RECENTS;
3580            Slog.w(TAG, msg);
3581            throw new SecurityException(msg);
3582        }
3583        final int callingUid;
3584        final String callingPackage;
3585        final Intent intent;
3586        final int userId;
3587        synchronized (this) {
3588            final TaskRecord task = recentTaskForIdLocked(taskId);
3589            if (task == null) {
3590                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3591            }
3592            callingUid = task.mCallingUid;
3593            callingPackage = task.mCallingPackage;
3594            intent = task.intent;
3595            userId = task.userId;
3596        }
3597        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3598                options, userId, null);
3599    }
3600
3601    final int startActivityInPackage(int uid, String callingPackage,
3602            Intent intent, String resolvedType, IBinder resultTo,
3603            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3604                    IActivityContainer container) {
3605
3606        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3607                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3608
3609        // TODO: Switch to user app stacks here.
3610        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3611                null, null, resultTo, resultWho, requestCode, startFlags,
3612                null, null, null, null, options, userId, container);
3613        return ret;
3614    }
3615
3616    @Override
3617    public final int startActivities(IApplicationThread caller, String callingPackage,
3618            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3619            int userId) {
3620        enforceNotIsolatedCaller("startActivities");
3621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3622                false, ALLOW_FULL_ONLY, "startActivity", null);
3623        // TODO: Switch to user app stacks here.
3624        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3625                resolvedTypes, resultTo, options, userId);
3626        return ret;
3627    }
3628
3629    final int startActivitiesInPackage(int uid, String callingPackage,
3630            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3631            Bundle options, int userId) {
3632
3633        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3634                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3635        // TODO: Switch to user app stacks here.
3636        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3637                resultTo, options, userId);
3638        return ret;
3639    }
3640
3641    final void addRecentTaskLocked(TaskRecord task) {
3642        int N = mRecentTasks.size();
3643        // Quick case: check if the top-most recent task is the same.
3644        if (N > 0 && mRecentTasks.get(0) == task) {
3645            return;
3646        }
3647        // Another quick case: never add voice sessions.
3648        if (task.voiceSession != null) {
3649            return;
3650        }
3651        // Remove any existing entries that are the same kind of task.
3652        final Intent intent = task.intent;
3653        final boolean document = intent != null && intent.isDocument();
3654        final ComponentName comp = intent.getComponent();
3655
3656        int maxRecents = task.maxRecents - 1;
3657        for (int i=0; i<N; i++) {
3658            final TaskRecord tr = mRecentTasks.get(i);
3659            if (task != tr) {
3660                if (task.userId != tr.userId) {
3661                    continue;
3662                }
3663                if (i > MAX_RECENT_BITMAPS) {
3664                    tr.freeLastThumbnail();
3665                }
3666                final Intent trIntent = tr.intent;
3667                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3668                    (intent == null || !intent.filterEquals(trIntent))) {
3669                    continue;
3670                }
3671                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3672                if (document && trIsDocument) {
3673                    // These are the same document activity (not necessarily the same doc).
3674                    if (maxRecents > 0) {
3675                        --maxRecents;
3676                        continue;
3677                    }
3678                    // Hit the maximum number of documents for this task. Fall through
3679                    // and remove this document from recents.
3680                } else if (document || trIsDocument) {
3681                    // Only one of these is a document. Not the droid we're looking for.
3682                    continue;
3683                }
3684            }
3685
3686            // Either task and tr are the same or, their affinities match or their intents match
3687            // and neither of them is a document, or they are documents using the same activity
3688            // and their maxRecents has been reached.
3689            tr.disposeThumbnail();
3690            mRecentTasks.remove(i);
3691            if (task != tr) {
3692                tr.closeRecentsChain();
3693            }
3694            i--;
3695            N--;
3696            if (task.intent == null) {
3697                // If the new recent task we are adding is not fully
3698                // specified, then replace it with the existing recent task.
3699                task = tr;
3700            }
3701            mTaskPersister.notify(tr, false);
3702        }
3703        if (N >= MAX_RECENT_TASKS) {
3704            final TaskRecord tr = mRecentTasks.remove(N - 1);
3705            tr.disposeThumbnail();
3706            tr.closeRecentsChain();
3707        }
3708        mRecentTasks.add(0, task);
3709    }
3710
3711    @Override
3712    public void reportActivityFullyDrawn(IBinder token) {
3713        synchronized (this) {
3714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3715            if (r == null) {
3716                return;
3717            }
3718            r.reportFullyDrawnLocked();
3719        }
3720    }
3721
3722    @Override
3723    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3724        synchronized (this) {
3725            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3726            if (r == null) {
3727                return;
3728            }
3729            final long origId = Binder.clearCallingIdentity();
3730            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3731            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3732                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3733            if (config != null) {
3734                r.frozenBeforeDestroy = true;
3735                if (!updateConfigurationLocked(config, r, false, false)) {
3736                    mStackSupervisor.resumeTopActivitiesLocked();
3737                }
3738            }
3739            Binder.restoreCallingIdentity(origId);
3740        }
3741    }
3742
3743    @Override
3744    public int getRequestedOrientation(IBinder token) {
3745        synchronized (this) {
3746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3747            if (r == null) {
3748                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3749            }
3750            return mWindowManager.getAppOrientation(r.appToken);
3751        }
3752    }
3753
3754    /**
3755     * This is the internal entry point for handling Activity.finish().
3756     *
3757     * @param token The Binder token referencing the Activity we want to finish.
3758     * @param resultCode Result code, if any, from this Activity.
3759     * @param resultData Result data (Intent), if any, from this Activity.
3760     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3761     *            the root Activity in the task.
3762     *
3763     * @return Returns true if the activity successfully finished, or false if it is still running.
3764     */
3765    @Override
3766    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3767            boolean finishTask) {
3768        // Refuse possible leaked file descriptors
3769        if (resultData != null && resultData.hasFileDescriptors() == true) {
3770            throw new IllegalArgumentException("File descriptors passed in Intent");
3771        }
3772
3773        synchronized(this) {
3774            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3775            if (r == null) {
3776                return true;
3777            }
3778            // Keep track of the root activity of the task before we finish it
3779            TaskRecord tr = r.task;
3780            ActivityRecord rootR = tr.getRootActivity();
3781            // Do not allow task to finish in Lock Task mode.
3782            if (tr == mStackSupervisor.mLockTaskModeTask) {
3783                if (rootR == r) {
3784                    mStackSupervisor.showLockTaskToast();
3785                    return false;
3786                }
3787            }
3788            if (mController != null) {
3789                // Find the first activity that is not finishing.
3790                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3791                if (next != null) {
3792                    // ask watcher if this is allowed
3793                    boolean resumeOK = true;
3794                    try {
3795                        resumeOK = mController.activityResuming(next.packageName);
3796                    } catch (RemoteException e) {
3797                        mController = null;
3798                        Watchdog.getInstance().setActivityController(null);
3799                    }
3800
3801                    if (!resumeOK) {
3802                        return false;
3803                    }
3804                }
3805            }
3806            final long origId = Binder.clearCallingIdentity();
3807            try {
3808                boolean res;
3809                if (finishTask && r == rootR) {
3810                    // If requested, remove the task that is associated to this activity only if it
3811                    // was the root activity in the task.  The result code and data is ignored because
3812                    // we don't support returning them across task boundaries.
3813                    res = removeTaskByIdLocked(tr.taskId, 0);
3814                } else {
3815                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3816                            resultData, "app-request", true);
3817                }
3818                return res;
3819            } finally {
3820                Binder.restoreCallingIdentity(origId);
3821            }
3822        }
3823    }
3824
3825    @Override
3826    public final void finishHeavyWeightApp() {
3827        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3828                != PackageManager.PERMISSION_GRANTED) {
3829            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3830                    + Binder.getCallingPid()
3831                    + ", uid=" + Binder.getCallingUid()
3832                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3833            Slog.w(TAG, msg);
3834            throw new SecurityException(msg);
3835        }
3836
3837        synchronized(this) {
3838            if (mHeavyWeightProcess == null) {
3839                return;
3840            }
3841
3842            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3843                    mHeavyWeightProcess.activities);
3844            for (int i=0; i<activities.size(); i++) {
3845                ActivityRecord r = activities.get(i);
3846                if (!r.finishing) {
3847                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3848                            null, "finish-heavy", true);
3849                }
3850            }
3851
3852            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3853                    mHeavyWeightProcess.userId, 0));
3854            mHeavyWeightProcess = null;
3855        }
3856    }
3857
3858    @Override
3859    public void crashApplication(int uid, int initialPid, String packageName,
3860            String message) {
3861        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3862                != PackageManager.PERMISSION_GRANTED) {
3863            String msg = "Permission Denial: crashApplication() from pid="
3864                    + Binder.getCallingPid()
3865                    + ", uid=" + Binder.getCallingUid()
3866                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3867            Slog.w(TAG, msg);
3868            throw new SecurityException(msg);
3869        }
3870
3871        synchronized(this) {
3872            ProcessRecord proc = null;
3873
3874            // Figure out which process to kill.  We don't trust that initialPid
3875            // still has any relation to current pids, so must scan through the
3876            // list.
3877            synchronized (mPidsSelfLocked) {
3878                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3879                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3880                    if (p.uid != uid) {
3881                        continue;
3882                    }
3883                    if (p.pid == initialPid) {
3884                        proc = p;
3885                        break;
3886                    }
3887                    if (p.pkgList.containsKey(packageName)) {
3888                        proc = p;
3889                    }
3890                }
3891            }
3892
3893            if (proc == null) {
3894                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3895                        + " initialPid=" + initialPid
3896                        + " packageName=" + packageName);
3897                return;
3898            }
3899
3900            if (proc.thread != null) {
3901                if (proc.pid == Process.myPid()) {
3902                    Log.w(TAG, "crashApplication: trying to crash self!");
3903                    return;
3904                }
3905                long ident = Binder.clearCallingIdentity();
3906                try {
3907                    proc.thread.scheduleCrash(message);
3908                } catch (RemoteException e) {
3909                }
3910                Binder.restoreCallingIdentity(ident);
3911            }
3912        }
3913    }
3914
3915    @Override
3916    public final void finishSubActivity(IBinder token, String resultWho,
3917            int requestCode) {
3918        synchronized(this) {
3919            final long origId = Binder.clearCallingIdentity();
3920            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3921            if (r != null) {
3922                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3923            }
3924            Binder.restoreCallingIdentity(origId);
3925        }
3926    }
3927
3928    @Override
3929    public boolean finishActivityAffinity(IBinder token) {
3930        synchronized(this) {
3931            final long origId = Binder.clearCallingIdentity();
3932            try {
3933                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3934
3935                ActivityRecord rootR = r.task.getRootActivity();
3936                // Do not allow task to finish in Lock Task mode.
3937                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3938                    if (rootR == r) {
3939                        mStackSupervisor.showLockTaskToast();
3940                        return false;
3941                    }
3942                }
3943                boolean res = false;
3944                if (r != null) {
3945                    res = r.task.stack.finishActivityAffinityLocked(r);
3946                }
3947                return res;
3948            } finally {
3949                Binder.restoreCallingIdentity(origId);
3950            }
3951        }
3952    }
3953
3954    @Override
3955    public void finishVoiceTask(IVoiceInteractionSession session) {
3956        synchronized(this) {
3957            final long origId = Binder.clearCallingIdentity();
3958            try {
3959                mStackSupervisor.finishVoiceTask(session);
3960            } finally {
3961                Binder.restoreCallingIdentity(origId);
3962            }
3963        }
3964
3965    }
3966
3967    @Override
3968    public boolean willActivityBeVisible(IBinder token) {
3969        synchronized(this) {
3970            ActivityStack stack = ActivityRecord.getStackLocked(token);
3971            if (stack != null) {
3972                return stack.willActivityBeVisibleLocked(token);
3973            }
3974            return false;
3975        }
3976    }
3977
3978    @Override
3979    public void overridePendingTransition(IBinder token, String packageName,
3980            int enterAnim, int exitAnim) {
3981        synchronized(this) {
3982            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3983            if (self == null) {
3984                return;
3985            }
3986
3987            final long origId = Binder.clearCallingIdentity();
3988
3989            if (self.state == ActivityState.RESUMED
3990                    || self.state == ActivityState.PAUSING) {
3991                mWindowManager.overridePendingAppTransition(packageName,
3992                        enterAnim, exitAnim, null);
3993            }
3994
3995            Binder.restoreCallingIdentity(origId);
3996        }
3997    }
3998
3999    /**
4000     * Main function for removing an existing process from the activity manager
4001     * as a result of that process going away.  Clears out all connections
4002     * to the process.
4003     */
4004    private final void handleAppDiedLocked(ProcessRecord app,
4005            boolean restarting, boolean allowRestart) {
4006        int pid = app.pid;
4007        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4008        if (!restarting) {
4009            removeLruProcessLocked(app);
4010            if (pid > 0) {
4011                ProcessList.remove(pid);
4012            }
4013        }
4014
4015        if (mProfileProc == app) {
4016            clearProfilerLocked();
4017        }
4018
4019        // Remove this application's activities from active lists.
4020        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4021
4022        app.activities.clear();
4023
4024        if (app.instrumentationClass != null) {
4025            Slog.w(TAG, "Crash of app " + app.processName
4026                  + " running instrumentation " + app.instrumentationClass);
4027            Bundle info = new Bundle();
4028            info.putString("shortMsg", "Process crashed.");
4029            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4030        }
4031
4032        if (!restarting) {
4033            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4034                // If there was nothing to resume, and we are not already
4035                // restarting this process, but there is a visible activity that
4036                // is hosted by the process...  then make sure all visible
4037                // activities are running, taking care of restarting this
4038                // process.
4039                if (hasVisibleActivities) {
4040                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4041                }
4042            }
4043        }
4044    }
4045
4046    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4047        IBinder threadBinder = thread.asBinder();
4048        // Find the application record.
4049        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4050            ProcessRecord rec = mLruProcesses.get(i);
4051            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4052                return i;
4053            }
4054        }
4055        return -1;
4056    }
4057
4058    final ProcessRecord getRecordForAppLocked(
4059            IApplicationThread thread) {
4060        if (thread == null) {
4061            return null;
4062        }
4063
4064        int appIndex = getLRURecordIndexForAppLocked(thread);
4065        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4066    }
4067
4068    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4069        // If there are no longer any background processes running,
4070        // and the app that died was not running instrumentation,
4071        // then tell everyone we are now low on memory.
4072        boolean haveBg = false;
4073        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4074            ProcessRecord rec = mLruProcesses.get(i);
4075            if (rec.thread != null
4076                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4077                haveBg = true;
4078                break;
4079            }
4080        }
4081
4082        if (!haveBg) {
4083            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4084            if (doReport) {
4085                long now = SystemClock.uptimeMillis();
4086                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4087                    doReport = false;
4088                } else {
4089                    mLastMemUsageReportTime = now;
4090                }
4091            }
4092            final ArrayList<ProcessMemInfo> memInfos
4093                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4094            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4095            long now = SystemClock.uptimeMillis();
4096            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4097                ProcessRecord rec = mLruProcesses.get(i);
4098                if (rec == dyingProc || rec.thread == null) {
4099                    continue;
4100                }
4101                if (doReport) {
4102                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4103                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4104                }
4105                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4106                    // The low memory report is overriding any current
4107                    // state for a GC request.  Make sure to do
4108                    // heavy/important/visible/foreground processes first.
4109                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4110                        rec.lastRequestedGc = 0;
4111                    } else {
4112                        rec.lastRequestedGc = rec.lastLowMemory;
4113                    }
4114                    rec.reportLowMemory = true;
4115                    rec.lastLowMemory = now;
4116                    mProcessesToGc.remove(rec);
4117                    addProcessToGcListLocked(rec);
4118                }
4119            }
4120            if (doReport) {
4121                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4122                mHandler.sendMessage(msg);
4123            }
4124            scheduleAppGcsLocked();
4125        }
4126    }
4127
4128    final void appDiedLocked(ProcessRecord app, int pid,
4129            IApplicationThread thread) {
4130
4131        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4132        synchronized (stats) {
4133            stats.noteProcessDiedLocked(app.info.uid, pid);
4134        }
4135
4136        Process.killProcessGroup(app.info.uid, pid);
4137
4138        // Clean up already done if the process has been re-started.
4139        if (app.pid == pid && app.thread != null &&
4140                app.thread.asBinder() == thread.asBinder()) {
4141            boolean doLowMem = app.instrumentationClass == null;
4142            boolean doOomAdj = doLowMem;
4143            if (!app.killedByAm) {
4144                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4145                        + ") has died.");
4146                mAllowLowerMemLevel = true;
4147            } else {
4148                // Note that we always want to do oom adj to update our state with the
4149                // new number of procs.
4150                mAllowLowerMemLevel = false;
4151                doLowMem = false;
4152            }
4153            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4154            if (DEBUG_CLEANUP) Slog.v(
4155                TAG, "Dying app: " + app + ", pid: " + pid
4156                + ", thread: " + thread.asBinder());
4157            handleAppDiedLocked(app, false, true);
4158
4159            if (doOomAdj) {
4160                updateOomAdjLocked();
4161            }
4162            if (doLowMem) {
4163                doLowMemReportIfNeededLocked(app);
4164            }
4165        } else if (app.pid != pid) {
4166            // A new process has already been started.
4167            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4168                    + ") has died and restarted (pid " + app.pid + ").");
4169            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4170        } else if (DEBUG_PROCESSES) {
4171            Slog.d(TAG, "Received spurious death notification for thread "
4172                    + thread.asBinder());
4173        }
4174    }
4175
4176    /**
4177     * If a stack trace dump file is configured, dump process stack traces.
4178     * @param clearTraces causes the dump file to be erased prior to the new
4179     *    traces being written, if true; when false, the new traces will be
4180     *    appended to any existing file content.
4181     * @param firstPids of dalvik VM processes to dump stack traces for first
4182     * @param lastPids of dalvik VM processes to dump stack traces for last
4183     * @param nativeProcs optional list of native process names to dump stack crawls
4184     * @return file containing stack traces, or null if no dump file is configured
4185     */
4186    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4187            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4188        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4189        if (tracesPath == null || tracesPath.length() == 0) {
4190            return null;
4191        }
4192
4193        File tracesFile = new File(tracesPath);
4194        try {
4195            File tracesDir = tracesFile.getParentFile();
4196            if (!tracesDir.exists()) {
4197                tracesFile.mkdirs();
4198                if (!SELinux.restorecon(tracesDir)) {
4199                    return null;
4200                }
4201            }
4202            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4203
4204            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4205            tracesFile.createNewFile();
4206            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4207        } catch (IOException e) {
4208            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4209            return null;
4210        }
4211
4212        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4213        return tracesFile;
4214    }
4215
4216    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4217            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4218        // Use a FileObserver to detect when traces finish writing.
4219        // The order of traces is considered important to maintain for legibility.
4220        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4221            @Override
4222            public synchronized void onEvent(int event, String path) { notify(); }
4223        };
4224
4225        try {
4226            observer.startWatching();
4227
4228            // First collect all of the stacks of the most important pids.
4229            if (firstPids != null) {
4230                try {
4231                    int num = firstPids.size();
4232                    for (int i = 0; i < num; i++) {
4233                        synchronized (observer) {
4234                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4235                            observer.wait(200);  // Wait for write-close, give up after 200msec
4236                        }
4237                    }
4238                } catch (InterruptedException e) {
4239                    Log.wtf(TAG, e);
4240                }
4241            }
4242
4243            // Next collect the stacks of the native pids
4244            if (nativeProcs != null) {
4245                int[] pids = Process.getPidsForCommands(nativeProcs);
4246                if (pids != null) {
4247                    for (int pid : pids) {
4248                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4249                    }
4250                }
4251            }
4252
4253            // Lastly, measure CPU usage.
4254            if (processCpuTracker != null) {
4255                processCpuTracker.init();
4256                System.gc();
4257                processCpuTracker.update();
4258                try {
4259                    synchronized (processCpuTracker) {
4260                        processCpuTracker.wait(500); // measure over 1/2 second.
4261                    }
4262                } catch (InterruptedException e) {
4263                }
4264                processCpuTracker.update();
4265
4266                // We'll take the stack crawls of just the top apps using CPU.
4267                final int N = processCpuTracker.countWorkingStats();
4268                int numProcs = 0;
4269                for (int i=0; i<N && numProcs<5; i++) {
4270                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4271                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4272                        numProcs++;
4273                        try {
4274                            synchronized (observer) {
4275                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4276                                observer.wait(200);  // Wait for write-close, give up after 200msec
4277                            }
4278                        } catch (InterruptedException e) {
4279                            Log.wtf(TAG, e);
4280                        }
4281
4282                    }
4283                }
4284            }
4285        } finally {
4286            observer.stopWatching();
4287        }
4288    }
4289
4290    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4291        if (true || IS_USER_BUILD) {
4292            return;
4293        }
4294        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4295        if (tracesPath == null || tracesPath.length() == 0) {
4296            return;
4297        }
4298
4299        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4300        StrictMode.allowThreadDiskWrites();
4301        try {
4302            final File tracesFile = new File(tracesPath);
4303            final File tracesDir = tracesFile.getParentFile();
4304            final File tracesTmp = new File(tracesDir, "__tmp__");
4305            try {
4306                if (!tracesDir.exists()) {
4307                    tracesFile.mkdirs();
4308                    if (!SELinux.restorecon(tracesDir.getPath())) {
4309                        return;
4310                    }
4311                }
4312                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4313
4314                if (tracesFile.exists()) {
4315                    tracesTmp.delete();
4316                    tracesFile.renameTo(tracesTmp);
4317                }
4318                StringBuilder sb = new StringBuilder();
4319                Time tobj = new Time();
4320                tobj.set(System.currentTimeMillis());
4321                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4322                sb.append(": ");
4323                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4324                sb.append(" since ");
4325                sb.append(msg);
4326                FileOutputStream fos = new FileOutputStream(tracesFile);
4327                fos.write(sb.toString().getBytes());
4328                if (app == null) {
4329                    fos.write("\n*** No application process!".getBytes());
4330                }
4331                fos.close();
4332                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4333            } catch (IOException e) {
4334                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4335                return;
4336            }
4337
4338            if (app != null) {
4339                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4340                firstPids.add(app.pid);
4341                dumpStackTraces(tracesPath, firstPids, null, null, null);
4342            }
4343
4344            File lastTracesFile = null;
4345            File curTracesFile = null;
4346            for (int i=9; i>=0; i--) {
4347                String name = String.format(Locale.US, "slow%02d.txt", i);
4348                curTracesFile = new File(tracesDir, name);
4349                if (curTracesFile.exists()) {
4350                    if (lastTracesFile != null) {
4351                        curTracesFile.renameTo(lastTracesFile);
4352                    } else {
4353                        curTracesFile.delete();
4354                    }
4355                }
4356                lastTracesFile = curTracesFile;
4357            }
4358            tracesFile.renameTo(curTracesFile);
4359            if (tracesTmp.exists()) {
4360                tracesTmp.renameTo(tracesFile);
4361            }
4362        } finally {
4363            StrictMode.setThreadPolicy(oldPolicy);
4364        }
4365    }
4366
4367    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4368            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4369        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4370        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4371
4372        if (mController != null) {
4373            try {
4374                // 0 == continue, -1 = kill process immediately
4375                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4376                if (res < 0 && app.pid != MY_PID) {
4377                    Process.killProcess(app.pid);
4378                    Process.killProcessGroup(app.info.uid, app.pid);
4379                }
4380            } catch (RemoteException e) {
4381                mController = null;
4382                Watchdog.getInstance().setActivityController(null);
4383            }
4384        }
4385
4386        long anrTime = SystemClock.uptimeMillis();
4387        if (MONITOR_CPU_USAGE) {
4388            updateCpuStatsNow();
4389        }
4390
4391        synchronized (this) {
4392            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4393            if (mShuttingDown) {
4394                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4395                return;
4396            } else if (app.notResponding) {
4397                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4398                return;
4399            } else if (app.crashing) {
4400                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4401                return;
4402            }
4403
4404            // In case we come through here for the same app before completing
4405            // this one, mark as anring now so we will bail out.
4406            app.notResponding = true;
4407
4408            // Log the ANR to the event log.
4409            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4410                    app.processName, app.info.flags, annotation);
4411
4412            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4413            firstPids.add(app.pid);
4414
4415            int parentPid = app.pid;
4416            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4417            if (parentPid != app.pid) firstPids.add(parentPid);
4418
4419            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4420
4421            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4422                ProcessRecord r = mLruProcesses.get(i);
4423                if (r != null && r.thread != null) {
4424                    int pid = r.pid;
4425                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4426                        if (r.persistent) {
4427                            firstPids.add(pid);
4428                        } else {
4429                            lastPids.put(pid, Boolean.TRUE);
4430                        }
4431                    }
4432                }
4433            }
4434        }
4435
4436        // Log the ANR to the main log.
4437        StringBuilder info = new StringBuilder();
4438        info.setLength(0);
4439        info.append("ANR in ").append(app.processName);
4440        if (activity != null && activity.shortComponentName != null) {
4441            info.append(" (").append(activity.shortComponentName).append(")");
4442        }
4443        info.append("\n");
4444        info.append("PID: ").append(app.pid).append("\n");
4445        if (annotation != null) {
4446            info.append("Reason: ").append(annotation).append("\n");
4447        }
4448        if (parent != null && parent != activity) {
4449            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4450        }
4451
4452        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4453
4454        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4455                NATIVE_STACKS_OF_INTEREST);
4456
4457        String cpuInfo = null;
4458        if (MONITOR_CPU_USAGE) {
4459            updateCpuStatsNow();
4460            synchronized (mProcessCpuThread) {
4461                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4462            }
4463            info.append(processCpuTracker.printCurrentLoad());
4464            info.append(cpuInfo);
4465        }
4466
4467        info.append(processCpuTracker.printCurrentState(anrTime));
4468
4469        Slog.e(TAG, info.toString());
4470        if (tracesFile == null) {
4471            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4472            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4473        }
4474
4475        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4476                cpuInfo, tracesFile, null);
4477
4478        if (mController != null) {
4479            try {
4480                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4481                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4482                if (res != 0) {
4483                    if (res < 0 && app.pid != MY_PID) {
4484                        Process.killProcess(app.pid);
4485                        Process.killProcessGroup(app.info.uid, app.pid);
4486                    } else {
4487                        synchronized (this) {
4488                            mServices.scheduleServiceTimeoutLocked(app);
4489                        }
4490                    }
4491                    return;
4492                }
4493            } catch (RemoteException e) {
4494                mController = null;
4495                Watchdog.getInstance().setActivityController(null);
4496            }
4497        }
4498
4499        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4500        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4501                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4502
4503        synchronized (this) {
4504            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4505                killUnneededProcessLocked(app, "background ANR");
4506                return;
4507            }
4508
4509            // Set the app's notResponding state, and look up the errorReportReceiver
4510            makeAppNotRespondingLocked(app,
4511                    activity != null ? activity.shortComponentName : null,
4512                    annotation != null ? "ANR " + annotation : "ANR",
4513                    info.toString());
4514
4515            // Bring up the infamous App Not Responding dialog
4516            Message msg = Message.obtain();
4517            HashMap<String, Object> map = new HashMap<String, Object>();
4518            msg.what = SHOW_NOT_RESPONDING_MSG;
4519            msg.obj = map;
4520            msg.arg1 = aboveSystem ? 1 : 0;
4521            map.put("app", app);
4522            if (activity != null) {
4523                map.put("activity", activity);
4524            }
4525
4526            mHandler.sendMessage(msg);
4527        }
4528    }
4529
4530    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4531        if (!mLaunchWarningShown) {
4532            mLaunchWarningShown = true;
4533            mHandler.post(new Runnable() {
4534                @Override
4535                public void run() {
4536                    synchronized (ActivityManagerService.this) {
4537                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4538                        d.show();
4539                        mHandler.postDelayed(new Runnable() {
4540                            @Override
4541                            public void run() {
4542                                synchronized (ActivityManagerService.this) {
4543                                    d.dismiss();
4544                                    mLaunchWarningShown = false;
4545                                }
4546                            }
4547                        }, 4000);
4548                    }
4549                }
4550            });
4551        }
4552    }
4553
4554    @Override
4555    public boolean clearApplicationUserData(final String packageName,
4556            final IPackageDataObserver observer, int userId) {
4557        enforceNotIsolatedCaller("clearApplicationUserData");
4558        int uid = Binder.getCallingUid();
4559        int pid = Binder.getCallingPid();
4560        userId = handleIncomingUser(pid, uid,
4561                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4562        long callingId = Binder.clearCallingIdentity();
4563        try {
4564            IPackageManager pm = AppGlobals.getPackageManager();
4565            int pkgUid = -1;
4566            synchronized(this) {
4567                try {
4568                    pkgUid = pm.getPackageUid(packageName, userId);
4569                } catch (RemoteException e) {
4570                }
4571                if (pkgUid == -1) {
4572                    Slog.w(TAG, "Invalid packageName: " + packageName);
4573                    if (observer != null) {
4574                        try {
4575                            observer.onRemoveCompleted(packageName, false);
4576                        } catch (RemoteException e) {
4577                            Slog.i(TAG, "Observer no longer exists.");
4578                        }
4579                    }
4580                    return false;
4581                }
4582                if (uid == pkgUid || checkComponentPermission(
4583                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4584                        pid, uid, -1, true)
4585                        == PackageManager.PERMISSION_GRANTED) {
4586                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4587                } else {
4588                    throw new SecurityException("PID " + pid + " does not have permission "
4589                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4590                                    + " of package " + packageName);
4591                }
4592            }
4593
4594            try {
4595                // Clear application user data
4596                pm.clearApplicationUserData(packageName, observer, userId);
4597
4598                // Remove all permissions granted from/to this package
4599                removeUriPermissionsForPackageLocked(packageName, userId, true);
4600
4601                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4602                        Uri.fromParts("package", packageName, null));
4603                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4604                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4605                        null, null, 0, null, null, null, false, false, userId);
4606            } catch (RemoteException e) {
4607            }
4608        } finally {
4609            Binder.restoreCallingIdentity(callingId);
4610        }
4611        return true;
4612    }
4613
4614    @Override
4615    public void killBackgroundProcesses(final String packageName, int userId) {
4616        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4617                != PackageManager.PERMISSION_GRANTED &&
4618                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4619                        != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4621                    + Binder.getCallingPid()
4622                    + ", uid=" + Binder.getCallingUid()
4623                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4624            Slog.w(TAG, msg);
4625            throw new SecurityException(msg);
4626        }
4627
4628        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4630        long callingId = Binder.clearCallingIdentity();
4631        try {
4632            IPackageManager pm = AppGlobals.getPackageManager();
4633            synchronized(this) {
4634                int appId = -1;
4635                try {
4636                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4637                } catch (RemoteException e) {
4638                }
4639                if (appId == -1) {
4640                    Slog.w(TAG, "Invalid packageName: " + packageName);
4641                    return;
4642                }
4643                killPackageProcessesLocked(packageName, appId, userId,
4644                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4645            }
4646        } finally {
4647            Binder.restoreCallingIdentity(callingId);
4648        }
4649    }
4650
4651    @Override
4652    public void killAllBackgroundProcesses() {
4653        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4654                != PackageManager.PERMISSION_GRANTED) {
4655            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4656                    + Binder.getCallingPid()
4657                    + ", uid=" + Binder.getCallingUid()
4658                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4659            Slog.w(TAG, msg);
4660            throw new SecurityException(msg);
4661        }
4662
4663        long callingId = Binder.clearCallingIdentity();
4664        try {
4665            synchronized(this) {
4666                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4667                final int NP = mProcessNames.getMap().size();
4668                for (int ip=0; ip<NP; ip++) {
4669                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4670                    final int NA = apps.size();
4671                    for (int ia=0; ia<NA; ia++) {
4672                        ProcessRecord app = apps.valueAt(ia);
4673                        if (app.persistent) {
4674                            // we don't kill persistent processes
4675                            continue;
4676                        }
4677                        if (app.removed) {
4678                            procs.add(app);
4679                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4680                            app.removed = true;
4681                            procs.add(app);
4682                        }
4683                    }
4684                }
4685
4686                int N = procs.size();
4687                for (int i=0; i<N; i++) {
4688                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4689                }
4690                mAllowLowerMemLevel = true;
4691                updateOomAdjLocked();
4692                doLowMemReportIfNeededLocked(null);
4693            }
4694        } finally {
4695            Binder.restoreCallingIdentity(callingId);
4696        }
4697    }
4698
4699    @Override
4700    public void forceStopPackage(final String packageName, int userId) {
4701        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4702                != PackageManager.PERMISSION_GRANTED) {
4703            String msg = "Permission Denial: forceStopPackage() from pid="
4704                    + Binder.getCallingPid()
4705                    + ", uid=" + Binder.getCallingUid()
4706                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4707            Slog.w(TAG, msg);
4708            throw new SecurityException(msg);
4709        }
4710        final int callingPid = Binder.getCallingPid();
4711        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4712                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4713        long callingId = Binder.clearCallingIdentity();
4714        try {
4715            IPackageManager pm = AppGlobals.getPackageManager();
4716            synchronized(this) {
4717                int[] users = userId == UserHandle.USER_ALL
4718                        ? getUsersLocked() : new int[] { userId };
4719                for (int user : users) {
4720                    int pkgUid = -1;
4721                    try {
4722                        pkgUid = pm.getPackageUid(packageName, user);
4723                    } catch (RemoteException e) {
4724                    }
4725                    if (pkgUid == -1) {
4726                        Slog.w(TAG, "Invalid packageName: " + packageName);
4727                        continue;
4728                    }
4729                    try {
4730                        pm.setPackageStoppedState(packageName, true, user);
4731                    } catch (RemoteException e) {
4732                    } catch (IllegalArgumentException e) {
4733                        Slog.w(TAG, "Failed trying to unstop package "
4734                                + packageName + ": " + e);
4735                    }
4736                    if (isUserRunningLocked(user, false)) {
4737                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4738                    }
4739                }
4740            }
4741        } finally {
4742            Binder.restoreCallingIdentity(callingId);
4743        }
4744    }
4745
4746    @Override
4747    public void addPackageDependency(String packageName) {
4748        synchronized (this) {
4749            int callingPid = Binder.getCallingPid();
4750            if (callingPid == Process.myPid()) {
4751                //  Yeah, um, no.
4752                Slog.w(TAG, "Can't addPackageDependency on system process");
4753                return;
4754            }
4755            ProcessRecord proc;
4756            synchronized (mPidsSelfLocked) {
4757                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4758            }
4759            if (proc != null) {
4760                if (proc.pkgDeps == null) {
4761                    proc.pkgDeps = new ArraySet<String>(1);
4762                }
4763                proc.pkgDeps.add(packageName);
4764            }
4765        }
4766    }
4767
4768    /*
4769     * The pkg name and app id have to be specified.
4770     */
4771    @Override
4772    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4773        if (pkg == null) {
4774            return;
4775        }
4776        // Make sure the uid is valid.
4777        if (appid < 0) {
4778            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4779            return;
4780        }
4781        int callerUid = Binder.getCallingUid();
4782        // Only the system server can kill an application
4783        if (callerUid == Process.SYSTEM_UID) {
4784            // Post an aysnc message to kill the application
4785            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4786            msg.arg1 = appid;
4787            msg.arg2 = 0;
4788            Bundle bundle = new Bundle();
4789            bundle.putString("pkg", pkg);
4790            bundle.putString("reason", reason);
4791            msg.obj = bundle;
4792            mHandler.sendMessage(msg);
4793        } else {
4794            throw new SecurityException(callerUid + " cannot kill pkg: " +
4795                    pkg);
4796        }
4797    }
4798
4799    @Override
4800    public void closeSystemDialogs(String reason) {
4801        enforceNotIsolatedCaller("closeSystemDialogs");
4802
4803        final int pid = Binder.getCallingPid();
4804        final int uid = Binder.getCallingUid();
4805        final long origId = Binder.clearCallingIdentity();
4806        try {
4807            synchronized (this) {
4808                // Only allow this from foreground processes, so that background
4809                // applications can't abuse it to prevent system UI from being shown.
4810                if (uid >= Process.FIRST_APPLICATION_UID) {
4811                    ProcessRecord proc;
4812                    synchronized (mPidsSelfLocked) {
4813                        proc = mPidsSelfLocked.get(pid);
4814                    }
4815                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4816                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4817                                + " from background process " + proc);
4818                        return;
4819                    }
4820                }
4821                closeSystemDialogsLocked(reason);
4822            }
4823        } finally {
4824            Binder.restoreCallingIdentity(origId);
4825        }
4826    }
4827
4828    void closeSystemDialogsLocked(String reason) {
4829        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4830        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4831                | Intent.FLAG_RECEIVER_FOREGROUND);
4832        if (reason != null) {
4833            intent.putExtra("reason", reason);
4834        }
4835        mWindowManager.closeSystemDialogs(reason);
4836
4837        mStackSupervisor.closeSystemDialogsLocked();
4838
4839        broadcastIntentLocked(null, null, intent, null,
4840                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4841                Process.SYSTEM_UID, UserHandle.USER_ALL);
4842    }
4843
4844    @Override
4845    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4846        enforceNotIsolatedCaller("getProcessMemoryInfo");
4847        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4848        for (int i=pids.length-1; i>=0; i--) {
4849            ProcessRecord proc;
4850            int oomAdj;
4851            synchronized (this) {
4852                synchronized (mPidsSelfLocked) {
4853                    proc = mPidsSelfLocked.get(pids[i]);
4854                    oomAdj = proc != null ? proc.setAdj : 0;
4855                }
4856            }
4857            infos[i] = new Debug.MemoryInfo();
4858            Debug.getMemoryInfo(pids[i], infos[i]);
4859            if (proc != null) {
4860                synchronized (this) {
4861                    if (proc.thread != null && proc.setAdj == oomAdj) {
4862                        // Record this for posterity if the process has been stable.
4863                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4864                                infos[i].getTotalUss(), false, proc.pkgList);
4865                    }
4866                }
4867            }
4868        }
4869        return infos;
4870    }
4871
4872    @Override
4873    public long[] getProcessPss(int[] pids) {
4874        enforceNotIsolatedCaller("getProcessPss");
4875        long[] pss = new long[pids.length];
4876        for (int i=pids.length-1; i>=0; i--) {
4877            ProcessRecord proc;
4878            int oomAdj;
4879            synchronized (this) {
4880                synchronized (mPidsSelfLocked) {
4881                    proc = mPidsSelfLocked.get(pids[i]);
4882                    oomAdj = proc != null ? proc.setAdj : 0;
4883                }
4884            }
4885            long[] tmpUss = new long[1];
4886            pss[i] = Debug.getPss(pids[i], tmpUss);
4887            if (proc != null) {
4888                synchronized (this) {
4889                    if (proc.thread != null && proc.setAdj == oomAdj) {
4890                        // Record this for posterity if the process has been stable.
4891                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4892                    }
4893                }
4894            }
4895        }
4896        return pss;
4897    }
4898
4899    @Override
4900    public void killApplicationProcess(String processName, int uid) {
4901        if (processName == null) {
4902            return;
4903        }
4904
4905        int callerUid = Binder.getCallingUid();
4906        // Only the system server can kill an application
4907        if (callerUid == Process.SYSTEM_UID) {
4908            synchronized (this) {
4909                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4910                if (app != null && app.thread != null) {
4911                    try {
4912                        app.thread.scheduleSuicide();
4913                    } catch (RemoteException e) {
4914                        // If the other end already died, then our work here is done.
4915                    }
4916                } else {
4917                    Slog.w(TAG, "Process/uid not found attempting kill of "
4918                            + processName + " / " + uid);
4919                }
4920            }
4921        } else {
4922            throw new SecurityException(callerUid + " cannot kill app process: " +
4923                    processName);
4924        }
4925    }
4926
4927    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4928        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4929                false, true, false, false, UserHandle.getUserId(uid), reason);
4930        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4931                Uri.fromParts("package", packageName, null));
4932        if (!mProcessesReady) {
4933            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4934                    | Intent.FLAG_RECEIVER_FOREGROUND);
4935        }
4936        intent.putExtra(Intent.EXTRA_UID, uid);
4937        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4938        broadcastIntentLocked(null, null, intent,
4939                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4940                false, false,
4941                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4942    }
4943
4944    private void forceStopUserLocked(int userId, String reason) {
4945        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4946        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4947        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4948                | Intent.FLAG_RECEIVER_FOREGROUND);
4949        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4950        broadcastIntentLocked(null, null, intent,
4951                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4952                false, false,
4953                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4954    }
4955
4956    private final boolean killPackageProcessesLocked(String packageName, int appId,
4957            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4958            boolean doit, boolean evenPersistent, String reason) {
4959        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4960
4961        // Remove all processes this package may have touched: all with the
4962        // same UID (except for the system or root user), and all whose name
4963        // matches the package name.
4964        final int NP = mProcessNames.getMap().size();
4965        for (int ip=0; ip<NP; ip++) {
4966            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4967            final int NA = apps.size();
4968            for (int ia=0; ia<NA; ia++) {
4969                ProcessRecord app = apps.valueAt(ia);
4970                if (app.persistent && !evenPersistent) {
4971                    // we don't kill persistent processes
4972                    continue;
4973                }
4974                if (app.removed) {
4975                    if (doit) {
4976                        procs.add(app);
4977                    }
4978                    continue;
4979                }
4980
4981                // Skip process if it doesn't meet our oom adj requirement.
4982                if (app.setAdj < minOomAdj) {
4983                    continue;
4984                }
4985
4986                // If no package is specified, we call all processes under the
4987                // give user id.
4988                if (packageName == null) {
4989                    if (app.userId != userId) {
4990                        continue;
4991                    }
4992                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4993                        continue;
4994                    }
4995                // Package has been specified, we want to hit all processes
4996                // that match it.  We need to qualify this by the processes
4997                // that are running under the specified app and user ID.
4998                } else {
4999                    final boolean isDep = app.pkgDeps != null
5000                            && app.pkgDeps.contains(packageName);
5001                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5002                        continue;
5003                    }
5004                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5005                        continue;
5006                    }
5007                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5008                        continue;
5009                    }
5010                }
5011
5012                // Process has passed all conditions, kill it!
5013                if (!doit) {
5014                    return true;
5015                }
5016                app.removed = true;
5017                procs.add(app);
5018            }
5019        }
5020
5021        int N = procs.size();
5022        for (int i=0; i<N; i++) {
5023            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5024        }
5025        updateOomAdjLocked();
5026        return N > 0;
5027    }
5028
5029    private final boolean forceStopPackageLocked(String name, int appId,
5030            boolean callerWillRestart, boolean purgeCache, boolean doit,
5031            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5032        int i;
5033        int N;
5034
5035        if (userId == UserHandle.USER_ALL && name == null) {
5036            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5037        }
5038
5039        if (appId < 0 && name != null) {
5040            try {
5041                appId = UserHandle.getAppId(
5042                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5043            } catch (RemoteException e) {
5044            }
5045        }
5046
5047        if (doit) {
5048            if (name != null) {
5049                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5050                        + " user=" + userId + ": " + reason);
5051            } else {
5052                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5053            }
5054
5055            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5056            for (int ip=pmap.size()-1; ip>=0; ip--) {
5057                SparseArray<Long> ba = pmap.valueAt(ip);
5058                for (i=ba.size()-1; i>=0; i--) {
5059                    boolean remove = false;
5060                    final int entUid = ba.keyAt(i);
5061                    if (name != null) {
5062                        if (userId == UserHandle.USER_ALL) {
5063                            if (UserHandle.getAppId(entUid) == appId) {
5064                                remove = true;
5065                            }
5066                        } else {
5067                            if (entUid == UserHandle.getUid(userId, appId)) {
5068                                remove = true;
5069                            }
5070                        }
5071                    } else if (UserHandle.getUserId(entUid) == userId) {
5072                        remove = true;
5073                    }
5074                    if (remove) {
5075                        ba.removeAt(i);
5076                    }
5077                }
5078                if (ba.size() == 0) {
5079                    pmap.removeAt(ip);
5080                }
5081            }
5082        }
5083
5084        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5085                -100, callerWillRestart, true, doit, evenPersistent,
5086                name == null ? ("stop user " + userId) : ("stop " + name));
5087
5088        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5089            if (!doit) {
5090                return true;
5091            }
5092            didSomething = true;
5093        }
5094
5095        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5096            if (!doit) {
5097                return true;
5098            }
5099            didSomething = true;
5100        }
5101
5102        if (name == null) {
5103            // Remove all sticky broadcasts from this user.
5104            mStickyBroadcasts.remove(userId);
5105        }
5106
5107        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5108        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5109                userId, providers)) {
5110            if (!doit) {
5111                return true;
5112            }
5113            didSomething = true;
5114        }
5115        N = providers.size();
5116        for (i=0; i<N; i++) {
5117            removeDyingProviderLocked(null, providers.get(i), true);
5118        }
5119
5120        // Remove transient permissions granted from/to this package/user
5121        removeUriPermissionsForPackageLocked(name, userId, false);
5122
5123        if (name == null || uninstalling) {
5124            // Remove pending intents.  For now we only do this when force
5125            // stopping users, because we have some problems when doing this
5126            // for packages -- app widgets are not currently cleaned up for
5127            // such packages, so they can be left with bad pending intents.
5128            if (mIntentSenderRecords.size() > 0) {
5129                Iterator<WeakReference<PendingIntentRecord>> it
5130                        = mIntentSenderRecords.values().iterator();
5131                while (it.hasNext()) {
5132                    WeakReference<PendingIntentRecord> wpir = it.next();
5133                    if (wpir == null) {
5134                        it.remove();
5135                        continue;
5136                    }
5137                    PendingIntentRecord pir = wpir.get();
5138                    if (pir == null) {
5139                        it.remove();
5140                        continue;
5141                    }
5142                    if (name == null) {
5143                        // Stopping user, remove all objects for the user.
5144                        if (pir.key.userId != userId) {
5145                            // Not the same user, skip it.
5146                            continue;
5147                        }
5148                    } else {
5149                        if (UserHandle.getAppId(pir.uid) != appId) {
5150                            // Different app id, skip it.
5151                            continue;
5152                        }
5153                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5154                            // Different user, skip it.
5155                            continue;
5156                        }
5157                        if (!pir.key.packageName.equals(name)) {
5158                            // Different package, skip it.
5159                            continue;
5160                        }
5161                    }
5162                    if (!doit) {
5163                        return true;
5164                    }
5165                    didSomething = true;
5166                    it.remove();
5167                    pir.canceled = true;
5168                    if (pir.key.activity != null) {
5169                        pir.key.activity.pendingResults.remove(pir.ref);
5170                    }
5171                }
5172            }
5173        }
5174
5175        if (doit) {
5176            if (purgeCache && name != null) {
5177                AttributeCache ac = AttributeCache.instance();
5178                if (ac != null) {
5179                    ac.removePackage(name);
5180                }
5181            }
5182            if (mBooted) {
5183                mStackSupervisor.resumeTopActivitiesLocked();
5184                mStackSupervisor.scheduleIdleLocked();
5185            }
5186        }
5187
5188        return didSomething;
5189    }
5190
5191    private final boolean removeProcessLocked(ProcessRecord app,
5192            boolean callerWillRestart, boolean allowRestart, String reason) {
5193        final String name = app.processName;
5194        final int uid = app.uid;
5195        if (DEBUG_PROCESSES) Slog.d(
5196            TAG, "Force removing proc " + app.toShortString() + " (" + name
5197            + "/" + uid + ")");
5198
5199        mProcessNames.remove(name, uid);
5200        mIsolatedProcesses.remove(app.uid);
5201        if (mHeavyWeightProcess == app) {
5202            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5203                    mHeavyWeightProcess.userId, 0));
5204            mHeavyWeightProcess = null;
5205        }
5206        boolean needRestart = false;
5207        if (app.pid > 0 && app.pid != MY_PID) {
5208            int pid = app.pid;
5209            synchronized (mPidsSelfLocked) {
5210                mPidsSelfLocked.remove(pid);
5211                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5212            }
5213            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5214            if (app.isolated) {
5215                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5216            }
5217            killUnneededProcessLocked(app, reason);
5218            Process.killProcessGroup(app.info.uid, app.pid);
5219            handleAppDiedLocked(app, true, allowRestart);
5220            removeLruProcessLocked(app);
5221
5222            if (app.persistent && !app.isolated) {
5223                if (!callerWillRestart) {
5224                    addAppLocked(app.info, false, null /* ABI override */);
5225                } else {
5226                    needRestart = true;
5227                }
5228            }
5229        } else {
5230            mRemovedProcesses.add(app);
5231        }
5232
5233        return needRestart;
5234    }
5235
5236    private final void processStartTimedOutLocked(ProcessRecord app) {
5237        final int pid = app.pid;
5238        boolean gone = false;
5239        synchronized (mPidsSelfLocked) {
5240            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5241            if (knownApp != null && knownApp.thread == null) {
5242                mPidsSelfLocked.remove(pid);
5243                gone = true;
5244            }
5245        }
5246
5247        if (gone) {
5248            Slog.w(TAG, "Process " + app + " failed to attach");
5249            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5250                    pid, app.uid, app.processName);
5251            mProcessNames.remove(app.processName, app.uid);
5252            mIsolatedProcesses.remove(app.uid);
5253            if (mHeavyWeightProcess == app) {
5254                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5255                        mHeavyWeightProcess.userId, 0));
5256                mHeavyWeightProcess = null;
5257            }
5258            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5259            if (app.isolated) {
5260                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5261            }
5262            // Take care of any launching providers waiting for this process.
5263            checkAppInLaunchingProvidersLocked(app, true);
5264            // Take care of any services that are waiting for the process.
5265            mServices.processStartTimedOutLocked(app);
5266            killUnneededProcessLocked(app, "start timeout");
5267            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5268                Slog.w(TAG, "Unattached app died before backup, skipping");
5269                try {
5270                    IBackupManager bm = IBackupManager.Stub.asInterface(
5271                            ServiceManager.getService(Context.BACKUP_SERVICE));
5272                    bm.agentDisconnected(app.info.packageName);
5273                } catch (RemoteException e) {
5274                    // Can't happen; the backup manager is local
5275                }
5276            }
5277            if (isPendingBroadcastProcessLocked(pid)) {
5278                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5279                skipPendingBroadcastLocked(pid);
5280            }
5281        } else {
5282            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5283        }
5284    }
5285
5286    private final boolean attachApplicationLocked(IApplicationThread thread,
5287            int pid) {
5288
5289        // Find the application record that is being attached...  either via
5290        // the pid if we are running in multiple processes, or just pull the
5291        // next app record if we are emulating process with anonymous threads.
5292        ProcessRecord app;
5293        if (pid != MY_PID && pid >= 0) {
5294            synchronized (mPidsSelfLocked) {
5295                app = mPidsSelfLocked.get(pid);
5296            }
5297        } else {
5298            app = null;
5299        }
5300
5301        if (app == null) {
5302            Slog.w(TAG, "No pending application record for pid " + pid
5303                    + " (IApplicationThread " + thread + "); dropping process");
5304            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5305            if (pid > 0 && pid != MY_PID) {
5306                Process.killProcessQuiet(pid);
5307                //TODO: Process.killProcessGroup(app.info.uid, pid);
5308            } else {
5309                try {
5310                    thread.scheduleExit();
5311                } catch (Exception e) {
5312                    // Ignore exceptions.
5313                }
5314            }
5315            return false;
5316        }
5317
5318        // If this application record is still attached to a previous
5319        // process, clean it up now.
5320        if (app.thread != null) {
5321            handleAppDiedLocked(app, true, true);
5322        }
5323
5324        // Tell the process all about itself.
5325
5326        if (localLOGV) Slog.v(
5327                TAG, "Binding process pid " + pid + " to record " + app);
5328
5329        final String processName = app.processName;
5330        try {
5331            AppDeathRecipient adr = new AppDeathRecipient(
5332                    app, pid, thread);
5333            thread.asBinder().linkToDeath(adr, 0);
5334            app.deathRecipient = adr;
5335        } catch (RemoteException e) {
5336            app.resetPackageList(mProcessStats);
5337            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5338            return false;
5339        }
5340
5341        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5342
5343        app.makeActive(thread, mProcessStats);
5344        app.curAdj = app.setAdj = -100;
5345        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5346        app.forcingToForeground = null;
5347        updateProcessForegroundLocked(app, false, false);
5348        app.hasShownUi = false;
5349        app.debugging = false;
5350        app.cached = false;
5351
5352        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5353
5354        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5355        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5356
5357        if (!normalMode) {
5358            Slog.i(TAG, "Launching preboot mode app: " + app);
5359        }
5360
5361        if (localLOGV) Slog.v(
5362            TAG, "New app record " + app
5363            + " thread=" + thread.asBinder() + " pid=" + pid);
5364        try {
5365            int testMode = IApplicationThread.DEBUG_OFF;
5366            if (mDebugApp != null && mDebugApp.equals(processName)) {
5367                testMode = mWaitForDebugger
5368                    ? IApplicationThread.DEBUG_WAIT
5369                    : IApplicationThread.DEBUG_ON;
5370                app.debugging = true;
5371                if (mDebugTransient) {
5372                    mDebugApp = mOrigDebugApp;
5373                    mWaitForDebugger = mOrigWaitForDebugger;
5374                }
5375            }
5376            String profileFile = app.instrumentationProfileFile;
5377            ParcelFileDescriptor profileFd = null;
5378            boolean profileAutoStop = false;
5379            if (mProfileApp != null && mProfileApp.equals(processName)) {
5380                mProfileProc = app;
5381                profileFile = mProfileFile;
5382                profileFd = mProfileFd;
5383                profileAutoStop = mAutoStopProfiler;
5384            }
5385            boolean enableOpenGlTrace = false;
5386            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5387                enableOpenGlTrace = true;
5388                mOpenGlTraceApp = null;
5389            }
5390
5391            // If the app is being launched for restore or full backup, set it up specially
5392            boolean isRestrictedBackupMode = false;
5393            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5394                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5395                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5396                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5397            }
5398
5399            ensurePackageDexOpt(app.instrumentationInfo != null
5400                    ? app.instrumentationInfo.packageName
5401                    : app.info.packageName);
5402            if (app.instrumentationClass != null) {
5403                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5404            }
5405            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5406                    + processName + " with config " + mConfiguration);
5407            ApplicationInfo appInfo = app.instrumentationInfo != null
5408                    ? app.instrumentationInfo : app.info;
5409            app.compat = compatibilityInfoForPackageLocked(appInfo);
5410            if (profileFd != null) {
5411                profileFd = profileFd.dup();
5412            }
5413            thread.bindApplication(processName, appInfo, providers,
5414                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5415                    app.instrumentationArguments, app.instrumentationWatcher,
5416                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5417                    isRestrictedBackupMode || !normalMode, app.persistent,
5418                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5419                    mCoreSettingsObserver.getCoreSettingsLocked());
5420            updateLruProcessLocked(app, false, null);
5421            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5422        } catch (Exception e) {
5423            // todo: Yikes!  What should we do?  For now we will try to
5424            // start another process, but that could easily get us in
5425            // an infinite loop of restarting processes...
5426            Slog.w(TAG, "Exception thrown during bind!", e);
5427
5428            app.resetPackageList(mProcessStats);
5429            app.unlinkDeathRecipient();
5430            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5431            return false;
5432        }
5433
5434        // Remove this record from the list of starting applications.
5435        mPersistentStartingProcesses.remove(app);
5436        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5437                "Attach application locked removing on hold: " + app);
5438        mProcessesOnHold.remove(app);
5439
5440        boolean badApp = false;
5441        boolean didSomething = false;
5442
5443        // See if the top visible activity is waiting to run in this process...
5444        if (normalMode) {
5445            try {
5446                if (mStackSupervisor.attachApplicationLocked(app)) {
5447                    didSomething = true;
5448                }
5449            } catch (Exception e) {
5450                badApp = true;
5451            }
5452        }
5453
5454        // Find any services that should be running in this process...
5455        if (!badApp) {
5456            try {
5457                didSomething |= mServices.attachApplicationLocked(app, processName);
5458            } catch (Exception e) {
5459                badApp = true;
5460            }
5461        }
5462
5463        // Check if a next-broadcast receiver is in this process...
5464        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5465            try {
5466                didSomething |= sendPendingBroadcastsLocked(app);
5467            } catch (Exception e) {
5468                // If the app died trying to launch the receiver we declare it 'bad'
5469                badApp = true;
5470            }
5471        }
5472
5473        // Check whether the next backup agent is in this process...
5474        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5475            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5476            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5477            try {
5478                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5479                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5480                        mBackupTarget.backupMode);
5481            } catch (Exception e) {
5482                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5483                e.printStackTrace();
5484            }
5485        }
5486
5487        if (badApp) {
5488            // todo: Also need to kill application to deal with all
5489            // kinds of exceptions.
5490            handleAppDiedLocked(app, false, true);
5491            return false;
5492        }
5493
5494        if (!didSomething) {
5495            updateOomAdjLocked();
5496        }
5497
5498        return true;
5499    }
5500
5501    @Override
5502    public final void attachApplication(IApplicationThread thread) {
5503        synchronized (this) {
5504            int callingPid = Binder.getCallingPid();
5505            final long origId = Binder.clearCallingIdentity();
5506            attachApplicationLocked(thread, callingPid);
5507            Binder.restoreCallingIdentity(origId);
5508        }
5509    }
5510
5511    @Override
5512    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5513        final long origId = Binder.clearCallingIdentity();
5514        synchronized (this) {
5515            ActivityStack stack = ActivityRecord.getStackLocked(token);
5516            if (stack != null) {
5517                ActivityRecord r =
5518                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5519                if (stopProfiling) {
5520                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5521                        try {
5522                            mProfileFd.close();
5523                        } catch (IOException e) {
5524                        }
5525                        clearProfilerLocked();
5526                    }
5527                }
5528            }
5529        }
5530        Binder.restoreCallingIdentity(origId);
5531    }
5532
5533    void postEnableScreenAfterBootLocked() {
5534        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5535    }
5536
5537    void enableScreenAfterBoot() {
5538        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5539                SystemClock.uptimeMillis());
5540        mWindowManager.enableScreenAfterBoot();
5541
5542        synchronized (this) {
5543            updateEventDispatchingLocked();
5544        }
5545    }
5546
5547    @Override
5548    public void showBootMessage(final CharSequence msg, final boolean always) {
5549        enforceNotIsolatedCaller("showBootMessage");
5550        mWindowManager.showBootMessage(msg, always);
5551    }
5552
5553    @Override
5554    public void dismissKeyguardOnNextActivity() {
5555        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5556        final long token = Binder.clearCallingIdentity();
5557        try {
5558            synchronized (this) {
5559                if (DEBUG_LOCKSCREEN) logLockScreen("");
5560                if (mLockScreenShown) {
5561                    mLockScreenShown = false;
5562                    comeOutOfSleepIfNeededLocked();
5563                }
5564                mStackSupervisor.setDismissKeyguard(true);
5565            }
5566        } finally {
5567            Binder.restoreCallingIdentity(token);
5568        }
5569    }
5570
5571    final void finishBooting() {
5572        // Register receivers to handle package update events
5573        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5574
5575        synchronized (this) {
5576            // Ensure that any processes we had put on hold are now started
5577            // up.
5578            final int NP = mProcessesOnHold.size();
5579            if (NP > 0) {
5580                ArrayList<ProcessRecord> procs =
5581                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5582                for (int ip=0; ip<NP; ip++) {
5583                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5584                            + procs.get(ip));
5585                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5586                }
5587            }
5588
5589            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5590                // Start looking for apps that are abusing wake locks.
5591                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5592                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5593                // Tell anyone interested that we are done booting!
5594                SystemProperties.set("sys.boot_completed", "1");
5595                SystemProperties.set("dev.bootcomplete", "1");
5596                for (int i=0; i<mStartedUsers.size(); i++) {
5597                    UserStartedState uss = mStartedUsers.valueAt(i);
5598                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5599                        uss.mState = UserStartedState.STATE_RUNNING;
5600                        final int userId = mStartedUsers.keyAt(i);
5601                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5602                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5603                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5604                        broadcastIntentLocked(null, null, intent, null,
5605                                new IIntentReceiver.Stub() {
5606                                    @Override
5607                                    public void performReceive(Intent intent, int resultCode,
5608                                            String data, Bundle extras, boolean ordered,
5609                                            boolean sticky, int sendingUser) {
5610                                        synchronized (ActivityManagerService.this) {
5611                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5612                                                    true, false);
5613                                        }
5614                                    }
5615                                },
5616                                0, null, null,
5617                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5618                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5619                                userId);
5620                    }
5621                }
5622                scheduleStartProfilesLocked();
5623            }
5624        }
5625    }
5626
5627    final void ensureBootCompleted() {
5628        boolean booting;
5629        boolean enableScreen;
5630        synchronized (this) {
5631            booting = mBooting;
5632            mBooting = false;
5633            enableScreen = !mBooted;
5634            mBooted = true;
5635        }
5636
5637        if (booting) {
5638            finishBooting();
5639        }
5640
5641        if (enableScreen) {
5642            enableScreenAfterBoot();
5643        }
5644    }
5645
5646    @Override
5647    public final void activityResumed(IBinder token) {
5648        final long origId = Binder.clearCallingIdentity();
5649        synchronized(this) {
5650            ActivityStack stack = ActivityRecord.getStackLocked(token);
5651            if (stack != null) {
5652                ActivityRecord.activityResumedLocked(token);
5653            }
5654        }
5655        Binder.restoreCallingIdentity(origId);
5656    }
5657
5658    @Override
5659    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5660        final long origId = Binder.clearCallingIdentity();
5661        synchronized(this) {
5662            ActivityStack stack = ActivityRecord.getStackLocked(token);
5663            if (stack != null) {
5664                stack.activityPausedLocked(token, false, persistentState);
5665            }
5666        }
5667        Binder.restoreCallingIdentity(origId);
5668    }
5669
5670    @Override
5671    public final void activityStopped(IBinder token, Bundle icicle,
5672            PersistableBundle persistentState, CharSequence description) {
5673        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5674
5675        // Refuse possible leaked file descriptors
5676        if (icicle != null && icicle.hasFileDescriptors()) {
5677            throw new IllegalArgumentException("File descriptors passed in Bundle");
5678        }
5679
5680        final long origId = Binder.clearCallingIdentity();
5681
5682        synchronized (this) {
5683            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5684            if (r != null) {
5685                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5686            }
5687        }
5688
5689        trimApplications();
5690
5691        Binder.restoreCallingIdentity(origId);
5692    }
5693
5694    @Override
5695    public final void activityDestroyed(IBinder token) {
5696        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5697        synchronized (this) {
5698            ActivityStack stack = ActivityRecord.getStackLocked(token);
5699            if (stack != null) {
5700                stack.activityDestroyedLocked(token);
5701            }
5702        }
5703    }
5704
5705    @Override
5706    public final void mediaResourcesReleased(IBinder token) {
5707        final long origId = Binder.clearCallingIdentity();
5708        try {
5709            synchronized (this) {
5710                ActivityStack stack = ActivityRecord.getStackLocked(token);
5711                if (stack != null) {
5712                    stack.mediaResourcesReleased(token);
5713                }
5714            }
5715        } finally {
5716            Binder.restoreCallingIdentity(origId);
5717        }
5718    }
5719
5720    @Override
5721    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5722        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5723    }
5724
5725    @Override
5726    public final void notifyEnterAnimationComplete(IBinder token) {
5727        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5728    }
5729
5730    @Override
5731    public String getCallingPackage(IBinder token) {
5732        synchronized (this) {
5733            ActivityRecord r = getCallingRecordLocked(token);
5734            return r != null ? r.info.packageName : null;
5735        }
5736    }
5737
5738    @Override
5739    public ComponentName getCallingActivity(IBinder token) {
5740        synchronized (this) {
5741            ActivityRecord r = getCallingRecordLocked(token);
5742            return r != null ? r.intent.getComponent() : null;
5743        }
5744    }
5745
5746    private ActivityRecord getCallingRecordLocked(IBinder token) {
5747        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5748        if (r == null) {
5749            return null;
5750        }
5751        return r.resultTo;
5752    }
5753
5754    @Override
5755    public ComponentName getActivityClassForToken(IBinder token) {
5756        synchronized(this) {
5757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5758            if (r == null) {
5759                return null;
5760            }
5761            return r.intent.getComponent();
5762        }
5763    }
5764
5765    @Override
5766    public String getPackageForToken(IBinder token) {
5767        synchronized(this) {
5768            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5769            if (r == null) {
5770                return null;
5771            }
5772            return r.packageName;
5773        }
5774    }
5775
5776    @Override
5777    public IIntentSender getIntentSender(int type,
5778            String packageName, IBinder token, String resultWho,
5779            int requestCode, Intent[] intents, String[] resolvedTypes,
5780            int flags, Bundle options, int userId) {
5781        enforceNotIsolatedCaller("getIntentSender");
5782        // Refuse possible leaked file descriptors
5783        if (intents != null) {
5784            if (intents.length < 1) {
5785                throw new IllegalArgumentException("Intents array length must be >= 1");
5786            }
5787            for (int i=0; i<intents.length; i++) {
5788                Intent intent = intents[i];
5789                if (intent != null) {
5790                    if (intent.hasFileDescriptors()) {
5791                        throw new IllegalArgumentException("File descriptors passed in Intent");
5792                    }
5793                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5794                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5795                        throw new IllegalArgumentException(
5796                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5797                    }
5798                    intents[i] = new Intent(intent);
5799                }
5800            }
5801            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5802                throw new IllegalArgumentException(
5803                        "Intent array length does not match resolvedTypes length");
5804            }
5805        }
5806        if (options != null) {
5807            if (options.hasFileDescriptors()) {
5808                throw new IllegalArgumentException("File descriptors passed in options");
5809            }
5810        }
5811
5812        synchronized(this) {
5813            int callingUid = Binder.getCallingUid();
5814            int origUserId = userId;
5815            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5816                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5817                    ALLOW_NON_FULL, "getIntentSender", null);
5818            if (origUserId == UserHandle.USER_CURRENT) {
5819                // We don't want to evaluate this until the pending intent is
5820                // actually executed.  However, we do want to always do the
5821                // security checking for it above.
5822                userId = UserHandle.USER_CURRENT;
5823            }
5824            try {
5825                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5826                    int uid = AppGlobals.getPackageManager()
5827                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5828                    if (!UserHandle.isSameApp(callingUid, uid)) {
5829                        String msg = "Permission Denial: getIntentSender() from pid="
5830                            + Binder.getCallingPid()
5831                            + ", uid=" + Binder.getCallingUid()
5832                            + ", (need uid=" + uid + ")"
5833                            + " is not allowed to send as package " + packageName;
5834                        Slog.w(TAG, msg);
5835                        throw new SecurityException(msg);
5836                    }
5837                }
5838
5839                return getIntentSenderLocked(type, packageName, callingUid, userId,
5840                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5841
5842            } catch (RemoteException e) {
5843                throw new SecurityException(e);
5844            }
5845        }
5846    }
5847
5848    IIntentSender getIntentSenderLocked(int type, String packageName,
5849            int callingUid, int userId, IBinder token, String resultWho,
5850            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5851            Bundle options) {
5852        if (DEBUG_MU)
5853            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5854        ActivityRecord activity = null;
5855        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5856            activity = ActivityRecord.isInStackLocked(token);
5857            if (activity == null) {
5858                return null;
5859            }
5860            if (activity.finishing) {
5861                return null;
5862            }
5863        }
5864
5865        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5866        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5867        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5868        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5869                |PendingIntent.FLAG_UPDATE_CURRENT);
5870
5871        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5872                type, packageName, activity, resultWho,
5873                requestCode, intents, resolvedTypes, flags, options, userId);
5874        WeakReference<PendingIntentRecord> ref;
5875        ref = mIntentSenderRecords.get(key);
5876        PendingIntentRecord rec = ref != null ? ref.get() : null;
5877        if (rec != null) {
5878            if (!cancelCurrent) {
5879                if (updateCurrent) {
5880                    if (rec.key.requestIntent != null) {
5881                        rec.key.requestIntent.replaceExtras(intents != null ?
5882                                intents[intents.length - 1] : null);
5883                    }
5884                    if (intents != null) {
5885                        intents[intents.length-1] = rec.key.requestIntent;
5886                        rec.key.allIntents = intents;
5887                        rec.key.allResolvedTypes = resolvedTypes;
5888                    } else {
5889                        rec.key.allIntents = null;
5890                        rec.key.allResolvedTypes = null;
5891                    }
5892                }
5893                return rec;
5894            }
5895            rec.canceled = true;
5896            mIntentSenderRecords.remove(key);
5897        }
5898        if (noCreate) {
5899            return rec;
5900        }
5901        rec = new PendingIntentRecord(this, key, callingUid);
5902        mIntentSenderRecords.put(key, rec.ref);
5903        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5904            if (activity.pendingResults == null) {
5905                activity.pendingResults
5906                        = new HashSet<WeakReference<PendingIntentRecord>>();
5907            }
5908            activity.pendingResults.add(rec.ref);
5909        }
5910        return rec;
5911    }
5912
5913    @Override
5914    public void cancelIntentSender(IIntentSender sender) {
5915        if (!(sender instanceof PendingIntentRecord)) {
5916            return;
5917        }
5918        synchronized(this) {
5919            PendingIntentRecord rec = (PendingIntentRecord)sender;
5920            try {
5921                int uid = AppGlobals.getPackageManager()
5922                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5923                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5924                    String msg = "Permission Denial: cancelIntentSender() from pid="
5925                        + Binder.getCallingPid()
5926                        + ", uid=" + Binder.getCallingUid()
5927                        + " is not allowed to cancel packges "
5928                        + rec.key.packageName;
5929                    Slog.w(TAG, msg);
5930                    throw new SecurityException(msg);
5931                }
5932            } catch (RemoteException e) {
5933                throw new SecurityException(e);
5934            }
5935            cancelIntentSenderLocked(rec, true);
5936        }
5937    }
5938
5939    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5940        rec.canceled = true;
5941        mIntentSenderRecords.remove(rec.key);
5942        if (cleanActivity && rec.key.activity != null) {
5943            rec.key.activity.pendingResults.remove(rec.ref);
5944        }
5945    }
5946
5947    @Override
5948    public String getPackageForIntentSender(IIntentSender pendingResult) {
5949        if (!(pendingResult instanceof PendingIntentRecord)) {
5950            return null;
5951        }
5952        try {
5953            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5954            return res.key.packageName;
5955        } catch (ClassCastException e) {
5956        }
5957        return null;
5958    }
5959
5960    @Override
5961    public int getUidForIntentSender(IIntentSender sender) {
5962        if (sender instanceof PendingIntentRecord) {
5963            try {
5964                PendingIntentRecord res = (PendingIntentRecord)sender;
5965                return res.uid;
5966            } catch (ClassCastException e) {
5967            }
5968        }
5969        return -1;
5970    }
5971
5972    @Override
5973    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5974        if (!(pendingResult instanceof PendingIntentRecord)) {
5975            return false;
5976        }
5977        try {
5978            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5979            if (res.key.allIntents == null) {
5980                return false;
5981            }
5982            for (int i=0; i<res.key.allIntents.length; i++) {
5983                Intent intent = res.key.allIntents[i];
5984                if (intent.getPackage() != null && intent.getComponent() != null) {
5985                    return false;
5986                }
5987            }
5988            return true;
5989        } catch (ClassCastException e) {
5990        }
5991        return false;
5992    }
5993
5994    @Override
5995    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5996        if (!(pendingResult instanceof PendingIntentRecord)) {
5997            return false;
5998        }
5999        try {
6000            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6001            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6002                return true;
6003            }
6004            return false;
6005        } catch (ClassCastException e) {
6006        }
6007        return false;
6008    }
6009
6010    @Override
6011    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6012        if (!(pendingResult instanceof PendingIntentRecord)) {
6013            return null;
6014        }
6015        try {
6016            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6017            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6018        } catch (ClassCastException e) {
6019        }
6020        return null;
6021    }
6022
6023    @Override
6024    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6025        if (!(pendingResult instanceof PendingIntentRecord)) {
6026            return null;
6027        }
6028        try {
6029            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6030            Intent intent = res.key.requestIntent;
6031            if (intent != null) {
6032                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6033                        || res.lastTagPrefix.equals(prefix))) {
6034                    return res.lastTag;
6035                }
6036                res.lastTagPrefix = prefix;
6037                StringBuilder sb = new StringBuilder(128);
6038                if (prefix != null) {
6039                    sb.append(prefix);
6040                }
6041                if (intent.getAction() != null) {
6042                    sb.append(intent.getAction());
6043                } else if (intent.getComponent() != null) {
6044                    intent.getComponent().appendShortString(sb);
6045                } else {
6046                    sb.append("?");
6047                }
6048                return res.lastTag = sb.toString();
6049            }
6050        } catch (ClassCastException e) {
6051        }
6052        return null;
6053    }
6054
6055    @Override
6056    public void setProcessLimit(int max) {
6057        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6058                "setProcessLimit()");
6059        synchronized (this) {
6060            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6061            mProcessLimitOverride = max;
6062        }
6063        trimApplications();
6064    }
6065
6066    @Override
6067    public int getProcessLimit() {
6068        synchronized (this) {
6069            return mProcessLimitOverride;
6070        }
6071    }
6072
6073    void foregroundTokenDied(ForegroundToken token) {
6074        synchronized (ActivityManagerService.this) {
6075            synchronized (mPidsSelfLocked) {
6076                ForegroundToken cur
6077                    = mForegroundProcesses.get(token.pid);
6078                if (cur != token) {
6079                    return;
6080                }
6081                mForegroundProcesses.remove(token.pid);
6082                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6083                if (pr == null) {
6084                    return;
6085                }
6086                pr.forcingToForeground = null;
6087                updateProcessForegroundLocked(pr, false, false);
6088            }
6089            updateOomAdjLocked();
6090        }
6091    }
6092
6093    @Override
6094    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6095        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6096                "setProcessForeground()");
6097        synchronized(this) {
6098            boolean changed = false;
6099
6100            synchronized (mPidsSelfLocked) {
6101                ProcessRecord pr = mPidsSelfLocked.get(pid);
6102                if (pr == null && isForeground) {
6103                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6104                    return;
6105                }
6106                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6107                if (oldToken != null) {
6108                    oldToken.token.unlinkToDeath(oldToken, 0);
6109                    mForegroundProcesses.remove(pid);
6110                    if (pr != null) {
6111                        pr.forcingToForeground = null;
6112                    }
6113                    changed = true;
6114                }
6115                if (isForeground && token != null) {
6116                    ForegroundToken newToken = new ForegroundToken() {
6117                        @Override
6118                        public void binderDied() {
6119                            foregroundTokenDied(this);
6120                        }
6121                    };
6122                    newToken.pid = pid;
6123                    newToken.token = token;
6124                    try {
6125                        token.linkToDeath(newToken, 0);
6126                        mForegroundProcesses.put(pid, newToken);
6127                        pr.forcingToForeground = token;
6128                        changed = true;
6129                    } catch (RemoteException e) {
6130                        // If the process died while doing this, we will later
6131                        // do the cleanup with the process death link.
6132                    }
6133                }
6134            }
6135
6136            if (changed) {
6137                updateOomAdjLocked();
6138            }
6139        }
6140    }
6141
6142    // =========================================================
6143    // PERMISSIONS
6144    // =========================================================
6145
6146    static class PermissionController extends IPermissionController.Stub {
6147        ActivityManagerService mActivityManagerService;
6148        PermissionController(ActivityManagerService activityManagerService) {
6149            mActivityManagerService = activityManagerService;
6150        }
6151
6152        @Override
6153        public boolean checkPermission(String permission, int pid, int uid) {
6154            return mActivityManagerService.checkPermission(permission, pid,
6155                    uid) == PackageManager.PERMISSION_GRANTED;
6156        }
6157    }
6158
6159    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6160        @Override
6161        public int checkComponentPermission(String permission, int pid, int uid,
6162                int owningUid, boolean exported) {
6163            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6164                    owningUid, exported);
6165        }
6166
6167        @Override
6168        public Object getAMSLock() {
6169            return ActivityManagerService.this;
6170        }
6171    }
6172
6173    /**
6174     * This can be called with or without the global lock held.
6175     */
6176    int checkComponentPermission(String permission, int pid, int uid,
6177            int owningUid, boolean exported) {
6178        // We might be performing an operation on behalf of an indirect binder
6179        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6180        // client identity accordingly before proceeding.
6181        Identity tlsIdentity = sCallerIdentity.get();
6182        if (tlsIdentity != null) {
6183            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6184                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6185            uid = tlsIdentity.uid;
6186            pid = tlsIdentity.pid;
6187        }
6188
6189        if (pid == MY_PID) {
6190            return PackageManager.PERMISSION_GRANTED;
6191        }
6192
6193        return ActivityManager.checkComponentPermission(permission, uid,
6194                owningUid, exported);
6195    }
6196
6197    /**
6198     * As the only public entry point for permissions checking, this method
6199     * can enforce the semantic that requesting a check on a null global
6200     * permission is automatically denied.  (Internally a null permission
6201     * string is used when calling {@link #checkComponentPermission} in cases
6202     * when only uid-based security is needed.)
6203     *
6204     * This can be called with or without the global lock held.
6205     */
6206    @Override
6207    public int checkPermission(String permission, int pid, int uid) {
6208        if (permission == null) {
6209            return PackageManager.PERMISSION_DENIED;
6210        }
6211        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6212    }
6213
6214    /**
6215     * Binder IPC calls go through the public entry point.
6216     * This can be called with or without the global lock held.
6217     */
6218    int checkCallingPermission(String permission) {
6219        return checkPermission(permission,
6220                Binder.getCallingPid(),
6221                UserHandle.getAppId(Binder.getCallingUid()));
6222    }
6223
6224    /**
6225     * This can be called with or without the global lock held.
6226     */
6227    void enforceCallingPermission(String permission, String func) {
6228        if (checkCallingPermission(permission)
6229                == PackageManager.PERMISSION_GRANTED) {
6230            return;
6231        }
6232
6233        String msg = "Permission Denial: " + func + " from pid="
6234                + Binder.getCallingPid()
6235                + ", uid=" + Binder.getCallingUid()
6236                + " requires " + permission;
6237        Slog.w(TAG, msg);
6238        throw new SecurityException(msg);
6239    }
6240
6241    /**
6242     * Determine if UID is holding permissions required to access {@link Uri} in
6243     * the given {@link ProviderInfo}. Final permission checking is always done
6244     * in {@link ContentProvider}.
6245     */
6246    private final boolean checkHoldingPermissionsLocked(
6247            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6248        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6249                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6250        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6251            return false;
6252        }
6253        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6254    }
6255
6256    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6257            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6258        if (pi.applicationInfo.uid == uid) {
6259            return true;
6260        } else if (!pi.exported) {
6261            return false;
6262        }
6263
6264        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6265        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6266        try {
6267            // check if target holds top-level <provider> permissions
6268            if (!readMet && pi.readPermission != null && considerUidPermissions
6269                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6270                readMet = true;
6271            }
6272            if (!writeMet && pi.writePermission != null && considerUidPermissions
6273                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6274                writeMet = true;
6275            }
6276
6277            // track if unprotected read/write is allowed; any denied
6278            // <path-permission> below removes this ability
6279            boolean allowDefaultRead = pi.readPermission == null;
6280            boolean allowDefaultWrite = pi.writePermission == null;
6281
6282            // check if target holds any <path-permission> that match uri
6283            final PathPermission[] pps = pi.pathPermissions;
6284            if (pps != null) {
6285                final String path = grantUri.uri.getPath();
6286                int i = pps.length;
6287                while (i > 0 && (!readMet || !writeMet)) {
6288                    i--;
6289                    PathPermission pp = pps[i];
6290                    if (pp.match(path)) {
6291                        if (!readMet) {
6292                            final String pprperm = pp.getReadPermission();
6293                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6294                                    + pprperm + " for " + pp.getPath()
6295                                    + ": match=" + pp.match(path)
6296                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6297                            if (pprperm != null) {
6298                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6299                                        == PERMISSION_GRANTED) {
6300                                    readMet = true;
6301                                } else {
6302                                    allowDefaultRead = false;
6303                                }
6304                            }
6305                        }
6306                        if (!writeMet) {
6307                            final String ppwperm = pp.getWritePermission();
6308                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6309                                    + ppwperm + " for " + pp.getPath()
6310                                    + ": match=" + pp.match(path)
6311                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6312                            if (ppwperm != null) {
6313                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6314                                        == PERMISSION_GRANTED) {
6315                                    writeMet = true;
6316                                } else {
6317                                    allowDefaultWrite = false;
6318                                }
6319                            }
6320                        }
6321                    }
6322                }
6323            }
6324
6325            // grant unprotected <provider> read/write, if not blocked by
6326            // <path-permission> above
6327            if (allowDefaultRead) readMet = true;
6328            if (allowDefaultWrite) writeMet = true;
6329
6330        } catch (RemoteException e) {
6331            return false;
6332        }
6333
6334        return readMet && writeMet;
6335    }
6336
6337    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6338        ProviderInfo pi = null;
6339        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6340        if (cpr != null) {
6341            pi = cpr.info;
6342        } else {
6343            try {
6344                pi = AppGlobals.getPackageManager().resolveContentProvider(
6345                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6346            } catch (RemoteException ex) {
6347            }
6348        }
6349        return pi;
6350    }
6351
6352    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6353        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6354        if (targetUris != null) {
6355            return targetUris.get(grantUri);
6356        }
6357        return null;
6358    }
6359
6360    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6361            String targetPkg, int targetUid, GrantUri grantUri) {
6362        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6363        if (targetUris == null) {
6364            targetUris = Maps.newArrayMap();
6365            mGrantedUriPermissions.put(targetUid, targetUris);
6366        }
6367
6368        UriPermission perm = targetUris.get(grantUri);
6369        if (perm == null) {
6370            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6371            targetUris.put(grantUri, perm);
6372        }
6373
6374        return perm;
6375    }
6376
6377    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6378            final int modeFlags) {
6379        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6380        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6381                : UriPermission.STRENGTH_OWNED;
6382
6383        // Root gets to do everything.
6384        if (uid == 0) {
6385            return true;
6386        }
6387
6388        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6389        if (perms == null) return false;
6390
6391        // First look for exact match
6392        final UriPermission exactPerm = perms.get(grantUri);
6393        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6394            return true;
6395        }
6396
6397        // No exact match, look for prefixes
6398        final int N = perms.size();
6399        for (int i = 0; i < N; i++) {
6400            final UriPermission perm = perms.valueAt(i);
6401            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6402                    && perm.getStrength(modeFlags) >= minStrength) {
6403                return true;
6404            }
6405        }
6406
6407        return false;
6408    }
6409
6410    @Override
6411    public int checkUriPermission(Uri uri, int pid, int uid,
6412            final int modeFlags, int userId) {
6413        enforceNotIsolatedCaller("checkUriPermission");
6414
6415        // Another redirected-binder-call permissions check as in
6416        // {@link checkComponentPermission}.
6417        Identity tlsIdentity = sCallerIdentity.get();
6418        if (tlsIdentity != null) {
6419            uid = tlsIdentity.uid;
6420            pid = tlsIdentity.pid;
6421        }
6422
6423        // Our own process gets to do everything.
6424        if (pid == MY_PID) {
6425            return PackageManager.PERMISSION_GRANTED;
6426        }
6427        synchronized (this) {
6428            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6429                    ? PackageManager.PERMISSION_GRANTED
6430                    : PackageManager.PERMISSION_DENIED;
6431        }
6432    }
6433
6434    /**
6435     * Check if the targetPkg can be granted permission to access uri by
6436     * the callingUid using the given modeFlags.  Throws a security exception
6437     * if callingUid is not allowed to do this.  Returns the uid of the target
6438     * if the URI permission grant should be performed; returns -1 if it is not
6439     * needed (for example targetPkg already has permission to access the URI).
6440     * If you already know the uid of the target, you can supply it in
6441     * lastTargetUid else set that to -1.
6442     */
6443    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6444            final int modeFlags, int lastTargetUid) {
6445        if (!Intent.isAccessUriMode(modeFlags)) {
6446            return -1;
6447        }
6448
6449        if (targetPkg != null) {
6450            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6451                    "Checking grant " + targetPkg + " permission to " + grantUri);
6452        }
6453
6454        final IPackageManager pm = AppGlobals.getPackageManager();
6455
6456        // If this is not a content: uri, we can't do anything with it.
6457        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6458            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6459                    "Can't grant URI permission for non-content URI: " + grantUri);
6460            return -1;
6461        }
6462
6463        final String authority = grantUri.uri.getAuthority();
6464        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6465        if (pi == null) {
6466            Slog.w(TAG, "No content provider found for permission check: " +
6467                    grantUri.uri.toSafeString());
6468            return -1;
6469        }
6470
6471        int targetUid = lastTargetUid;
6472        if (targetUid < 0 && targetPkg != null) {
6473            try {
6474                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6475                if (targetUid < 0) {
6476                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6477                            "Can't grant URI permission no uid for: " + targetPkg);
6478                    return -1;
6479                }
6480            } catch (RemoteException ex) {
6481                return -1;
6482            }
6483        }
6484
6485        if (targetUid >= 0) {
6486            // First...  does the target actually need this permission?
6487            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6488                // No need to grant the target this permission.
6489                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6490                        "Target " + targetPkg + " already has full permission to " + grantUri);
6491                return -1;
6492            }
6493        } else {
6494            // First...  there is no target package, so can anyone access it?
6495            boolean allowed = pi.exported;
6496            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6497                if (pi.readPermission != null) {
6498                    allowed = false;
6499                }
6500            }
6501            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6502                if (pi.writePermission != null) {
6503                    allowed = false;
6504                }
6505            }
6506            if (allowed) {
6507                return -1;
6508            }
6509        }
6510
6511        /* There is a special cross user grant if:
6512         * - The target is on another user.
6513         * - Apps on the current user can access the uri without any uid permissions.
6514         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6515         * grant uri permissions.
6516         */
6517        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6518                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6519                modeFlags, false /*without considering the uid permissions*/);
6520
6521        // Second...  is the provider allowing granting of URI permissions?
6522        if (!specialCrossUserGrant) {
6523            if (!pi.grantUriPermissions) {
6524                throw new SecurityException("Provider " + pi.packageName
6525                        + "/" + pi.name
6526                        + " does not allow granting of Uri permissions (uri "
6527                        + grantUri + ")");
6528            }
6529            if (pi.uriPermissionPatterns != null) {
6530                final int N = pi.uriPermissionPatterns.length;
6531                boolean allowed = false;
6532                for (int i=0; i<N; i++) {
6533                    if (pi.uriPermissionPatterns[i] != null
6534                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6535                        allowed = true;
6536                        break;
6537                    }
6538                }
6539                if (!allowed) {
6540                    throw new SecurityException("Provider " + pi.packageName
6541                            + "/" + pi.name
6542                            + " does not allow granting of permission to path of Uri "
6543                            + grantUri);
6544                }
6545            }
6546        }
6547
6548        // Third...  does the caller itself have permission to access
6549        // this uri?
6550        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6551            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6552                // Require they hold a strong enough Uri permission
6553                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6554                    throw new SecurityException("Uid " + callingUid
6555                            + " does not have permission to uri " + grantUri);
6556                }
6557            }
6558        }
6559        return targetUid;
6560    }
6561
6562    @Override
6563    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6564            final int modeFlags, int userId) {
6565        enforceNotIsolatedCaller("checkGrantUriPermission");
6566        synchronized(this) {
6567            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6568                    new GrantUri(userId, uri, false), modeFlags, -1);
6569        }
6570    }
6571
6572    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6573            final int modeFlags, UriPermissionOwner owner) {
6574        if (!Intent.isAccessUriMode(modeFlags)) {
6575            return;
6576        }
6577
6578        // So here we are: the caller has the assumed permission
6579        // to the uri, and the target doesn't.  Let's now give this to
6580        // the target.
6581
6582        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6583                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6584
6585        final String authority = grantUri.uri.getAuthority();
6586        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6587        if (pi == null) {
6588            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6589            return;
6590        }
6591
6592        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6593            grantUri.prefix = true;
6594        }
6595        final UriPermission perm = findOrCreateUriPermissionLocked(
6596                pi.packageName, targetPkg, targetUid, grantUri);
6597        perm.grantModes(modeFlags, owner);
6598    }
6599
6600    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6601            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6602        if (targetPkg == null) {
6603            throw new NullPointerException("targetPkg");
6604        }
6605        int targetUid;
6606        final IPackageManager pm = AppGlobals.getPackageManager();
6607        try {
6608            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6609        } catch (RemoteException ex) {
6610            return;
6611        }
6612
6613        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6614                targetUid);
6615        if (targetUid < 0) {
6616            return;
6617        }
6618
6619        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6620                owner);
6621    }
6622
6623    static class NeededUriGrants extends ArrayList<GrantUri> {
6624        final String targetPkg;
6625        final int targetUid;
6626        final int flags;
6627
6628        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6629            this.targetPkg = targetPkg;
6630            this.targetUid = targetUid;
6631            this.flags = flags;
6632        }
6633    }
6634
6635    /**
6636     * Like checkGrantUriPermissionLocked, but takes an Intent.
6637     */
6638    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6639            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6640        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6641                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6642                + " clip=" + (intent != null ? intent.getClipData() : null)
6643                + " from " + intent + "; flags=0x"
6644                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6645
6646        if (targetPkg == null) {
6647            throw new NullPointerException("targetPkg");
6648        }
6649
6650        if (intent == null) {
6651            return null;
6652        }
6653        Uri data = intent.getData();
6654        ClipData clip = intent.getClipData();
6655        if (data == null && clip == null) {
6656            return null;
6657        }
6658        // Default userId for uris in the intent (if they don't specify it themselves)
6659        int contentUserHint = intent.getContentUserHint();
6660        if (contentUserHint == UserHandle.USER_CURRENT) {
6661            contentUserHint = UserHandle.getUserId(callingUid);
6662        }
6663        final IPackageManager pm = AppGlobals.getPackageManager();
6664        int targetUid;
6665        if (needed != null) {
6666            targetUid = needed.targetUid;
6667        } else {
6668            try {
6669                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6670            } catch (RemoteException ex) {
6671                return null;
6672            }
6673            if (targetUid < 0) {
6674                if (DEBUG_URI_PERMISSION) {
6675                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6676                            + " on user " + targetUserId);
6677                }
6678                return null;
6679            }
6680        }
6681        if (data != null) {
6682            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6683            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6684                    targetUid);
6685            if (targetUid > 0) {
6686                if (needed == null) {
6687                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6688                }
6689                needed.add(grantUri);
6690            }
6691        }
6692        if (clip != null) {
6693            for (int i=0; i<clip.getItemCount(); i++) {
6694                Uri uri = clip.getItemAt(i).getUri();
6695                if (uri != null) {
6696                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6697                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6698                            targetUid);
6699                    if (targetUid > 0) {
6700                        if (needed == null) {
6701                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6702                        }
6703                        needed.add(grantUri);
6704                    }
6705                } else {
6706                    Intent clipIntent = clip.getItemAt(i).getIntent();
6707                    if (clipIntent != null) {
6708                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6709                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6710                        if (newNeeded != null) {
6711                            needed = newNeeded;
6712                        }
6713                    }
6714                }
6715            }
6716        }
6717
6718        return needed;
6719    }
6720
6721    /**
6722     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6723     */
6724    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6725            UriPermissionOwner owner) {
6726        if (needed != null) {
6727            for (int i=0; i<needed.size(); i++) {
6728                GrantUri grantUri = needed.get(i);
6729                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6730                        grantUri, needed.flags, owner);
6731            }
6732        }
6733    }
6734
6735    void grantUriPermissionFromIntentLocked(int callingUid,
6736            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6737        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6738                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6739        if (needed == null) {
6740            return;
6741        }
6742
6743        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6744    }
6745
6746    @Override
6747    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6748            final int modeFlags, int userId) {
6749        enforceNotIsolatedCaller("grantUriPermission");
6750        GrantUri grantUri = new GrantUri(userId, uri, false);
6751        synchronized(this) {
6752            final ProcessRecord r = getRecordForAppLocked(caller);
6753            if (r == null) {
6754                throw new SecurityException("Unable to find app for caller "
6755                        + caller
6756                        + " when granting permission to uri " + grantUri);
6757            }
6758            if (targetPkg == null) {
6759                throw new IllegalArgumentException("null target");
6760            }
6761            if (grantUri == null) {
6762                throw new IllegalArgumentException("null uri");
6763            }
6764
6765            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6766                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6767                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6768                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6769
6770            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6771                    UserHandle.getUserId(r.uid));
6772        }
6773    }
6774
6775    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6776        if (perm.modeFlags == 0) {
6777            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6778                    perm.targetUid);
6779            if (perms != null) {
6780                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6781                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6782
6783                perms.remove(perm.uri);
6784                if (perms.isEmpty()) {
6785                    mGrantedUriPermissions.remove(perm.targetUid);
6786                }
6787            }
6788        }
6789    }
6790
6791    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6792        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6793
6794        final IPackageManager pm = AppGlobals.getPackageManager();
6795        final String authority = grantUri.uri.getAuthority();
6796        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6797        if (pi == null) {
6798            Slog.w(TAG, "No content provider found for permission revoke: "
6799                    + grantUri.toSafeString());
6800            return;
6801        }
6802
6803        // Does the caller have this permission on the URI?
6804        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6805            // Right now, if you are not the original owner of the permission,
6806            // you are not allowed to revoke it.
6807            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6808                throw new SecurityException("Uid " + callingUid
6809                        + " does not have permission to uri " + grantUri);
6810            //}
6811        }
6812
6813        boolean persistChanged = false;
6814
6815        // Go through all of the permissions and remove any that match.
6816        int N = mGrantedUriPermissions.size();
6817        for (int i = 0; i < N; i++) {
6818            final int targetUid = mGrantedUriPermissions.keyAt(i);
6819            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6820
6821            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6822                final UriPermission perm = it.next();
6823                if (perm.uri.sourceUserId == grantUri.sourceUserId
6824                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6825                    if (DEBUG_URI_PERMISSION)
6826                        Slog.v(TAG,
6827                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6828                    persistChanged |= perm.revokeModes(
6829                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6830                    if (perm.modeFlags == 0) {
6831                        it.remove();
6832                    }
6833                }
6834            }
6835
6836            if (perms.isEmpty()) {
6837                mGrantedUriPermissions.remove(targetUid);
6838                N--;
6839                i--;
6840            }
6841        }
6842
6843        if (persistChanged) {
6844            schedulePersistUriGrants();
6845        }
6846    }
6847
6848    @Override
6849    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6850            int userId) {
6851        enforceNotIsolatedCaller("revokeUriPermission");
6852        synchronized(this) {
6853            final ProcessRecord r = getRecordForAppLocked(caller);
6854            if (r == null) {
6855                throw new SecurityException("Unable to find app for caller "
6856                        + caller
6857                        + " when revoking permission to uri " + uri);
6858            }
6859            if (uri == null) {
6860                Slog.w(TAG, "revokeUriPermission: null uri");
6861                return;
6862            }
6863
6864            if (!Intent.isAccessUriMode(modeFlags)) {
6865                return;
6866            }
6867
6868            final IPackageManager pm = AppGlobals.getPackageManager();
6869            final String authority = uri.getAuthority();
6870            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6871            if (pi == null) {
6872                Slog.w(TAG, "No content provider found for permission revoke: "
6873                        + uri.toSafeString());
6874                return;
6875            }
6876
6877            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6878        }
6879    }
6880
6881    /**
6882     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6883     * given package.
6884     *
6885     * @param packageName Package name to match, or {@code null} to apply to all
6886     *            packages.
6887     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6888     *            to all users.
6889     * @param persistable If persistable grants should be removed.
6890     */
6891    private void removeUriPermissionsForPackageLocked(
6892            String packageName, int userHandle, boolean persistable) {
6893        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6894            throw new IllegalArgumentException("Must narrow by either package or user");
6895        }
6896
6897        boolean persistChanged = false;
6898
6899        int N = mGrantedUriPermissions.size();
6900        for (int i = 0; i < N; i++) {
6901            final int targetUid = mGrantedUriPermissions.keyAt(i);
6902            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6903
6904            // Only inspect grants matching user
6905            if (userHandle == UserHandle.USER_ALL
6906                    || userHandle == UserHandle.getUserId(targetUid)) {
6907                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6908                    final UriPermission perm = it.next();
6909
6910                    // Only inspect grants matching package
6911                    if (packageName == null || perm.sourcePkg.equals(packageName)
6912                            || perm.targetPkg.equals(packageName)) {
6913                        persistChanged |= perm.revokeModes(
6914                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6915
6916                        // Only remove when no modes remain; any persisted grants
6917                        // will keep this alive.
6918                        if (perm.modeFlags == 0) {
6919                            it.remove();
6920                        }
6921                    }
6922                }
6923
6924                if (perms.isEmpty()) {
6925                    mGrantedUriPermissions.remove(targetUid);
6926                    N--;
6927                    i--;
6928                }
6929            }
6930        }
6931
6932        if (persistChanged) {
6933            schedulePersistUriGrants();
6934        }
6935    }
6936
6937    @Override
6938    public IBinder newUriPermissionOwner(String name) {
6939        enforceNotIsolatedCaller("newUriPermissionOwner");
6940        synchronized(this) {
6941            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6942            return owner.getExternalTokenLocked();
6943        }
6944    }
6945
6946    @Override
6947    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6948            final int modeFlags, int sourceUserId, int targetUserId) {
6949        synchronized(this) {
6950            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6951            if (owner == null) {
6952                throw new IllegalArgumentException("Unknown owner: " + token);
6953            }
6954            if (fromUid != Binder.getCallingUid()) {
6955                if (Binder.getCallingUid() != Process.myUid()) {
6956                    // Only system code can grant URI permissions on behalf
6957                    // of other users.
6958                    throw new SecurityException("nice try");
6959                }
6960            }
6961            if (targetPkg == null) {
6962                throw new IllegalArgumentException("null target");
6963            }
6964            if (uri == null) {
6965                throw new IllegalArgumentException("null uri");
6966            }
6967
6968            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6969                    modeFlags, owner, targetUserId);
6970        }
6971    }
6972
6973    @Override
6974    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6975        synchronized(this) {
6976            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6977            if (owner == null) {
6978                throw new IllegalArgumentException("Unknown owner: " + token);
6979            }
6980
6981            if (uri == null) {
6982                owner.removeUriPermissionsLocked(mode);
6983            } else {
6984                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6985            }
6986        }
6987    }
6988
6989    private void schedulePersistUriGrants() {
6990        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6991            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6992                    10 * DateUtils.SECOND_IN_MILLIS);
6993        }
6994    }
6995
6996    private void writeGrantedUriPermissions() {
6997        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6998
6999        // Snapshot permissions so we can persist without lock
7000        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7001        synchronized (this) {
7002            final int size = mGrantedUriPermissions.size();
7003            for (int i = 0; i < size; i++) {
7004                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7005                for (UriPermission perm : perms.values()) {
7006                    if (perm.persistedModeFlags != 0) {
7007                        persist.add(perm.snapshot());
7008                    }
7009                }
7010            }
7011        }
7012
7013        FileOutputStream fos = null;
7014        try {
7015            fos = mGrantFile.startWrite();
7016
7017            XmlSerializer out = new FastXmlSerializer();
7018            out.setOutput(fos, "utf-8");
7019            out.startDocument(null, true);
7020            out.startTag(null, TAG_URI_GRANTS);
7021            for (UriPermission.Snapshot perm : persist) {
7022                out.startTag(null, TAG_URI_GRANT);
7023                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7024                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7025                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7026                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7027                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7028                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7029                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7030                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7031                out.endTag(null, TAG_URI_GRANT);
7032            }
7033            out.endTag(null, TAG_URI_GRANTS);
7034            out.endDocument();
7035
7036            mGrantFile.finishWrite(fos);
7037        } catch (IOException e) {
7038            if (fos != null) {
7039                mGrantFile.failWrite(fos);
7040            }
7041        }
7042    }
7043
7044    private void readGrantedUriPermissionsLocked() {
7045        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7046
7047        final long now = System.currentTimeMillis();
7048
7049        FileInputStream fis = null;
7050        try {
7051            fis = mGrantFile.openRead();
7052            final XmlPullParser in = Xml.newPullParser();
7053            in.setInput(fis, null);
7054
7055            int type;
7056            while ((type = in.next()) != END_DOCUMENT) {
7057                final String tag = in.getName();
7058                if (type == START_TAG) {
7059                    if (TAG_URI_GRANT.equals(tag)) {
7060                        final int sourceUserId;
7061                        final int targetUserId;
7062                        final int userHandle = readIntAttribute(in,
7063                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7064                        if (userHandle != UserHandle.USER_NULL) {
7065                            // For backwards compatibility.
7066                            sourceUserId = userHandle;
7067                            targetUserId = userHandle;
7068                        } else {
7069                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7070                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7071                        }
7072                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7073                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7074                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7075                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7076                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7077                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7078
7079                        // Sanity check that provider still belongs to source package
7080                        final ProviderInfo pi = getProviderInfoLocked(
7081                                uri.getAuthority(), sourceUserId);
7082                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7083                            int targetUid = -1;
7084                            try {
7085                                targetUid = AppGlobals.getPackageManager()
7086                                        .getPackageUid(targetPkg, targetUserId);
7087                            } catch (RemoteException e) {
7088                            }
7089                            if (targetUid != -1) {
7090                                final UriPermission perm = findOrCreateUriPermissionLocked(
7091                                        sourcePkg, targetPkg, targetUid,
7092                                        new GrantUri(sourceUserId, uri, prefix));
7093                                perm.initPersistedModes(modeFlags, createdTime);
7094                            }
7095                        } else {
7096                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7097                                    + " but instead found " + pi);
7098                        }
7099                    }
7100                }
7101            }
7102        } catch (FileNotFoundException e) {
7103            // Missing grants is okay
7104        } catch (IOException e) {
7105            Log.wtf(TAG, "Failed reading Uri grants", e);
7106        } catch (XmlPullParserException e) {
7107            Log.wtf(TAG, "Failed reading Uri grants", e);
7108        } finally {
7109            IoUtils.closeQuietly(fis);
7110        }
7111    }
7112
7113    @Override
7114    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7115        enforceNotIsolatedCaller("takePersistableUriPermission");
7116
7117        Preconditions.checkFlagsArgument(modeFlags,
7118                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7119
7120        synchronized (this) {
7121            final int callingUid = Binder.getCallingUid();
7122            boolean persistChanged = false;
7123            GrantUri grantUri = new GrantUri(userId, uri, false);
7124
7125            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7126                    new GrantUri(userId, uri, false));
7127            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7128                    new GrantUri(userId, uri, true));
7129
7130            final boolean exactValid = (exactPerm != null)
7131                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7132            final boolean prefixValid = (prefixPerm != null)
7133                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7134
7135            if (!(exactValid || prefixValid)) {
7136                throw new SecurityException("No persistable permission grants found for UID "
7137                        + callingUid + " and Uri " + grantUri.toSafeString());
7138            }
7139
7140            if (exactValid) {
7141                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7142            }
7143            if (prefixValid) {
7144                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7145            }
7146
7147            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7148
7149            if (persistChanged) {
7150                schedulePersistUriGrants();
7151            }
7152        }
7153    }
7154
7155    @Override
7156    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7157        enforceNotIsolatedCaller("releasePersistableUriPermission");
7158
7159        Preconditions.checkFlagsArgument(modeFlags,
7160                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7161
7162        synchronized (this) {
7163            final int callingUid = Binder.getCallingUid();
7164            boolean persistChanged = false;
7165
7166            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7167                    new GrantUri(userId, uri, false));
7168            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7169                    new GrantUri(userId, uri, true));
7170            if (exactPerm == null && prefixPerm == null) {
7171                throw new SecurityException("No permission grants found for UID " + callingUid
7172                        + " and Uri " + uri.toSafeString());
7173            }
7174
7175            if (exactPerm != null) {
7176                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7177                removeUriPermissionIfNeededLocked(exactPerm);
7178            }
7179            if (prefixPerm != null) {
7180                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7181                removeUriPermissionIfNeededLocked(prefixPerm);
7182            }
7183
7184            if (persistChanged) {
7185                schedulePersistUriGrants();
7186            }
7187        }
7188    }
7189
7190    /**
7191     * Prune any older {@link UriPermission} for the given UID until outstanding
7192     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7193     *
7194     * @return if any mutations occured that require persisting.
7195     */
7196    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7197        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7198        if (perms == null) return false;
7199        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7200
7201        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7202        for (UriPermission perm : perms.values()) {
7203            if (perm.persistedModeFlags != 0) {
7204                persisted.add(perm);
7205            }
7206        }
7207
7208        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7209        if (trimCount <= 0) return false;
7210
7211        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7212        for (int i = 0; i < trimCount; i++) {
7213            final UriPermission perm = persisted.get(i);
7214
7215            if (DEBUG_URI_PERMISSION) {
7216                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7217            }
7218
7219            perm.releasePersistableModes(~0);
7220            removeUriPermissionIfNeededLocked(perm);
7221        }
7222
7223        return true;
7224    }
7225
7226    @Override
7227    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7228            String packageName, boolean incoming) {
7229        enforceNotIsolatedCaller("getPersistedUriPermissions");
7230        Preconditions.checkNotNull(packageName, "packageName");
7231
7232        final int callingUid = Binder.getCallingUid();
7233        final IPackageManager pm = AppGlobals.getPackageManager();
7234        try {
7235            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7236            if (packageUid != callingUid) {
7237                throw new SecurityException(
7238                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7239            }
7240        } catch (RemoteException e) {
7241            throw new SecurityException("Failed to verify package name ownership");
7242        }
7243
7244        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7245        synchronized (this) {
7246            if (incoming) {
7247                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7248                        callingUid);
7249                if (perms == null) {
7250                    Slog.w(TAG, "No permission grants found for " + packageName);
7251                } else {
7252                    for (UriPermission perm : perms.values()) {
7253                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7254                            result.add(perm.buildPersistedPublicApiObject());
7255                        }
7256                    }
7257                }
7258            } else {
7259                final int size = mGrantedUriPermissions.size();
7260                for (int i = 0; i < size; i++) {
7261                    final ArrayMap<GrantUri, UriPermission> perms =
7262                            mGrantedUriPermissions.valueAt(i);
7263                    for (UriPermission perm : perms.values()) {
7264                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7265                            result.add(perm.buildPersistedPublicApiObject());
7266                        }
7267                    }
7268                }
7269            }
7270        }
7271        return new ParceledListSlice<android.content.UriPermission>(result);
7272    }
7273
7274    @Override
7275    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7276        synchronized (this) {
7277            ProcessRecord app =
7278                who != null ? getRecordForAppLocked(who) : null;
7279            if (app == null) return;
7280
7281            Message msg = Message.obtain();
7282            msg.what = WAIT_FOR_DEBUGGER_MSG;
7283            msg.obj = app;
7284            msg.arg1 = waiting ? 1 : 0;
7285            mHandler.sendMessage(msg);
7286        }
7287    }
7288
7289    @Override
7290    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7291        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7292        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7293        outInfo.availMem = Process.getFreeMemory();
7294        outInfo.totalMem = Process.getTotalMemory();
7295        outInfo.threshold = homeAppMem;
7296        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7297        outInfo.hiddenAppThreshold = cachedAppMem;
7298        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7299                ProcessList.SERVICE_ADJ);
7300        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7301                ProcessList.VISIBLE_APP_ADJ);
7302        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7303                ProcessList.FOREGROUND_APP_ADJ);
7304    }
7305
7306    // =========================================================
7307    // TASK MANAGEMENT
7308    // =========================================================
7309
7310    @Override
7311    public List<IAppTask> getAppTasks() {
7312        final PackageManager pm = mContext.getPackageManager();
7313        int callingUid = Binder.getCallingUid();
7314        long ident = Binder.clearCallingIdentity();
7315
7316        // Compose the list of packages for this id to test against
7317        HashSet<String> packages = new HashSet<String>();
7318        String[] uidPackages = pm.getPackagesForUid(callingUid);
7319        for (int i = 0; i < uidPackages.length; i++) {
7320            packages.add(uidPackages[i]);
7321        }
7322
7323        synchronized(this) {
7324            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7325            try {
7326                if (localLOGV) Slog.v(TAG, "getAppTasks");
7327
7328                final int N = mRecentTasks.size();
7329                for (int i = 0; i < N; i++) {
7330                    TaskRecord tr = mRecentTasks.get(i);
7331                    // Skip tasks that are not created by the caller
7332                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7333                        ActivityManager.RecentTaskInfo taskInfo =
7334                                createRecentTaskInfoFromTaskRecord(tr);
7335                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7336                        list.add(taskImpl);
7337                    }
7338                }
7339            } finally {
7340                Binder.restoreCallingIdentity(ident);
7341            }
7342            return list;
7343        }
7344    }
7345
7346    @Override
7347    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7348        final int callingUid = Binder.getCallingUid();
7349        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7350
7351        synchronized(this) {
7352            if (localLOGV) Slog.v(
7353                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7354
7355            final boolean allowed = checkCallingPermission(
7356                    android.Manifest.permission.GET_TASKS)
7357                    == PackageManager.PERMISSION_GRANTED;
7358            if (!allowed) {
7359                Slog.w(TAG, "getTasks: caller " + callingUid
7360                        + " does not hold GET_TASKS; limiting output");
7361            }
7362
7363            // TODO: Improve with MRU list from all ActivityStacks.
7364            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7365        }
7366
7367        return list;
7368    }
7369
7370    TaskRecord getMostRecentTask() {
7371        return mRecentTasks.get(0);
7372    }
7373
7374    /**
7375     * Creates a new RecentTaskInfo from a TaskRecord.
7376     */
7377    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7378        // Update the task description to reflect any changes in the task stack
7379        tr.updateTaskDescription();
7380
7381        // Compose the recent task info
7382        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7383        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7384        rti.persistentId = tr.taskId;
7385        rti.baseIntent = new Intent(tr.getBaseIntent());
7386        rti.origActivity = tr.origActivity;
7387        rti.description = tr.lastDescription;
7388        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7389        rti.userId = tr.userId;
7390        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7391        rti.firstActiveTime = tr.firstActiveTime;
7392        rti.lastActiveTime = tr.lastActiveTime;
7393        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7394        return rti;
7395    }
7396
7397    @Override
7398    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7399        final int callingUid = Binder.getCallingUid();
7400        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7401                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7402
7403        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7404        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7405        synchronized (this) {
7406            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7407                    == PackageManager.PERMISSION_GRANTED;
7408            if (!allowed) {
7409                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7410                        + " does not hold GET_TASKS; limiting output");
7411            }
7412            final boolean detailed = checkCallingPermission(
7413                    android.Manifest.permission.GET_DETAILED_TASKS)
7414                    == PackageManager.PERMISSION_GRANTED;
7415
7416            IPackageManager pm = AppGlobals.getPackageManager();
7417
7418            final int N = mRecentTasks.size();
7419            ArrayList<ActivityManager.RecentTaskInfo> res
7420                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7421                            maxNum < N ? maxNum : N);
7422
7423            final Set<Integer> includedUsers;
7424            if (includeProfiles) {
7425                includedUsers = getProfileIdsLocked(userId);
7426            } else {
7427                includedUsers = new HashSet<Integer>();
7428            }
7429            includedUsers.add(Integer.valueOf(userId));
7430
7431            // Regroup affiliated tasks together.
7432            for (int i = 0; i < N; ) {
7433                TaskRecord task = mRecentTasks.remove(i);
7434                if (mTmpRecents.contains(task)) {
7435                    continue;
7436                }
7437                int affiliatedTaskId = task.mAffiliatedTaskId;
7438                while (true) {
7439                    TaskRecord next = task.mNextAffiliate;
7440                    if (next == null) {
7441                        break;
7442                    }
7443                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7444                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7445                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7446                        task.setNextAffiliate(null);
7447                        if (next.mPrevAffiliate == task) {
7448                            next.setPrevAffiliate(null);
7449                        }
7450                        break;
7451                    }
7452                    if (next.mPrevAffiliate != task) {
7453                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7454                                next.mPrevAffiliate + " task=" + task);
7455                        next.setPrevAffiliate(null);
7456                        break;
7457                    }
7458                    if (!mRecentTasks.contains(next)) {
7459                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7460                        task.setNextAffiliate(null);
7461                        if (next.mPrevAffiliate == task) {
7462                            next.setPrevAffiliate(null);
7463                        }
7464                        break;
7465                    }
7466                    task = next;
7467                }
7468                // task is now the end of the list
7469                do {
7470                    mRecentTasks.remove(task);
7471                    mRecentTasks.add(i++, task);
7472                    mTmpRecents.add(task);
7473                } while ((task = task.mPrevAffiliate) != null);
7474            }
7475            mTmpRecents.clear();
7476            // mRecentTasks is now in sorted, affiliated order.
7477
7478            for (int i=0; i<N && maxNum > 0; i++) {
7479                TaskRecord tr = mRecentTasks.get(i);
7480                // Only add calling user or related users recent tasks
7481                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7482
7483                // Return the entry if desired by the caller.  We always return
7484                // the first entry, because callers always expect this to be the
7485                // foreground app.  We may filter others if the caller has
7486                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7487                // we should exclude the entry.
7488
7489                if (i == 0
7490                        || withExcluded
7491                        || (tr.intent == null)
7492                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7493                                == 0)) {
7494                    if (!allowed) {
7495                        // If the caller doesn't have the GET_TASKS permission, then only
7496                        // allow them to see a small subset of tasks -- their own and home.
7497                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7498                            continue;
7499                        }
7500                    }
7501                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7502                        // Don't include auto remove tasks that are finished or finishing.
7503                        continue;
7504                    }
7505
7506                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7507                    if (!detailed) {
7508                        rti.baseIntent.replaceExtras((Bundle)null);
7509                    }
7510
7511                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7512                        // Check whether this activity is currently available.
7513                        try {
7514                            if (rti.origActivity != null) {
7515                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7516                                        == null) {
7517                                    continue;
7518                                }
7519                            } else if (rti.baseIntent != null) {
7520                                if (pm.queryIntentActivities(rti.baseIntent,
7521                                        null, 0, userId) == null) {
7522                                    continue;
7523                                }
7524                            }
7525                        } catch (RemoteException e) {
7526                            // Will never happen.
7527                        }
7528                    }
7529
7530                    res.add(rti);
7531                    maxNum--;
7532                }
7533            }
7534            return res;
7535        }
7536    }
7537
7538    private TaskRecord recentTaskForIdLocked(int id) {
7539        final int N = mRecentTasks.size();
7540            for (int i=0; i<N; i++) {
7541                TaskRecord tr = mRecentTasks.get(i);
7542                if (tr.taskId == id) {
7543                    return tr;
7544                }
7545            }
7546            return null;
7547    }
7548
7549    @Override
7550    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7551        synchronized (this) {
7552            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7553                    "getTaskThumbnail()");
7554            TaskRecord tr = recentTaskForIdLocked(id);
7555            if (tr != null) {
7556                return tr.getTaskThumbnailLocked();
7557            }
7558        }
7559        return null;
7560    }
7561
7562    @Override
7563    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7564        synchronized (this) {
7565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7566            if (r != null) {
7567                r.taskDescription = td;
7568                r.task.updateTaskDescription();
7569            }
7570        }
7571    }
7572
7573    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7574        if (!pr.killedByAm) {
7575            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7576            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7577                    pr.processName, pr.setAdj, reason);
7578            pr.killedByAm = true;
7579            Process.killProcessQuiet(pr.pid);
7580            Process.killProcessGroup(pr.info.uid, pr.pid);
7581        }
7582    }
7583
7584    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7585        tr.disposeThumbnail();
7586        mRecentTasks.remove(tr);
7587        tr.closeRecentsChain();
7588        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7589        Intent baseIntent = new Intent(
7590                tr.intent != null ? tr.intent : tr.affinityIntent);
7591        ComponentName component = baseIntent.getComponent();
7592        if (component == null) {
7593            Slog.w(TAG, "Now component for base intent of task: " + tr);
7594            return;
7595        }
7596
7597        // Find any running services associated with this app.
7598        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7599
7600        if (killProcesses) {
7601            // Find any running processes associated with this app.
7602            final String pkg = component.getPackageName();
7603            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7604            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7605            for (int i=0; i<pmap.size(); i++) {
7606                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7607                for (int j=0; j<uids.size(); j++) {
7608                    ProcessRecord proc = uids.valueAt(j);
7609                    if (proc.userId != tr.userId) {
7610                        continue;
7611                    }
7612                    if (!proc.pkgList.containsKey(pkg)) {
7613                        continue;
7614                    }
7615                    procs.add(proc);
7616                }
7617            }
7618
7619            // Kill the running processes.
7620            for (int i=0; i<procs.size(); i++) {
7621                ProcessRecord pr = procs.get(i);
7622                if (pr == mHomeProcess) {
7623                    // Don't kill the home process along with tasks from the same package.
7624                    continue;
7625                }
7626                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7627                    killUnneededProcessLocked(pr, "remove task");
7628                } else {
7629                    pr.waitingToKill = "remove task";
7630                }
7631            }
7632        }
7633    }
7634
7635    /**
7636     * Removes the task with the specified task id.
7637     *
7638     * @param taskId Identifier of the task to be removed.
7639     * @param flags Additional operational flags.  May be 0 or
7640     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7641     * @return Returns true if the given task was found and removed.
7642     */
7643    private boolean removeTaskByIdLocked(int taskId, int flags) {
7644        TaskRecord tr = recentTaskForIdLocked(taskId);
7645        if (tr != null) {
7646            tr.removeTaskActivitiesLocked();
7647            cleanUpRemovedTaskLocked(tr, flags);
7648            if (tr.isPersistable) {
7649                notifyTaskPersisterLocked(tr, true);
7650            }
7651            return true;
7652        }
7653        return false;
7654    }
7655
7656    @Override
7657    public boolean removeTask(int taskId, int flags) {
7658        synchronized (this) {
7659            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7660                    "removeTask()");
7661            long ident = Binder.clearCallingIdentity();
7662            try {
7663                return removeTaskByIdLocked(taskId, flags);
7664            } finally {
7665                Binder.restoreCallingIdentity(ident);
7666            }
7667        }
7668    }
7669
7670    /**
7671     * TODO: Add mController hook
7672     */
7673    @Override
7674    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7675        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7676                "moveTaskToFront()");
7677
7678        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7679        synchronized(this) {
7680            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7681                    Binder.getCallingUid(), "Task to front")) {
7682                ActivityOptions.abort(options);
7683                return;
7684            }
7685            final long origId = Binder.clearCallingIdentity();
7686            try {
7687                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7688                if (task == null) {
7689                    return;
7690                }
7691                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7692                    mStackSupervisor.showLockTaskToast();
7693                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7694                    return;
7695                }
7696                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7697                if (prev != null && prev.isRecentsActivity()) {
7698                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7699                }
7700                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7701            } finally {
7702                Binder.restoreCallingIdentity(origId);
7703            }
7704            ActivityOptions.abort(options);
7705        }
7706    }
7707
7708    @Override
7709    public void moveTaskToBack(int taskId) {
7710        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7711                "moveTaskToBack()");
7712
7713        synchronized(this) {
7714            TaskRecord tr = recentTaskForIdLocked(taskId);
7715            if (tr != null) {
7716                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7717                ActivityStack stack = tr.stack;
7718                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7719                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7720                            Binder.getCallingUid(), "Task to back")) {
7721                        return;
7722                    }
7723                }
7724                final long origId = Binder.clearCallingIdentity();
7725                try {
7726                    stack.moveTaskToBackLocked(taskId, null);
7727                } finally {
7728                    Binder.restoreCallingIdentity(origId);
7729                }
7730            }
7731        }
7732    }
7733
7734    /**
7735     * Moves an activity, and all of the other activities within the same task, to the bottom
7736     * of the history stack.  The activity's order within the task is unchanged.
7737     *
7738     * @param token A reference to the activity we wish to move
7739     * @param nonRoot If false then this only works if the activity is the root
7740     *                of a task; if true it will work for any activity in a task.
7741     * @return Returns true if the move completed, false if not.
7742     */
7743    @Override
7744    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7745        enforceNotIsolatedCaller("moveActivityTaskToBack");
7746        synchronized(this) {
7747            final long origId = Binder.clearCallingIdentity();
7748            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7749            if (taskId >= 0) {
7750                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7751            }
7752            Binder.restoreCallingIdentity(origId);
7753        }
7754        return false;
7755    }
7756
7757    @Override
7758    public void moveTaskBackwards(int task) {
7759        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7760                "moveTaskBackwards()");
7761
7762        synchronized(this) {
7763            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7764                    Binder.getCallingUid(), "Task backwards")) {
7765                return;
7766            }
7767            final long origId = Binder.clearCallingIdentity();
7768            moveTaskBackwardsLocked(task);
7769            Binder.restoreCallingIdentity(origId);
7770        }
7771    }
7772
7773    private final void moveTaskBackwardsLocked(int task) {
7774        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7775    }
7776
7777    @Override
7778    public IBinder getHomeActivityToken() throws RemoteException {
7779        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7780                "getHomeActivityToken()");
7781        synchronized (this) {
7782            return mStackSupervisor.getHomeActivityToken();
7783        }
7784    }
7785
7786    @Override
7787    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7788            IActivityContainerCallback callback) throws RemoteException {
7789        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7790                "createActivityContainer()");
7791        synchronized (this) {
7792            if (parentActivityToken == null) {
7793                throw new IllegalArgumentException("parent token must not be null");
7794            }
7795            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7796            if (r == null) {
7797                return null;
7798            }
7799            if (callback == null) {
7800                throw new IllegalArgumentException("callback must not be null");
7801            }
7802            return mStackSupervisor.createActivityContainer(r, callback);
7803        }
7804    }
7805
7806    @Override
7807    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7808        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7809                "deleteActivityContainer()");
7810        synchronized (this) {
7811            mStackSupervisor.deleteActivityContainer(container);
7812        }
7813    }
7814
7815    @Override
7816    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7817            throws RemoteException {
7818        synchronized (this) {
7819            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7820            if (stack != null) {
7821                return stack.mActivityContainer;
7822            }
7823            return null;
7824        }
7825    }
7826
7827    @Override
7828    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7829        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7830                "moveTaskToStack()");
7831        if (stackId == HOME_STACK_ID) {
7832            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7833                    new RuntimeException("here").fillInStackTrace());
7834        }
7835        synchronized (this) {
7836            long ident = Binder.clearCallingIdentity();
7837            try {
7838                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7839                        + stackId + " toTop=" + toTop);
7840                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7841            } finally {
7842                Binder.restoreCallingIdentity(ident);
7843            }
7844        }
7845    }
7846
7847    @Override
7848    public void resizeStack(int stackBoxId, Rect bounds) {
7849        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7850                "resizeStackBox()");
7851        long ident = Binder.clearCallingIdentity();
7852        try {
7853            mWindowManager.resizeStack(stackBoxId, bounds);
7854        } finally {
7855            Binder.restoreCallingIdentity(ident);
7856        }
7857    }
7858
7859    @Override
7860    public List<StackInfo> getAllStackInfos() {
7861        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7862                "getAllStackInfos()");
7863        long ident = Binder.clearCallingIdentity();
7864        try {
7865            synchronized (this) {
7866                return mStackSupervisor.getAllStackInfosLocked();
7867            }
7868        } finally {
7869            Binder.restoreCallingIdentity(ident);
7870        }
7871    }
7872
7873    @Override
7874    public StackInfo getStackInfo(int stackId) {
7875        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7876                "getStackInfo()");
7877        long ident = Binder.clearCallingIdentity();
7878        try {
7879            synchronized (this) {
7880                return mStackSupervisor.getStackInfoLocked(stackId);
7881            }
7882        } finally {
7883            Binder.restoreCallingIdentity(ident);
7884        }
7885    }
7886
7887    @Override
7888    public boolean isInHomeStack(int taskId) {
7889        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7890                "getStackInfo()");
7891        long ident = Binder.clearCallingIdentity();
7892        try {
7893            synchronized (this) {
7894                TaskRecord tr = recentTaskForIdLocked(taskId);
7895                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7896            }
7897        } finally {
7898            Binder.restoreCallingIdentity(ident);
7899        }
7900    }
7901
7902    @Override
7903    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7904        synchronized(this) {
7905            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7906        }
7907    }
7908
7909    private boolean isLockTaskAuthorized(String pkg) {
7910        final DevicePolicyManager dpm = (DevicePolicyManager)
7911                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7912        try {
7913            int uid = mContext.getPackageManager().getPackageUid(pkg,
7914                    Binder.getCallingUserHandle().getIdentifier());
7915            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7916        } catch (NameNotFoundException e) {
7917            return false;
7918        }
7919    }
7920
7921    void startLockTaskMode(TaskRecord task) {
7922        final String pkg;
7923        synchronized (this) {
7924            pkg = task.intent.getComponent().getPackageName();
7925        }
7926        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7927        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7928            final TaskRecord taskRecord = task;
7929            mHandler.post(new Runnable() {
7930                @Override
7931                public void run() {
7932                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7933                }
7934            });
7935            return;
7936        }
7937        long ident = Binder.clearCallingIdentity();
7938        try {
7939            synchronized (this) {
7940                // Since we lost lock on task, make sure it is still there.
7941                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7942                if (task != null) {
7943                    if (!isSystemInitiated
7944                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7945                        throw new IllegalArgumentException("Invalid task, not in foreground");
7946                    }
7947                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7948                }
7949            }
7950        } finally {
7951            Binder.restoreCallingIdentity(ident);
7952        }
7953    }
7954
7955    @Override
7956    public void startLockTaskMode(int taskId) {
7957        final TaskRecord task;
7958        long ident = Binder.clearCallingIdentity();
7959        try {
7960            synchronized (this) {
7961                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7962            }
7963        } finally {
7964            Binder.restoreCallingIdentity(ident);
7965        }
7966        if (task != null) {
7967            startLockTaskMode(task);
7968        }
7969    }
7970
7971    @Override
7972    public void startLockTaskMode(IBinder token) {
7973        final TaskRecord task;
7974        long ident = Binder.clearCallingIdentity();
7975        try {
7976            synchronized (this) {
7977                final ActivityRecord r = ActivityRecord.forToken(token);
7978                if (r == null) {
7979                    return;
7980                }
7981                task = r.task;
7982            }
7983        } finally {
7984            Binder.restoreCallingIdentity(ident);
7985        }
7986        if (task != null) {
7987            startLockTaskMode(task);
7988        }
7989    }
7990
7991    @Override
7992    public void startLockTaskModeOnCurrent() throws RemoteException {
7993        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7994        ActivityRecord r = null;
7995        synchronized (this) {
7996            r = mStackSupervisor.topRunningActivityLocked();
7997        }
7998        startLockTaskMode(r.task);
7999    }
8000
8001    @Override
8002    public void stopLockTaskMode() {
8003        // Verify that the user matches the package of the intent for the TaskRecord
8004        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8005        // and stopLockTaskMode.
8006        final int callingUid = Binder.getCallingUid();
8007        if (callingUid != Process.SYSTEM_UID) {
8008            try {
8009                String pkg =
8010                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8011                int uid = mContext.getPackageManager().getPackageUid(pkg,
8012                        Binder.getCallingUserHandle().getIdentifier());
8013                if (uid != callingUid) {
8014                    throw new SecurityException("Invalid uid, expected " + uid);
8015                }
8016            } catch (NameNotFoundException e) {
8017                Log.d(TAG, "stopLockTaskMode " + e);
8018                return;
8019            }
8020        }
8021        long ident = Binder.clearCallingIdentity();
8022        try {
8023            Log.d(TAG, "stopLockTaskMode");
8024            // Stop lock task
8025            synchronized (this) {
8026                mStackSupervisor.setLockTaskModeLocked(null, false);
8027            }
8028        } finally {
8029            Binder.restoreCallingIdentity(ident);
8030        }
8031    }
8032
8033    @Override
8034    public void stopLockTaskModeOnCurrent() throws RemoteException {
8035        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8036        long ident = Binder.clearCallingIdentity();
8037        try {
8038            stopLockTaskMode();
8039        } finally {
8040            Binder.restoreCallingIdentity(ident);
8041        }
8042    }
8043
8044    @Override
8045    public boolean isInLockTaskMode() {
8046        synchronized (this) {
8047            return mStackSupervisor.isInLockTaskMode();
8048        }
8049    }
8050
8051    // =========================================================
8052    // CONTENT PROVIDERS
8053    // =========================================================
8054
8055    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8056        List<ProviderInfo> providers = null;
8057        try {
8058            providers = AppGlobals.getPackageManager().
8059                queryContentProviders(app.processName, app.uid,
8060                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8061        } catch (RemoteException ex) {
8062        }
8063        if (DEBUG_MU)
8064            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8065        int userId = app.userId;
8066        if (providers != null) {
8067            int N = providers.size();
8068            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8069            for (int i=0; i<N; i++) {
8070                ProviderInfo cpi =
8071                    (ProviderInfo)providers.get(i);
8072                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8073                        cpi.name, cpi.flags);
8074                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8075                    // This is a singleton provider, but a user besides the
8076                    // default user is asking to initialize a process it runs
8077                    // in...  well, no, it doesn't actually run in this process,
8078                    // it runs in the process of the default user.  Get rid of it.
8079                    providers.remove(i);
8080                    N--;
8081                    i--;
8082                    continue;
8083                }
8084
8085                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8086                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8087                if (cpr == null) {
8088                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8089                    mProviderMap.putProviderByClass(comp, cpr);
8090                }
8091                if (DEBUG_MU)
8092                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8093                app.pubProviders.put(cpi.name, cpr);
8094                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8095                    // Don't add this if it is a platform component that is marked
8096                    // to run in multiple processes, because this is actually
8097                    // part of the framework so doesn't make sense to track as a
8098                    // separate apk in the process.
8099                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8100                            mProcessStats);
8101                }
8102                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8103            }
8104        }
8105        return providers;
8106    }
8107
8108    /**
8109     * Check if {@link ProcessRecord} has a possible chance at accessing the
8110     * given {@link ProviderInfo}. Final permission checking is always done
8111     * in {@link ContentProvider}.
8112     */
8113    private final String checkContentProviderPermissionLocked(
8114            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8115        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8116        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8117        boolean checkedGrants = false;
8118        if (checkUser) {
8119            // Looking for cross-user grants before enforcing the typical cross-users permissions
8120            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8121            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8122                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8123                    return null;
8124                }
8125                checkedGrants = true;
8126            }
8127            userId = handleIncomingUser(callingPid, callingUid, userId,
8128                    false, ALLOW_NON_FULL,
8129                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8130            if (userId != tmpTargetUserId) {
8131                // When we actually went to determine the final targer user ID, this ended
8132                // up different than our initial check for the authority.  This is because
8133                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8134                // SELF.  So we need to re-check the grants again.
8135                checkedGrants = false;
8136            }
8137        }
8138        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8139                cpi.applicationInfo.uid, cpi.exported)
8140                == PackageManager.PERMISSION_GRANTED) {
8141            return null;
8142        }
8143        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8144                cpi.applicationInfo.uid, cpi.exported)
8145                == PackageManager.PERMISSION_GRANTED) {
8146            return null;
8147        }
8148
8149        PathPermission[] pps = cpi.pathPermissions;
8150        if (pps != null) {
8151            int i = pps.length;
8152            while (i > 0) {
8153                i--;
8154                PathPermission pp = pps[i];
8155                String pprperm = pp.getReadPermission();
8156                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8157                        cpi.applicationInfo.uid, cpi.exported)
8158                        == PackageManager.PERMISSION_GRANTED) {
8159                    return null;
8160                }
8161                String ppwperm = pp.getWritePermission();
8162                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8163                        cpi.applicationInfo.uid, cpi.exported)
8164                        == PackageManager.PERMISSION_GRANTED) {
8165                    return null;
8166                }
8167            }
8168        }
8169        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8170            return null;
8171        }
8172
8173        String msg;
8174        if (!cpi.exported) {
8175            msg = "Permission Denial: opening provider " + cpi.name
8176                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8177                    + ", uid=" + callingUid + ") that is not exported from uid "
8178                    + cpi.applicationInfo.uid;
8179        } else {
8180            msg = "Permission Denial: opening provider " + cpi.name
8181                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8182                    + ", uid=" + callingUid + ") requires "
8183                    + cpi.readPermission + " or " + cpi.writePermission;
8184        }
8185        Slog.w(TAG, msg);
8186        return msg;
8187    }
8188
8189    /**
8190     * Returns if the ContentProvider has granted a uri to callingUid
8191     */
8192    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8193        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8194        if (perms != null) {
8195            for (int i=perms.size()-1; i>=0; i--) {
8196                GrantUri grantUri = perms.keyAt(i);
8197                if (grantUri.sourceUserId == userId || !checkUser) {
8198                    if (matchesProvider(grantUri.uri, cpi)) {
8199                        return true;
8200                    }
8201                }
8202            }
8203        }
8204        return false;
8205    }
8206
8207    /**
8208     * Returns true if the uri authority is one of the authorities specified in the provider.
8209     */
8210    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8211        String uriAuth = uri.getAuthority();
8212        String cpiAuth = cpi.authority;
8213        if (cpiAuth.indexOf(';') == -1) {
8214            return cpiAuth.equals(uriAuth);
8215        }
8216        String[] cpiAuths = cpiAuth.split(";");
8217        int length = cpiAuths.length;
8218        for (int i = 0; i < length; i++) {
8219            if (cpiAuths[i].equals(uriAuth)) return true;
8220        }
8221        return false;
8222    }
8223
8224    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8225            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8226        if (r != null) {
8227            for (int i=0; i<r.conProviders.size(); i++) {
8228                ContentProviderConnection conn = r.conProviders.get(i);
8229                if (conn.provider == cpr) {
8230                    if (DEBUG_PROVIDER) Slog.v(TAG,
8231                            "Adding provider requested by "
8232                            + r.processName + " from process "
8233                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8234                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8235                    if (stable) {
8236                        conn.stableCount++;
8237                        conn.numStableIncs++;
8238                    } else {
8239                        conn.unstableCount++;
8240                        conn.numUnstableIncs++;
8241                    }
8242                    return conn;
8243                }
8244            }
8245            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8246            if (stable) {
8247                conn.stableCount = 1;
8248                conn.numStableIncs = 1;
8249            } else {
8250                conn.unstableCount = 1;
8251                conn.numUnstableIncs = 1;
8252            }
8253            cpr.connections.add(conn);
8254            r.conProviders.add(conn);
8255            return conn;
8256        }
8257        cpr.addExternalProcessHandleLocked(externalProcessToken);
8258        return null;
8259    }
8260
8261    boolean decProviderCountLocked(ContentProviderConnection conn,
8262            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8263        if (conn != null) {
8264            cpr = conn.provider;
8265            if (DEBUG_PROVIDER) Slog.v(TAG,
8266                    "Removing provider requested by "
8267                    + conn.client.processName + " from process "
8268                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8269                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8270            if (stable) {
8271                conn.stableCount--;
8272            } else {
8273                conn.unstableCount--;
8274            }
8275            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8276                cpr.connections.remove(conn);
8277                conn.client.conProviders.remove(conn);
8278                return true;
8279            }
8280            return false;
8281        }
8282        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8283        return false;
8284    }
8285
8286    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8287            String name, IBinder token, boolean stable, int userId) {
8288        ContentProviderRecord cpr;
8289        ContentProviderConnection conn = null;
8290        ProviderInfo cpi = null;
8291
8292        synchronized(this) {
8293            ProcessRecord r = null;
8294            if (caller != null) {
8295                r = getRecordForAppLocked(caller);
8296                if (r == null) {
8297                    throw new SecurityException(
8298                            "Unable to find app for caller " + caller
8299                          + " (pid=" + Binder.getCallingPid()
8300                          + ") when getting content provider " + name);
8301                }
8302            }
8303
8304            boolean checkCrossUser = true;
8305
8306            // First check if this content provider has been published...
8307            cpr = mProviderMap.getProviderByName(name, userId);
8308            // If that didn't work, check if it exists for user 0 and then
8309            // verify that it's a singleton provider before using it.
8310            if (cpr == null && userId != UserHandle.USER_OWNER) {
8311                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8312                if (cpr != null) {
8313                    cpi = cpr.info;
8314                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8315                            cpi.name, cpi.flags)
8316                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8317                        userId = UserHandle.USER_OWNER;
8318                        checkCrossUser = false;
8319                    } else {
8320                        cpr = null;
8321                        cpi = null;
8322                    }
8323                }
8324            }
8325
8326            boolean providerRunning = cpr != null;
8327            if (providerRunning) {
8328                cpi = cpr.info;
8329                String msg;
8330                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8331                        != null) {
8332                    throw new SecurityException(msg);
8333                }
8334
8335                if (r != null && cpr.canRunHere(r)) {
8336                    // This provider has been published or is in the process
8337                    // of being published...  but it is also allowed to run
8338                    // in the caller's process, so don't make a connection
8339                    // and just let the caller instantiate its own instance.
8340                    ContentProviderHolder holder = cpr.newHolder(null);
8341                    // don't give caller the provider object, it needs
8342                    // to make its own.
8343                    holder.provider = null;
8344                    return holder;
8345                }
8346
8347                final long origId = Binder.clearCallingIdentity();
8348
8349                // In this case the provider instance already exists, so we can
8350                // return it right away.
8351                conn = incProviderCountLocked(r, cpr, token, stable);
8352                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8353                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8354                        // If this is a perceptible app accessing the provider,
8355                        // make sure to count it as being accessed and thus
8356                        // back up on the LRU list.  This is good because
8357                        // content providers are often expensive to start.
8358                        updateLruProcessLocked(cpr.proc, false, null);
8359                    }
8360                }
8361
8362                if (cpr.proc != null) {
8363                    if (false) {
8364                        if (cpr.name.flattenToShortString().equals(
8365                                "com.android.providers.calendar/.CalendarProvider2")) {
8366                            Slog.v(TAG, "****************** KILLING "
8367                                + cpr.name.flattenToShortString());
8368                            Process.killProcess(cpr.proc.pid);
8369                        }
8370                    }
8371                    boolean success = updateOomAdjLocked(cpr.proc);
8372                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8373                    // NOTE: there is still a race here where a signal could be
8374                    // pending on the process even though we managed to update its
8375                    // adj level.  Not sure what to do about this, but at least
8376                    // the race is now smaller.
8377                    if (!success) {
8378                        // Uh oh...  it looks like the provider's process
8379                        // has been killed on us.  We need to wait for a new
8380                        // process to be started, and make sure its death
8381                        // doesn't kill our process.
8382                        Slog.i(TAG,
8383                                "Existing provider " + cpr.name.flattenToShortString()
8384                                + " is crashing; detaching " + r);
8385                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8386                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8387                        if (!lastRef) {
8388                            // This wasn't the last ref our process had on
8389                            // the provider...  we have now been killed, bail.
8390                            return null;
8391                        }
8392                        providerRunning = false;
8393                        conn = null;
8394                    }
8395                }
8396
8397                Binder.restoreCallingIdentity(origId);
8398            }
8399
8400            boolean singleton;
8401            if (!providerRunning) {
8402                try {
8403                    cpi = AppGlobals.getPackageManager().
8404                        resolveContentProvider(name,
8405                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8406                } catch (RemoteException ex) {
8407                }
8408                if (cpi == null) {
8409                    return null;
8410                }
8411                // If the provider is a singleton AND
8412                // (it's a call within the same user || the provider is a
8413                // privileged app)
8414                // Then allow connecting to the singleton provider
8415                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8416                        cpi.name, cpi.flags)
8417                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8418                if (singleton) {
8419                    userId = UserHandle.USER_OWNER;
8420                }
8421                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8422
8423                String msg;
8424                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8425                        != null) {
8426                    throw new SecurityException(msg);
8427                }
8428
8429                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8430                        && !cpi.processName.equals("system")) {
8431                    // If this content provider does not run in the system
8432                    // process, and the system is not yet ready to run other
8433                    // processes, then fail fast instead of hanging.
8434                    throw new IllegalArgumentException(
8435                            "Attempt to launch content provider before system ready");
8436                }
8437
8438                // Make sure that the user who owns this provider is started.  If not,
8439                // we don't want to allow it to run.
8440                if (mStartedUsers.get(userId) == null) {
8441                    Slog.w(TAG, "Unable to launch app "
8442                            + cpi.applicationInfo.packageName + "/"
8443                            + cpi.applicationInfo.uid + " for provider "
8444                            + name + ": user " + userId + " is stopped");
8445                    return null;
8446                }
8447
8448                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8449                cpr = mProviderMap.getProviderByClass(comp, userId);
8450                final boolean firstClass = cpr == null;
8451                if (firstClass) {
8452                    try {
8453                        ApplicationInfo ai =
8454                            AppGlobals.getPackageManager().
8455                                getApplicationInfo(
8456                                        cpi.applicationInfo.packageName,
8457                                        STOCK_PM_FLAGS, userId);
8458                        if (ai == null) {
8459                            Slog.w(TAG, "No package info for content provider "
8460                                    + cpi.name);
8461                            return null;
8462                        }
8463                        ai = getAppInfoForUser(ai, userId);
8464                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8465                    } catch (RemoteException ex) {
8466                        // pm is in same process, this will never happen.
8467                    }
8468                }
8469
8470                if (r != null && cpr.canRunHere(r)) {
8471                    // If this is a multiprocess provider, then just return its
8472                    // info and allow the caller to instantiate it.  Only do
8473                    // this if the provider is the same user as the caller's
8474                    // process, or can run as root (so can be in any process).
8475                    return cpr.newHolder(null);
8476                }
8477
8478                if (DEBUG_PROVIDER) {
8479                    RuntimeException e = new RuntimeException("here");
8480                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8481                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8482                }
8483
8484                // This is single process, and our app is now connecting to it.
8485                // See if we are already in the process of launching this
8486                // provider.
8487                final int N = mLaunchingProviders.size();
8488                int i;
8489                for (i=0; i<N; i++) {
8490                    if (mLaunchingProviders.get(i) == cpr) {
8491                        break;
8492                    }
8493                }
8494
8495                // If the provider is not already being launched, then get it
8496                // started.
8497                if (i >= N) {
8498                    final long origId = Binder.clearCallingIdentity();
8499
8500                    try {
8501                        // Content provider is now in use, its package can't be stopped.
8502                        try {
8503                            AppGlobals.getPackageManager().setPackageStoppedState(
8504                                    cpr.appInfo.packageName, false, userId);
8505                        } catch (RemoteException e) {
8506                        } catch (IllegalArgumentException e) {
8507                            Slog.w(TAG, "Failed trying to unstop package "
8508                                    + cpr.appInfo.packageName + ": " + e);
8509                        }
8510
8511                        // Use existing process if already started
8512                        ProcessRecord proc = getProcessRecordLocked(
8513                                cpi.processName, cpr.appInfo.uid, false);
8514                        if (proc != null && proc.thread != null) {
8515                            if (DEBUG_PROVIDER) {
8516                                Slog.d(TAG, "Installing in existing process " + proc);
8517                            }
8518                            proc.pubProviders.put(cpi.name, cpr);
8519                            try {
8520                                proc.thread.scheduleInstallProvider(cpi);
8521                            } catch (RemoteException e) {
8522                            }
8523                        } else {
8524                            proc = startProcessLocked(cpi.processName,
8525                                    cpr.appInfo, false, 0, "content provider",
8526                                    new ComponentName(cpi.applicationInfo.packageName,
8527                                            cpi.name), false, false, false);
8528                            if (proc == null) {
8529                                Slog.w(TAG, "Unable to launch app "
8530                                        + cpi.applicationInfo.packageName + "/"
8531                                        + cpi.applicationInfo.uid + " for provider "
8532                                        + name + ": process is bad");
8533                                return null;
8534                            }
8535                        }
8536                        cpr.launchingApp = proc;
8537                        mLaunchingProviders.add(cpr);
8538                    } finally {
8539                        Binder.restoreCallingIdentity(origId);
8540                    }
8541                }
8542
8543                // Make sure the provider is published (the same provider class
8544                // may be published under multiple names).
8545                if (firstClass) {
8546                    mProviderMap.putProviderByClass(comp, cpr);
8547                }
8548
8549                mProviderMap.putProviderByName(name, cpr);
8550                conn = incProviderCountLocked(r, cpr, token, stable);
8551                if (conn != null) {
8552                    conn.waiting = true;
8553                }
8554            }
8555        }
8556
8557        // Wait for the provider to be published...
8558        synchronized (cpr) {
8559            while (cpr.provider == null) {
8560                if (cpr.launchingApp == null) {
8561                    Slog.w(TAG, "Unable to launch app "
8562                            + cpi.applicationInfo.packageName + "/"
8563                            + cpi.applicationInfo.uid + " for provider "
8564                            + name + ": launching app became null");
8565                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8566                            UserHandle.getUserId(cpi.applicationInfo.uid),
8567                            cpi.applicationInfo.packageName,
8568                            cpi.applicationInfo.uid, name);
8569                    return null;
8570                }
8571                try {
8572                    if (DEBUG_MU) {
8573                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8574                                + cpr.launchingApp);
8575                    }
8576                    if (conn != null) {
8577                        conn.waiting = true;
8578                    }
8579                    cpr.wait();
8580                } catch (InterruptedException ex) {
8581                } finally {
8582                    if (conn != null) {
8583                        conn.waiting = false;
8584                    }
8585                }
8586            }
8587        }
8588        return cpr != null ? cpr.newHolder(conn) : null;
8589    }
8590
8591    @Override
8592    public final ContentProviderHolder getContentProvider(
8593            IApplicationThread caller, String name, int userId, boolean stable) {
8594        enforceNotIsolatedCaller("getContentProvider");
8595        if (caller == null) {
8596            String msg = "null IApplicationThread when getting content provider "
8597                    + name;
8598            Slog.w(TAG, msg);
8599            throw new SecurityException(msg);
8600        }
8601        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8602        // with cross-user grant.
8603        return getContentProviderImpl(caller, name, null, stable, userId);
8604    }
8605
8606    public ContentProviderHolder getContentProviderExternal(
8607            String name, int userId, IBinder token) {
8608        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8609            "Do not have permission in call getContentProviderExternal()");
8610        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8611                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8612        return getContentProviderExternalUnchecked(name, token, userId);
8613    }
8614
8615    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8616            IBinder token, int userId) {
8617        return getContentProviderImpl(null, name, token, true, userId);
8618    }
8619
8620    /**
8621     * Drop a content provider from a ProcessRecord's bookkeeping
8622     */
8623    public void removeContentProvider(IBinder connection, boolean stable) {
8624        enforceNotIsolatedCaller("removeContentProvider");
8625        long ident = Binder.clearCallingIdentity();
8626        try {
8627            synchronized (this) {
8628                ContentProviderConnection conn;
8629                try {
8630                    conn = (ContentProviderConnection)connection;
8631                } catch (ClassCastException e) {
8632                    String msg ="removeContentProvider: " + connection
8633                            + " not a ContentProviderConnection";
8634                    Slog.w(TAG, msg);
8635                    throw new IllegalArgumentException(msg);
8636                }
8637                if (conn == null) {
8638                    throw new NullPointerException("connection is null");
8639                }
8640                if (decProviderCountLocked(conn, null, null, stable)) {
8641                    updateOomAdjLocked();
8642                }
8643            }
8644        } finally {
8645            Binder.restoreCallingIdentity(ident);
8646        }
8647    }
8648
8649    public void removeContentProviderExternal(String name, IBinder token) {
8650        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8651            "Do not have permission in call removeContentProviderExternal()");
8652        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8653    }
8654
8655    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8656        synchronized (this) {
8657            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8658            if(cpr == null) {
8659                //remove from mProvidersByClass
8660                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8661                return;
8662            }
8663
8664            //update content provider record entry info
8665            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8666            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8667            if (localCpr.hasExternalProcessHandles()) {
8668                if (localCpr.removeExternalProcessHandleLocked(token)) {
8669                    updateOomAdjLocked();
8670                } else {
8671                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8672                            + " with no external reference for token: "
8673                            + token + ".");
8674                }
8675            } else {
8676                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8677                        + " with no external references.");
8678            }
8679        }
8680    }
8681
8682    public final void publishContentProviders(IApplicationThread caller,
8683            List<ContentProviderHolder> providers) {
8684        if (providers == null) {
8685            return;
8686        }
8687
8688        enforceNotIsolatedCaller("publishContentProviders");
8689        synchronized (this) {
8690            final ProcessRecord r = getRecordForAppLocked(caller);
8691            if (DEBUG_MU)
8692                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8693            if (r == null) {
8694                throw new SecurityException(
8695                        "Unable to find app for caller " + caller
8696                      + " (pid=" + Binder.getCallingPid()
8697                      + ") when publishing content providers");
8698            }
8699
8700            final long origId = Binder.clearCallingIdentity();
8701
8702            final int N = providers.size();
8703            for (int i=0; i<N; i++) {
8704                ContentProviderHolder src = providers.get(i);
8705                if (src == null || src.info == null || src.provider == null) {
8706                    continue;
8707                }
8708                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8709                if (DEBUG_MU)
8710                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8711                if (dst != null) {
8712                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8713                    mProviderMap.putProviderByClass(comp, dst);
8714                    String names[] = dst.info.authority.split(";");
8715                    for (int j = 0; j < names.length; j++) {
8716                        mProviderMap.putProviderByName(names[j], dst);
8717                    }
8718
8719                    int NL = mLaunchingProviders.size();
8720                    int j;
8721                    for (j=0; j<NL; j++) {
8722                        if (mLaunchingProviders.get(j) == dst) {
8723                            mLaunchingProviders.remove(j);
8724                            j--;
8725                            NL--;
8726                        }
8727                    }
8728                    synchronized (dst) {
8729                        dst.provider = src.provider;
8730                        dst.proc = r;
8731                        dst.notifyAll();
8732                    }
8733                    updateOomAdjLocked(r);
8734                }
8735            }
8736
8737            Binder.restoreCallingIdentity(origId);
8738        }
8739    }
8740
8741    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8742        ContentProviderConnection conn;
8743        try {
8744            conn = (ContentProviderConnection)connection;
8745        } catch (ClassCastException e) {
8746            String msg ="refContentProvider: " + connection
8747                    + " not a ContentProviderConnection";
8748            Slog.w(TAG, msg);
8749            throw new IllegalArgumentException(msg);
8750        }
8751        if (conn == null) {
8752            throw new NullPointerException("connection is null");
8753        }
8754
8755        synchronized (this) {
8756            if (stable > 0) {
8757                conn.numStableIncs += stable;
8758            }
8759            stable = conn.stableCount + stable;
8760            if (stable < 0) {
8761                throw new IllegalStateException("stableCount < 0: " + stable);
8762            }
8763
8764            if (unstable > 0) {
8765                conn.numUnstableIncs += unstable;
8766            }
8767            unstable = conn.unstableCount + unstable;
8768            if (unstable < 0) {
8769                throw new IllegalStateException("unstableCount < 0: " + unstable);
8770            }
8771
8772            if ((stable+unstable) <= 0) {
8773                throw new IllegalStateException("ref counts can't go to zero here: stable="
8774                        + stable + " unstable=" + unstable);
8775            }
8776            conn.stableCount = stable;
8777            conn.unstableCount = unstable;
8778            return !conn.dead;
8779        }
8780    }
8781
8782    public void unstableProviderDied(IBinder connection) {
8783        ContentProviderConnection conn;
8784        try {
8785            conn = (ContentProviderConnection)connection;
8786        } catch (ClassCastException e) {
8787            String msg ="refContentProvider: " + connection
8788                    + " not a ContentProviderConnection";
8789            Slog.w(TAG, msg);
8790            throw new IllegalArgumentException(msg);
8791        }
8792        if (conn == null) {
8793            throw new NullPointerException("connection is null");
8794        }
8795
8796        // Safely retrieve the content provider associated with the connection.
8797        IContentProvider provider;
8798        synchronized (this) {
8799            provider = conn.provider.provider;
8800        }
8801
8802        if (provider == null) {
8803            // Um, yeah, we're way ahead of you.
8804            return;
8805        }
8806
8807        // Make sure the caller is being honest with us.
8808        if (provider.asBinder().pingBinder()) {
8809            // Er, no, still looks good to us.
8810            synchronized (this) {
8811                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8812                        + " says " + conn + " died, but we don't agree");
8813                return;
8814            }
8815        }
8816
8817        // Well look at that!  It's dead!
8818        synchronized (this) {
8819            if (conn.provider.provider != provider) {
8820                // But something changed...  good enough.
8821                return;
8822            }
8823
8824            ProcessRecord proc = conn.provider.proc;
8825            if (proc == null || proc.thread == null) {
8826                // Seems like the process is already cleaned up.
8827                return;
8828            }
8829
8830            // As far as we're concerned, this is just like receiving a
8831            // death notification...  just a bit prematurely.
8832            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8833                    + ") early provider death");
8834            final long ident = Binder.clearCallingIdentity();
8835            try {
8836                appDiedLocked(proc, proc.pid, proc.thread);
8837            } finally {
8838                Binder.restoreCallingIdentity(ident);
8839            }
8840        }
8841    }
8842
8843    @Override
8844    public void appNotRespondingViaProvider(IBinder connection) {
8845        enforceCallingPermission(
8846                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8847
8848        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8849        if (conn == null) {
8850            Slog.w(TAG, "ContentProviderConnection is null");
8851            return;
8852        }
8853
8854        final ProcessRecord host = conn.provider.proc;
8855        if (host == null) {
8856            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8857            return;
8858        }
8859
8860        final long token = Binder.clearCallingIdentity();
8861        try {
8862            appNotResponding(host, null, null, false, "ContentProvider not responding");
8863        } finally {
8864            Binder.restoreCallingIdentity(token);
8865        }
8866    }
8867
8868    public final void installSystemProviders() {
8869        List<ProviderInfo> providers;
8870        synchronized (this) {
8871            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8872            providers = generateApplicationProvidersLocked(app);
8873            if (providers != null) {
8874                for (int i=providers.size()-1; i>=0; i--) {
8875                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8876                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8877                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8878                                + ": not system .apk");
8879                        providers.remove(i);
8880                    }
8881                }
8882            }
8883        }
8884        if (providers != null) {
8885            mSystemThread.installSystemProviders(providers);
8886        }
8887
8888        mCoreSettingsObserver = new CoreSettingsObserver(this);
8889
8890        //mUsageStatsService.monitorPackages();
8891    }
8892
8893    /**
8894     * Allows app to retrieve the MIME type of a URI without having permission
8895     * to access its content provider.
8896     *
8897     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8898     *
8899     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8900     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8901     */
8902    public String getProviderMimeType(Uri uri, int userId) {
8903        enforceNotIsolatedCaller("getProviderMimeType");
8904        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8905                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8906        final String name = uri.getAuthority();
8907        final long ident = Binder.clearCallingIdentity();
8908        ContentProviderHolder holder = null;
8909
8910        try {
8911            holder = getContentProviderExternalUnchecked(name, null, userId);
8912            if (holder != null) {
8913                return holder.provider.getType(uri);
8914            }
8915        } catch (RemoteException e) {
8916            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8917            return null;
8918        } finally {
8919            if (holder != null) {
8920                removeContentProviderExternalUnchecked(name, null, userId);
8921            }
8922            Binder.restoreCallingIdentity(ident);
8923        }
8924
8925        return null;
8926    }
8927
8928    // =========================================================
8929    // GLOBAL MANAGEMENT
8930    // =========================================================
8931
8932    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8933            boolean isolated) {
8934        String proc = customProcess != null ? customProcess : info.processName;
8935        BatteryStatsImpl.Uid.Proc ps = null;
8936        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8937        int uid = info.uid;
8938        if (isolated) {
8939            int userId = UserHandle.getUserId(uid);
8940            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8941            while (true) {
8942                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8943                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8944                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8945                }
8946                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8947                mNextIsolatedProcessUid++;
8948                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8949                    // No process for this uid, use it.
8950                    break;
8951                }
8952                stepsLeft--;
8953                if (stepsLeft <= 0) {
8954                    return null;
8955                }
8956            }
8957        }
8958        return new ProcessRecord(stats, info, proc, uid);
8959    }
8960
8961    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8962            String abiOverride) {
8963        ProcessRecord app;
8964        if (!isolated) {
8965            app = getProcessRecordLocked(info.processName, info.uid, true);
8966        } else {
8967            app = null;
8968        }
8969
8970        if (app == null) {
8971            app = newProcessRecordLocked(info, null, isolated);
8972            mProcessNames.put(info.processName, app.uid, app);
8973            if (isolated) {
8974                mIsolatedProcesses.put(app.uid, app);
8975            }
8976            updateLruProcessLocked(app, false, null);
8977            updateOomAdjLocked();
8978        }
8979
8980        // This package really, really can not be stopped.
8981        try {
8982            AppGlobals.getPackageManager().setPackageStoppedState(
8983                    info.packageName, false, UserHandle.getUserId(app.uid));
8984        } catch (RemoteException e) {
8985        } catch (IllegalArgumentException e) {
8986            Slog.w(TAG, "Failed trying to unstop package "
8987                    + info.packageName + ": " + e);
8988        }
8989
8990        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8991                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8992            app.persistent = true;
8993            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8994        }
8995        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8996            mPersistentStartingProcesses.add(app);
8997            startProcessLocked(app, "added application", app.processName,
8998                    abiOverride);
8999        }
9000
9001        return app;
9002    }
9003
9004    public void unhandledBack() {
9005        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9006                "unhandledBack()");
9007
9008        synchronized(this) {
9009            final long origId = Binder.clearCallingIdentity();
9010            try {
9011                getFocusedStack().unhandledBackLocked();
9012            } finally {
9013                Binder.restoreCallingIdentity(origId);
9014            }
9015        }
9016    }
9017
9018    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9019        enforceNotIsolatedCaller("openContentUri");
9020        final int userId = UserHandle.getCallingUserId();
9021        String name = uri.getAuthority();
9022        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9023        ParcelFileDescriptor pfd = null;
9024        if (cph != null) {
9025            // We record the binder invoker's uid in thread-local storage before
9026            // going to the content provider to open the file.  Later, in the code
9027            // that handles all permissions checks, we look for this uid and use
9028            // that rather than the Activity Manager's own uid.  The effect is that
9029            // we do the check against the caller's permissions even though it looks
9030            // to the content provider like the Activity Manager itself is making
9031            // the request.
9032            sCallerIdentity.set(new Identity(
9033                    Binder.getCallingPid(), Binder.getCallingUid()));
9034            try {
9035                pfd = cph.provider.openFile(null, uri, "r", null);
9036            } catch (FileNotFoundException e) {
9037                // do nothing; pfd will be returned null
9038            } finally {
9039                // Ensure that whatever happens, we clean up the identity state
9040                sCallerIdentity.remove();
9041            }
9042
9043            // We've got the fd now, so we're done with the provider.
9044            removeContentProviderExternalUnchecked(name, null, userId);
9045        } else {
9046            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9047        }
9048        return pfd;
9049    }
9050
9051    // Actually is sleeping or shutting down or whatever else in the future
9052    // is an inactive state.
9053    public boolean isSleepingOrShuttingDown() {
9054        return mSleeping || mShuttingDown;
9055    }
9056
9057    public boolean isSleeping() {
9058        return mSleeping;
9059    }
9060
9061    void goingToSleep() {
9062        synchronized(this) {
9063            mWentToSleep = true;
9064            updateEventDispatchingLocked();
9065            goToSleepIfNeededLocked();
9066        }
9067    }
9068
9069    void finishRunningVoiceLocked() {
9070        if (mRunningVoice) {
9071            mRunningVoice = false;
9072            goToSleepIfNeededLocked();
9073        }
9074    }
9075
9076    void goToSleepIfNeededLocked() {
9077        if (mWentToSleep && !mRunningVoice) {
9078            if (!mSleeping) {
9079                mSleeping = true;
9080                mStackSupervisor.goingToSleepLocked();
9081
9082                // Initialize the wake times of all processes.
9083                checkExcessivePowerUsageLocked(false);
9084                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9085                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9086                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9087            }
9088        }
9089    }
9090
9091    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9092        mTaskPersister.notify(task, flush);
9093    }
9094
9095    @Override
9096    public boolean shutdown(int timeout) {
9097        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9098                != PackageManager.PERMISSION_GRANTED) {
9099            throw new SecurityException("Requires permission "
9100                    + android.Manifest.permission.SHUTDOWN);
9101        }
9102
9103        boolean timedout = false;
9104
9105        synchronized(this) {
9106            mShuttingDown = true;
9107            updateEventDispatchingLocked();
9108            timedout = mStackSupervisor.shutdownLocked(timeout);
9109        }
9110
9111        mAppOpsService.shutdown();
9112        if (mUsageStatsService != null) {
9113            mUsageStatsService.prepareShutdown();
9114        }
9115        mBatteryStatsService.shutdown();
9116        synchronized (this) {
9117            mProcessStats.shutdownLocked();
9118        }
9119        notifyTaskPersisterLocked(null, true);
9120
9121        return timedout;
9122    }
9123
9124    public final void activitySlept(IBinder token) {
9125        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9126
9127        final long origId = Binder.clearCallingIdentity();
9128
9129        synchronized (this) {
9130            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9131            if (r != null) {
9132                mStackSupervisor.activitySleptLocked(r);
9133            }
9134        }
9135
9136        Binder.restoreCallingIdentity(origId);
9137    }
9138
9139    void logLockScreen(String msg) {
9140        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9141                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9142                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9143                mStackSupervisor.mDismissKeyguardOnNextActivity);
9144    }
9145
9146    private void comeOutOfSleepIfNeededLocked() {
9147        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9148            if (mSleeping) {
9149                mSleeping = false;
9150                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9151            }
9152        }
9153    }
9154
9155    void wakingUp() {
9156        synchronized(this) {
9157            mWentToSleep = false;
9158            updateEventDispatchingLocked();
9159            comeOutOfSleepIfNeededLocked();
9160        }
9161    }
9162
9163    void startRunningVoiceLocked() {
9164        if (!mRunningVoice) {
9165            mRunningVoice = true;
9166            comeOutOfSleepIfNeededLocked();
9167        }
9168    }
9169
9170    private void updateEventDispatchingLocked() {
9171        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9172    }
9173
9174    public void setLockScreenShown(boolean shown) {
9175        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9176                != PackageManager.PERMISSION_GRANTED) {
9177            throw new SecurityException("Requires permission "
9178                    + android.Manifest.permission.DEVICE_POWER);
9179        }
9180
9181        synchronized(this) {
9182            long ident = Binder.clearCallingIdentity();
9183            try {
9184                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9185                mLockScreenShown = shown;
9186                comeOutOfSleepIfNeededLocked();
9187            } finally {
9188                Binder.restoreCallingIdentity(ident);
9189            }
9190        }
9191    }
9192
9193    @Override
9194    public void stopAppSwitches() {
9195        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9196                != PackageManager.PERMISSION_GRANTED) {
9197            throw new SecurityException("Requires permission "
9198                    + android.Manifest.permission.STOP_APP_SWITCHES);
9199        }
9200
9201        synchronized(this) {
9202            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9203                    + APP_SWITCH_DELAY_TIME;
9204            mDidAppSwitch = false;
9205            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9206            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9207            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9208        }
9209    }
9210
9211    public void resumeAppSwitches() {
9212        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9213                != PackageManager.PERMISSION_GRANTED) {
9214            throw new SecurityException("Requires permission "
9215                    + android.Manifest.permission.STOP_APP_SWITCHES);
9216        }
9217
9218        synchronized(this) {
9219            // Note that we don't execute any pending app switches... we will
9220            // let those wait until either the timeout, or the next start
9221            // activity request.
9222            mAppSwitchesAllowedTime = 0;
9223        }
9224    }
9225
9226    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9227            String name) {
9228        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9229            return true;
9230        }
9231
9232        final int perm = checkComponentPermission(
9233                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9234                callingUid, -1, true);
9235        if (perm == PackageManager.PERMISSION_GRANTED) {
9236            return true;
9237        }
9238
9239        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9240        return false;
9241    }
9242
9243    public void setDebugApp(String packageName, boolean waitForDebugger,
9244            boolean persistent) {
9245        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9246                "setDebugApp()");
9247
9248        long ident = Binder.clearCallingIdentity();
9249        try {
9250            // Note that this is not really thread safe if there are multiple
9251            // callers into it at the same time, but that's not a situation we
9252            // care about.
9253            if (persistent) {
9254                final ContentResolver resolver = mContext.getContentResolver();
9255                Settings.Global.putString(
9256                    resolver, Settings.Global.DEBUG_APP,
9257                    packageName);
9258                Settings.Global.putInt(
9259                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9260                    waitForDebugger ? 1 : 0);
9261            }
9262
9263            synchronized (this) {
9264                if (!persistent) {
9265                    mOrigDebugApp = mDebugApp;
9266                    mOrigWaitForDebugger = mWaitForDebugger;
9267                }
9268                mDebugApp = packageName;
9269                mWaitForDebugger = waitForDebugger;
9270                mDebugTransient = !persistent;
9271                if (packageName != null) {
9272                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9273                            false, UserHandle.USER_ALL, "set debug app");
9274                }
9275            }
9276        } finally {
9277            Binder.restoreCallingIdentity(ident);
9278        }
9279    }
9280
9281    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9282        synchronized (this) {
9283            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9284            if (!isDebuggable) {
9285                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9286                    throw new SecurityException("Process not debuggable: " + app.packageName);
9287                }
9288            }
9289
9290            mOpenGlTraceApp = processName;
9291        }
9292    }
9293
9294    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9295            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9296        synchronized (this) {
9297            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9298            if (!isDebuggable) {
9299                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9300                    throw new SecurityException("Process not debuggable: " + app.packageName);
9301                }
9302            }
9303            mProfileApp = processName;
9304            mProfileFile = profileFile;
9305            if (mProfileFd != null) {
9306                try {
9307                    mProfileFd.close();
9308                } catch (IOException e) {
9309                }
9310                mProfileFd = null;
9311            }
9312            mProfileFd = profileFd;
9313            mProfileType = 0;
9314            mAutoStopProfiler = autoStopProfiler;
9315        }
9316    }
9317
9318    @Override
9319    public void setAlwaysFinish(boolean enabled) {
9320        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9321                "setAlwaysFinish()");
9322
9323        Settings.Global.putInt(
9324                mContext.getContentResolver(),
9325                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9326
9327        synchronized (this) {
9328            mAlwaysFinishActivities = enabled;
9329        }
9330    }
9331
9332    @Override
9333    public void setActivityController(IActivityController controller) {
9334        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9335                "setActivityController()");
9336        synchronized (this) {
9337            mController = controller;
9338            Watchdog.getInstance().setActivityController(controller);
9339        }
9340    }
9341
9342    @Override
9343    public void setUserIsMonkey(boolean userIsMonkey) {
9344        synchronized (this) {
9345            synchronized (mPidsSelfLocked) {
9346                final int callingPid = Binder.getCallingPid();
9347                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9348                if (precessRecord == null) {
9349                    throw new SecurityException("Unknown process: " + callingPid);
9350                }
9351                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9352                    throw new SecurityException("Only an instrumentation process "
9353                            + "with a UiAutomation can call setUserIsMonkey");
9354                }
9355            }
9356            mUserIsMonkey = userIsMonkey;
9357        }
9358    }
9359
9360    @Override
9361    public boolean isUserAMonkey() {
9362        synchronized (this) {
9363            // If there is a controller also implies the user is a monkey.
9364            return (mUserIsMonkey || mController != null);
9365        }
9366    }
9367
9368    public void requestBugReport() {
9369        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9370        SystemProperties.set("ctl.start", "bugreport");
9371    }
9372
9373    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9374        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9375    }
9376
9377    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9378        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9379            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9380        }
9381        return KEY_DISPATCHING_TIMEOUT;
9382    }
9383
9384    @Override
9385    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9386        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9387                != PackageManager.PERMISSION_GRANTED) {
9388            throw new SecurityException("Requires permission "
9389                    + android.Manifest.permission.FILTER_EVENTS);
9390        }
9391        ProcessRecord proc;
9392        long timeout;
9393        synchronized (this) {
9394            synchronized (mPidsSelfLocked) {
9395                proc = mPidsSelfLocked.get(pid);
9396            }
9397            timeout = getInputDispatchingTimeoutLocked(proc);
9398        }
9399
9400        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9401            return -1;
9402        }
9403
9404        return timeout;
9405    }
9406
9407    /**
9408     * Handle input dispatching timeouts.
9409     * Returns whether input dispatching should be aborted or not.
9410     */
9411    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9412            final ActivityRecord activity, final ActivityRecord parent,
9413            final boolean aboveSystem, String reason) {
9414        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9415                != PackageManager.PERMISSION_GRANTED) {
9416            throw new SecurityException("Requires permission "
9417                    + android.Manifest.permission.FILTER_EVENTS);
9418        }
9419
9420        final String annotation;
9421        if (reason == null) {
9422            annotation = "Input dispatching timed out";
9423        } else {
9424            annotation = "Input dispatching timed out (" + reason + ")";
9425        }
9426
9427        if (proc != null) {
9428            synchronized (this) {
9429                if (proc.debugging) {
9430                    return false;
9431                }
9432
9433                if (mDidDexOpt) {
9434                    // Give more time since we were dexopting.
9435                    mDidDexOpt = false;
9436                    return false;
9437                }
9438
9439                if (proc.instrumentationClass != null) {
9440                    Bundle info = new Bundle();
9441                    info.putString("shortMsg", "keyDispatchingTimedOut");
9442                    info.putString("longMsg", annotation);
9443                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9444                    return true;
9445                }
9446            }
9447            mHandler.post(new Runnable() {
9448                @Override
9449                public void run() {
9450                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9451                }
9452            });
9453        }
9454
9455        return true;
9456    }
9457
9458    public Bundle getAssistContextExtras(int requestType) {
9459        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9460                "getAssistContextExtras()");
9461        PendingAssistExtras pae;
9462        Bundle extras = new Bundle();
9463        synchronized (this) {
9464            ActivityRecord activity = getFocusedStack().mResumedActivity;
9465            if (activity == null) {
9466                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9467                return null;
9468            }
9469            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9470            if (activity.app == null || activity.app.thread == null) {
9471                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9472                return extras;
9473            }
9474            if (activity.app.pid == Binder.getCallingPid()) {
9475                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9476                return extras;
9477            }
9478            pae = new PendingAssistExtras(activity);
9479            try {
9480                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9481                        requestType);
9482                mPendingAssistExtras.add(pae);
9483                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9484            } catch (RemoteException e) {
9485                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9486                return extras;
9487            }
9488        }
9489        synchronized (pae) {
9490            while (!pae.haveResult) {
9491                try {
9492                    pae.wait();
9493                } catch (InterruptedException e) {
9494                }
9495            }
9496            if (pae.result != null) {
9497                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9498            }
9499        }
9500        synchronized (this) {
9501            mPendingAssistExtras.remove(pae);
9502            mHandler.removeCallbacks(pae);
9503        }
9504        return extras;
9505    }
9506
9507    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9508        PendingAssistExtras pae = (PendingAssistExtras)token;
9509        synchronized (pae) {
9510            pae.result = extras;
9511            pae.haveResult = true;
9512            pae.notifyAll();
9513        }
9514    }
9515
9516    public void registerProcessObserver(IProcessObserver observer) {
9517        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9518                "registerProcessObserver()");
9519        synchronized (this) {
9520            mProcessObservers.register(observer);
9521        }
9522    }
9523
9524    @Override
9525    public void unregisterProcessObserver(IProcessObserver observer) {
9526        synchronized (this) {
9527            mProcessObservers.unregister(observer);
9528        }
9529    }
9530
9531    @Override
9532    public boolean convertFromTranslucent(IBinder token) {
9533        final long origId = Binder.clearCallingIdentity();
9534        try {
9535            synchronized (this) {
9536                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9537                if (r == null) {
9538                    return false;
9539                }
9540                if (r.changeWindowTranslucency(true)) {
9541                    mWindowManager.setAppFullscreen(token, true);
9542                    r.task.stack.releaseMediaResources();
9543                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9544                    return true;
9545                }
9546                return false;
9547            }
9548        } finally {
9549            Binder.restoreCallingIdentity(origId);
9550        }
9551    }
9552
9553    @Override
9554    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9555        final long origId = Binder.clearCallingIdentity();
9556        try {
9557            synchronized (this) {
9558                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9559                if (r == null) {
9560                    return false;
9561                }
9562                int index = r.task.mActivities.lastIndexOf(r);
9563                if (index > 0) {
9564                    ActivityRecord under = r.task.mActivities.get(index - 1);
9565                    under.returningOptions = options;
9566                }
9567                if (r.changeWindowTranslucency(false)) {
9568                    r.task.stack.convertToTranslucent(r);
9569                    mWindowManager.setAppFullscreen(token, false);
9570                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9571                    return true;
9572                } else {
9573                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9574                    return false;
9575                }
9576            }
9577        } finally {
9578            Binder.restoreCallingIdentity(origId);
9579        }
9580    }
9581
9582    @Override
9583    public boolean setMediaPlaying(IBinder token, boolean playing) {
9584        final long origId = Binder.clearCallingIdentity();
9585        try {
9586            synchronized (this) {
9587                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9588                if (r != null) {
9589                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9590                }
9591            }
9592            return false;
9593        } finally {
9594            Binder.restoreCallingIdentity(origId);
9595        }
9596    }
9597
9598    @Override
9599    public boolean isBackgroundMediaPlaying(IBinder token) {
9600        final long origId = Binder.clearCallingIdentity();
9601        try {
9602            synchronized (this) {
9603                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9604                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9605                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9606                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9607                return playing;
9608            }
9609        } finally {
9610            Binder.restoreCallingIdentity(origId);
9611        }
9612    }
9613
9614    @Override
9615    public ActivityOptions getActivityOptions(IBinder token) {
9616        final long origId = Binder.clearCallingIdentity();
9617        try {
9618            synchronized (this) {
9619                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9620                if (r != null) {
9621                    final ActivityOptions activityOptions = r.pendingOptions;
9622                    r.pendingOptions = null;
9623                    return activityOptions;
9624                }
9625                return null;
9626            }
9627        } finally {
9628            Binder.restoreCallingIdentity(origId);
9629        }
9630    }
9631
9632    @Override
9633    public void setImmersive(IBinder token, boolean immersive) {
9634        synchronized(this) {
9635            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9636            if (r == null) {
9637                throw new IllegalArgumentException();
9638            }
9639            r.immersive = immersive;
9640
9641            // update associated state if we're frontmost
9642            if (r == mFocusedActivity) {
9643                if (DEBUG_IMMERSIVE) {
9644                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9645                }
9646                applyUpdateLockStateLocked(r);
9647            }
9648        }
9649    }
9650
9651    @Override
9652    public boolean isImmersive(IBinder token) {
9653        synchronized (this) {
9654            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9655            if (r == null) {
9656                throw new IllegalArgumentException();
9657            }
9658            return r.immersive;
9659        }
9660    }
9661
9662    public boolean isTopActivityImmersive() {
9663        enforceNotIsolatedCaller("startActivity");
9664        synchronized (this) {
9665            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9666            return (r != null) ? r.immersive : false;
9667        }
9668    }
9669
9670    @Override
9671    public boolean isTopOfTask(IBinder token) {
9672        synchronized (this) {
9673            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9674            if (r == null) {
9675                throw new IllegalArgumentException();
9676            }
9677            return r.task.getTopActivity() == r;
9678        }
9679    }
9680
9681    public final void enterSafeMode() {
9682        synchronized(this) {
9683            // It only makes sense to do this before the system is ready
9684            // and started launching other packages.
9685            if (!mSystemReady) {
9686                try {
9687                    AppGlobals.getPackageManager().enterSafeMode();
9688                } catch (RemoteException e) {
9689                }
9690            }
9691
9692            mSafeMode = true;
9693        }
9694    }
9695
9696    public final void showSafeModeOverlay() {
9697        View v = LayoutInflater.from(mContext).inflate(
9698                com.android.internal.R.layout.safe_mode, null);
9699        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9700        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9701        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9702        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9703        lp.gravity = Gravity.BOTTOM | Gravity.START;
9704        lp.format = v.getBackground().getOpacity();
9705        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9706                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9707        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9708        ((WindowManager)mContext.getSystemService(
9709                Context.WINDOW_SERVICE)).addView(v, lp);
9710    }
9711
9712    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9713        if (!(sender instanceof PendingIntentRecord)) {
9714            return;
9715        }
9716        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9717        synchronized (stats) {
9718            if (mBatteryStatsService.isOnBattery()) {
9719                mBatteryStatsService.enforceCallingPermission();
9720                PendingIntentRecord rec = (PendingIntentRecord)sender;
9721                int MY_UID = Binder.getCallingUid();
9722                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9723                BatteryStatsImpl.Uid.Pkg pkg =
9724                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9725                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9726                pkg.incWakeupsLocked();
9727            }
9728        }
9729    }
9730
9731    public boolean killPids(int[] pids, String pReason, boolean secure) {
9732        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9733            throw new SecurityException("killPids only available to the system");
9734        }
9735        String reason = (pReason == null) ? "Unknown" : pReason;
9736        // XXX Note: don't acquire main activity lock here, because the window
9737        // manager calls in with its locks held.
9738
9739        boolean killed = false;
9740        synchronized (mPidsSelfLocked) {
9741            int[] types = new int[pids.length];
9742            int worstType = 0;
9743            for (int i=0; i<pids.length; i++) {
9744                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9745                if (proc != null) {
9746                    int type = proc.setAdj;
9747                    types[i] = type;
9748                    if (type > worstType) {
9749                        worstType = type;
9750                    }
9751                }
9752            }
9753
9754            // If the worst oom_adj is somewhere in the cached proc LRU range,
9755            // then constrain it so we will kill all cached procs.
9756            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9757                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9758                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9759            }
9760
9761            // If this is not a secure call, don't let it kill processes that
9762            // are important.
9763            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9764                worstType = ProcessList.SERVICE_ADJ;
9765            }
9766
9767            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9768            for (int i=0; i<pids.length; i++) {
9769                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9770                if (proc == null) {
9771                    continue;
9772                }
9773                int adj = proc.setAdj;
9774                if (adj >= worstType && !proc.killedByAm) {
9775                    killUnneededProcessLocked(proc, reason);
9776                    killed = true;
9777                }
9778            }
9779        }
9780        return killed;
9781    }
9782
9783    @Override
9784    public void killUid(int uid, String reason) {
9785        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9786            throw new SecurityException("killUid only available to the system");
9787        }
9788        synchronized (this) {
9789            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9790                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9791                    reason != null ? reason : "kill uid");
9792        }
9793    }
9794
9795    @Override
9796    public boolean killProcessesBelowForeground(String reason) {
9797        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9798            throw new SecurityException("killProcessesBelowForeground() only available to system");
9799        }
9800
9801        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9802    }
9803
9804    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9805        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9806            throw new SecurityException("killProcessesBelowAdj() only available to system");
9807        }
9808
9809        boolean killed = false;
9810        synchronized (mPidsSelfLocked) {
9811            final int size = mPidsSelfLocked.size();
9812            for (int i = 0; i < size; i++) {
9813                final int pid = mPidsSelfLocked.keyAt(i);
9814                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9815                if (proc == null) continue;
9816
9817                final int adj = proc.setAdj;
9818                if (adj > belowAdj && !proc.killedByAm) {
9819                    killUnneededProcessLocked(proc, reason);
9820                    killed = true;
9821                }
9822            }
9823        }
9824        return killed;
9825    }
9826
9827    @Override
9828    public void hang(final IBinder who, boolean allowRestart) {
9829        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9830                != PackageManager.PERMISSION_GRANTED) {
9831            throw new SecurityException("Requires permission "
9832                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9833        }
9834
9835        final IBinder.DeathRecipient death = new DeathRecipient() {
9836            @Override
9837            public void binderDied() {
9838                synchronized (this) {
9839                    notifyAll();
9840                }
9841            }
9842        };
9843
9844        try {
9845            who.linkToDeath(death, 0);
9846        } catch (RemoteException e) {
9847            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9848            return;
9849        }
9850
9851        synchronized (this) {
9852            Watchdog.getInstance().setAllowRestart(allowRestart);
9853            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9854            synchronized (death) {
9855                while (who.isBinderAlive()) {
9856                    try {
9857                        death.wait();
9858                    } catch (InterruptedException e) {
9859                    }
9860                }
9861            }
9862            Watchdog.getInstance().setAllowRestart(true);
9863        }
9864    }
9865
9866    @Override
9867    public void restart() {
9868        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9869                != PackageManager.PERMISSION_GRANTED) {
9870            throw new SecurityException("Requires permission "
9871                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9872        }
9873
9874        Log.i(TAG, "Sending shutdown broadcast...");
9875
9876        BroadcastReceiver br = new BroadcastReceiver() {
9877            @Override public void onReceive(Context context, Intent intent) {
9878                // Now the broadcast is done, finish up the low-level shutdown.
9879                Log.i(TAG, "Shutting down activity manager...");
9880                shutdown(10000);
9881                Log.i(TAG, "Shutdown complete, restarting!");
9882                Process.killProcess(Process.myPid());
9883                System.exit(10);
9884            }
9885        };
9886
9887        // First send the high-level shut down broadcast.
9888        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9889        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9890        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9891        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9892        mContext.sendOrderedBroadcastAsUser(intent,
9893                UserHandle.ALL, null, br, mHandler, 0, null, null);
9894        */
9895        br.onReceive(mContext, intent);
9896    }
9897
9898    private long getLowRamTimeSinceIdle(long now) {
9899        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9900    }
9901
9902    @Override
9903    public void performIdleMaintenance() {
9904        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9905                != PackageManager.PERMISSION_GRANTED) {
9906            throw new SecurityException("Requires permission "
9907                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9908        }
9909
9910        synchronized (this) {
9911            final long now = SystemClock.uptimeMillis();
9912            final long timeSinceLastIdle = now - mLastIdleTime;
9913            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9914            mLastIdleTime = now;
9915            mLowRamTimeSinceLastIdle = 0;
9916            if (mLowRamStartTime != 0) {
9917                mLowRamStartTime = now;
9918            }
9919
9920            StringBuilder sb = new StringBuilder(128);
9921            sb.append("Idle maintenance over ");
9922            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9923            sb.append(" low RAM for ");
9924            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9925            Slog.i(TAG, sb.toString());
9926
9927            // If at least 1/3 of our time since the last idle period has been spent
9928            // with RAM low, then we want to kill processes.
9929            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9930
9931            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9932                ProcessRecord proc = mLruProcesses.get(i);
9933                if (proc.notCachedSinceIdle) {
9934                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9935                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9936                        if (doKilling && proc.initialIdlePss != 0
9937                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9938                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9939                                    + " from " + proc.initialIdlePss + ")");
9940                        }
9941                    }
9942                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9943                    proc.notCachedSinceIdle = true;
9944                    proc.initialIdlePss = 0;
9945                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9946                            isSleeping(), now);
9947                }
9948            }
9949
9950            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9951            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9952        }
9953    }
9954
9955    private void retrieveSettings() {
9956        final ContentResolver resolver = mContext.getContentResolver();
9957        String debugApp = Settings.Global.getString(
9958            resolver, Settings.Global.DEBUG_APP);
9959        boolean waitForDebugger = Settings.Global.getInt(
9960            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9961        boolean alwaysFinishActivities = Settings.Global.getInt(
9962            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9963        boolean forceRtl = Settings.Global.getInt(
9964                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9965        // Transfer any global setting for forcing RTL layout, into a System Property
9966        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9967
9968        Configuration configuration = new Configuration();
9969        Settings.System.getConfiguration(resolver, configuration);
9970        if (forceRtl) {
9971            // This will take care of setting the correct layout direction flags
9972            configuration.setLayoutDirection(configuration.locale);
9973        }
9974
9975        synchronized (this) {
9976            mDebugApp = mOrigDebugApp = debugApp;
9977            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9978            mAlwaysFinishActivities = alwaysFinishActivities;
9979            // This happens before any activities are started, so we can
9980            // change mConfiguration in-place.
9981            updateConfigurationLocked(configuration, null, false, true);
9982            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9983        }
9984    }
9985
9986    public boolean testIsSystemReady() {
9987        // no need to synchronize(this) just to read & return the value
9988        return mSystemReady;
9989    }
9990
9991    private static File getCalledPreBootReceiversFile() {
9992        File dataDir = Environment.getDataDirectory();
9993        File systemDir = new File(dataDir, "system");
9994        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
9995        return fname;
9996    }
9997
9998    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9999        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10000        File file = getCalledPreBootReceiversFile();
10001        FileInputStream fis = null;
10002        try {
10003            fis = new FileInputStream(file);
10004            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10005            int fvers = dis.readInt();
10006            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10007                String vers = dis.readUTF();
10008                String codename = dis.readUTF();
10009                String build = dis.readUTF();
10010                if (android.os.Build.VERSION.RELEASE.equals(vers)
10011                        && android.os.Build.VERSION.CODENAME.equals(codename)
10012                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10013                    int num = dis.readInt();
10014                    while (num > 0) {
10015                        num--;
10016                        String pkg = dis.readUTF();
10017                        String cls = dis.readUTF();
10018                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10019                    }
10020                }
10021            }
10022        } catch (FileNotFoundException e) {
10023        } catch (IOException e) {
10024            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10025        } finally {
10026            if (fis != null) {
10027                try {
10028                    fis.close();
10029                } catch (IOException e) {
10030                }
10031            }
10032        }
10033        return lastDoneReceivers;
10034    }
10035
10036    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10037        File file = getCalledPreBootReceiversFile();
10038        FileOutputStream fos = null;
10039        DataOutputStream dos = null;
10040        try {
10041            fos = new FileOutputStream(file);
10042            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10043            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10044            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10045            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10046            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10047            dos.writeInt(list.size());
10048            for (int i=0; i<list.size(); i++) {
10049                dos.writeUTF(list.get(i).getPackageName());
10050                dos.writeUTF(list.get(i).getClassName());
10051            }
10052        } catch (IOException e) {
10053            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10054            file.delete();
10055        } finally {
10056            FileUtils.sync(fos);
10057            if (dos != null) {
10058                try {
10059                    dos.close();
10060                } catch (IOException e) {
10061                    // TODO Auto-generated catch block
10062                    e.printStackTrace();
10063                }
10064            }
10065        }
10066    }
10067
10068    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10069            ArrayList<ComponentName> doneReceivers, int userId) {
10070        boolean waitingUpdate = false;
10071        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10072        List<ResolveInfo> ris = null;
10073        try {
10074            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10075                    intent, null, 0, userId);
10076        } catch (RemoteException e) {
10077        }
10078        if (ris != null) {
10079            for (int i=ris.size()-1; i>=0; i--) {
10080                if ((ris.get(i).activityInfo.applicationInfo.flags
10081                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10082                    ris.remove(i);
10083                }
10084            }
10085            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10086
10087            // For User 0, load the version number. When delivering to a new user, deliver
10088            // to all receivers.
10089            if (userId == UserHandle.USER_OWNER) {
10090                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10091                for (int i=0; i<ris.size(); i++) {
10092                    ActivityInfo ai = ris.get(i).activityInfo;
10093                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10094                    if (lastDoneReceivers.contains(comp)) {
10095                        // We already did the pre boot receiver for this app with the current
10096                        // platform version, so don't do it again...
10097                        ris.remove(i);
10098                        i--;
10099                        // ...however, do keep it as one that has been done, so we don't
10100                        // forget about it when rewriting the file of last done receivers.
10101                        doneReceivers.add(comp);
10102                    }
10103                }
10104            }
10105
10106            // If primary user, send broadcast to all available users, else just to userId
10107            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10108                    : new int[] { userId };
10109            for (int i = 0; i < ris.size(); i++) {
10110                ActivityInfo ai = ris.get(i).activityInfo;
10111                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10112                doneReceivers.add(comp);
10113                intent.setComponent(comp);
10114                for (int j=0; j<users.length; j++) {
10115                    IIntentReceiver finisher = null;
10116                    // On last receiver and user, set up a completion callback
10117                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10118                        finisher = new IIntentReceiver.Stub() {
10119                            public void performReceive(Intent intent, int resultCode,
10120                                    String data, Bundle extras, boolean ordered,
10121                                    boolean sticky, int sendingUser) {
10122                                // The raw IIntentReceiver interface is called
10123                                // with the AM lock held, so redispatch to
10124                                // execute our code without the lock.
10125                                mHandler.post(onFinishCallback);
10126                            }
10127                        };
10128                    }
10129                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10130                            + " for user " + users[j]);
10131                    broadcastIntentLocked(null, null, intent, null, finisher,
10132                            0, null, null, null, AppOpsManager.OP_NONE,
10133                            true, false, MY_PID, Process.SYSTEM_UID,
10134                            users[j]);
10135                    if (finisher != null) {
10136                        waitingUpdate = true;
10137                    }
10138                }
10139            }
10140        }
10141
10142        return waitingUpdate;
10143    }
10144
10145    public void systemReady(final Runnable goingCallback) {
10146        synchronized(this) {
10147            if (mSystemReady) {
10148                // If we're done calling all the receivers, run the next "boot phase" passed in
10149                // by the SystemServer
10150                if (goingCallback != null) {
10151                    goingCallback.run();
10152                }
10153                return;
10154            }
10155
10156            // Make sure we have the current profile info, since it is needed for
10157            // security checks.
10158            updateCurrentProfileIdsLocked();
10159
10160            if (mRecentTasks == null) {
10161                mRecentTasks = mTaskPersister.restoreTasksLocked();
10162                if (!mRecentTasks.isEmpty()) {
10163                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10164                }
10165                mTaskPersister.startPersisting();
10166            }
10167
10168            // Check to see if there are any update receivers to run.
10169            if (!mDidUpdate) {
10170                if (mWaitingUpdate) {
10171                    return;
10172                }
10173                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10174                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10175                    public void run() {
10176                        synchronized (ActivityManagerService.this) {
10177                            mDidUpdate = true;
10178                        }
10179                        writeLastDonePreBootReceivers(doneReceivers);
10180                        showBootMessage(mContext.getText(
10181                                R.string.android_upgrading_complete),
10182                                false);
10183                        systemReady(goingCallback);
10184                    }
10185                }, doneReceivers, UserHandle.USER_OWNER);
10186
10187                if (mWaitingUpdate) {
10188                    return;
10189                }
10190                mDidUpdate = true;
10191            }
10192
10193            mAppOpsService.systemReady();
10194            mSystemReady = true;
10195        }
10196
10197        ArrayList<ProcessRecord> procsToKill = null;
10198        synchronized(mPidsSelfLocked) {
10199            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10200                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10201                if (!isAllowedWhileBooting(proc.info)){
10202                    if (procsToKill == null) {
10203                        procsToKill = new ArrayList<ProcessRecord>();
10204                    }
10205                    procsToKill.add(proc);
10206                }
10207            }
10208        }
10209
10210        synchronized(this) {
10211            if (procsToKill != null) {
10212                for (int i=procsToKill.size()-1; i>=0; i--) {
10213                    ProcessRecord proc = procsToKill.get(i);
10214                    Slog.i(TAG, "Removing system update proc: " + proc);
10215                    removeProcessLocked(proc, true, false, "system update done");
10216                }
10217            }
10218
10219            // Now that we have cleaned up any update processes, we
10220            // are ready to start launching real processes and know that
10221            // we won't trample on them any more.
10222            mProcessesReady = true;
10223        }
10224
10225        Slog.i(TAG, "System now ready");
10226        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10227            SystemClock.uptimeMillis());
10228
10229        synchronized(this) {
10230            // Make sure we have no pre-ready processes sitting around.
10231
10232            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10233                ResolveInfo ri = mContext.getPackageManager()
10234                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10235                                STOCK_PM_FLAGS);
10236                CharSequence errorMsg = null;
10237                if (ri != null) {
10238                    ActivityInfo ai = ri.activityInfo;
10239                    ApplicationInfo app = ai.applicationInfo;
10240                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10241                        mTopAction = Intent.ACTION_FACTORY_TEST;
10242                        mTopData = null;
10243                        mTopComponent = new ComponentName(app.packageName,
10244                                ai.name);
10245                    } else {
10246                        errorMsg = mContext.getResources().getText(
10247                                com.android.internal.R.string.factorytest_not_system);
10248                    }
10249                } else {
10250                    errorMsg = mContext.getResources().getText(
10251                            com.android.internal.R.string.factorytest_no_action);
10252                }
10253                if (errorMsg != null) {
10254                    mTopAction = null;
10255                    mTopData = null;
10256                    mTopComponent = null;
10257                    Message msg = Message.obtain();
10258                    msg.what = SHOW_FACTORY_ERROR_MSG;
10259                    msg.getData().putCharSequence("msg", errorMsg);
10260                    mHandler.sendMessage(msg);
10261                }
10262            }
10263        }
10264
10265        retrieveSettings();
10266
10267        synchronized (this) {
10268            readGrantedUriPermissionsLocked();
10269        }
10270
10271        if (goingCallback != null) goingCallback.run();
10272
10273        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10274                Integer.toString(mCurrentUserId), mCurrentUserId);
10275        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10276                Integer.toString(mCurrentUserId), mCurrentUserId);
10277        mSystemServiceManager.startUser(mCurrentUserId);
10278
10279        synchronized (this) {
10280            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10281                try {
10282                    List apps = AppGlobals.getPackageManager().
10283                        getPersistentApplications(STOCK_PM_FLAGS);
10284                    if (apps != null) {
10285                        int N = apps.size();
10286                        int i;
10287                        for (i=0; i<N; i++) {
10288                            ApplicationInfo info
10289                                = (ApplicationInfo)apps.get(i);
10290                            if (info != null &&
10291                                    !info.packageName.equals("android")) {
10292                                addAppLocked(info, false, null /* ABI override */);
10293                            }
10294                        }
10295                    }
10296                } catch (RemoteException ex) {
10297                    // pm is in same process, this will never happen.
10298                }
10299            }
10300
10301            // Start up initial activity.
10302            mBooting = true;
10303
10304            try {
10305                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10306                    Message msg = Message.obtain();
10307                    msg.what = SHOW_UID_ERROR_MSG;
10308                    mHandler.sendMessage(msg);
10309                }
10310            } catch (RemoteException e) {
10311            }
10312
10313            long ident = Binder.clearCallingIdentity();
10314            try {
10315                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10316                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10317                        | Intent.FLAG_RECEIVER_FOREGROUND);
10318                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10319                broadcastIntentLocked(null, null, intent,
10320                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10321                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10322                intent = new Intent(Intent.ACTION_USER_STARTING);
10323                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10324                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10325                broadcastIntentLocked(null, null, intent,
10326                        null, new IIntentReceiver.Stub() {
10327                            @Override
10328                            public void performReceive(Intent intent, int resultCode, String data,
10329                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10330                                    throws RemoteException {
10331                            }
10332                        }, 0, null, null,
10333                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10334                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10335            } catch (Throwable t) {
10336                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10337            } finally {
10338                Binder.restoreCallingIdentity(ident);
10339            }
10340            mStackSupervisor.resumeTopActivitiesLocked();
10341            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10342        }
10343    }
10344
10345    private boolean makeAppCrashingLocked(ProcessRecord app,
10346            String shortMsg, String longMsg, String stackTrace) {
10347        app.crashing = true;
10348        app.crashingReport = generateProcessError(app,
10349                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10350        startAppProblemLocked(app);
10351        app.stopFreezingAllLocked();
10352        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10353    }
10354
10355    private void makeAppNotRespondingLocked(ProcessRecord app,
10356            String activity, String shortMsg, String longMsg) {
10357        app.notResponding = true;
10358        app.notRespondingReport = generateProcessError(app,
10359                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10360                activity, shortMsg, longMsg, null);
10361        startAppProblemLocked(app);
10362        app.stopFreezingAllLocked();
10363    }
10364
10365    /**
10366     * Generate a process error record, suitable for attachment to a ProcessRecord.
10367     *
10368     * @param app The ProcessRecord in which the error occurred.
10369     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10370     *                      ActivityManager.AppErrorStateInfo
10371     * @param activity The activity associated with the crash, if known.
10372     * @param shortMsg Short message describing the crash.
10373     * @param longMsg Long message describing the crash.
10374     * @param stackTrace Full crash stack trace, may be null.
10375     *
10376     * @return Returns a fully-formed AppErrorStateInfo record.
10377     */
10378    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10379            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10380        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10381
10382        report.condition = condition;
10383        report.processName = app.processName;
10384        report.pid = app.pid;
10385        report.uid = app.info.uid;
10386        report.tag = activity;
10387        report.shortMsg = shortMsg;
10388        report.longMsg = longMsg;
10389        report.stackTrace = stackTrace;
10390
10391        return report;
10392    }
10393
10394    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10395        synchronized (this) {
10396            app.crashing = false;
10397            app.crashingReport = null;
10398            app.notResponding = false;
10399            app.notRespondingReport = null;
10400            if (app.anrDialog == fromDialog) {
10401                app.anrDialog = null;
10402            }
10403            if (app.waitDialog == fromDialog) {
10404                app.waitDialog = null;
10405            }
10406            if (app.pid > 0 && app.pid != MY_PID) {
10407                handleAppCrashLocked(app, null, null, null);
10408                killUnneededProcessLocked(app, "user request after error");
10409            }
10410        }
10411    }
10412
10413    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10414            String stackTrace) {
10415        long now = SystemClock.uptimeMillis();
10416
10417        Long crashTime;
10418        if (!app.isolated) {
10419            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10420        } else {
10421            crashTime = null;
10422        }
10423        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10424            // This process loses!
10425            Slog.w(TAG, "Process " + app.info.processName
10426                    + " has crashed too many times: killing!");
10427            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10428                    app.userId, app.info.processName, app.uid);
10429            mStackSupervisor.handleAppCrashLocked(app);
10430            if (!app.persistent) {
10431                // We don't want to start this process again until the user
10432                // explicitly does so...  but for persistent process, we really
10433                // need to keep it running.  If a persistent process is actually
10434                // repeatedly crashing, then badness for everyone.
10435                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10436                        app.info.processName);
10437                if (!app.isolated) {
10438                    // XXX We don't have a way to mark isolated processes
10439                    // as bad, since they don't have a peristent identity.
10440                    mBadProcesses.put(app.info.processName, app.uid,
10441                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10442                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10443                }
10444                app.bad = true;
10445                app.removed = true;
10446                // Don't let services in this process be restarted and potentially
10447                // annoy the user repeatedly.  Unless it is persistent, since those
10448                // processes run critical code.
10449                removeProcessLocked(app, false, false, "crash");
10450                mStackSupervisor.resumeTopActivitiesLocked();
10451                return false;
10452            }
10453            mStackSupervisor.resumeTopActivitiesLocked();
10454        } else {
10455            mStackSupervisor.finishTopRunningActivityLocked(app);
10456        }
10457
10458        // Bump up the crash count of any services currently running in the proc.
10459        for (int i=app.services.size()-1; i>=0; i--) {
10460            // Any services running in the application need to be placed
10461            // back in the pending list.
10462            ServiceRecord sr = app.services.valueAt(i);
10463            sr.crashCount++;
10464        }
10465
10466        // If the crashing process is what we consider to be the "home process" and it has been
10467        // replaced by a third-party app, clear the package preferred activities from packages
10468        // with a home activity running in the process to prevent a repeatedly crashing app
10469        // from blocking the user to manually clear the list.
10470        final ArrayList<ActivityRecord> activities = app.activities;
10471        if (app == mHomeProcess && activities.size() > 0
10472                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10473            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10474                final ActivityRecord r = activities.get(activityNdx);
10475                if (r.isHomeActivity()) {
10476                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10477                    try {
10478                        ActivityThread.getPackageManager()
10479                                .clearPackagePreferredActivities(r.packageName);
10480                    } catch (RemoteException c) {
10481                        // pm is in same process, this will never happen.
10482                    }
10483                }
10484            }
10485        }
10486
10487        if (!app.isolated) {
10488            // XXX Can't keep track of crash times for isolated processes,
10489            // because they don't have a perisistent identity.
10490            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10491        }
10492
10493        return true;
10494    }
10495
10496    void startAppProblemLocked(ProcessRecord app) {
10497        if (app.userId == mCurrentUserId) {
10498            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10499                    mContext, app.info.packageName, app.info.flags);
10500        } else {
10501            // If this app is not running under the current user, then we
10502            // can't give it a report button because that would require
10503            // launching the report UI under a different user.
10504            app.errorReportReceiver = null;
10505        }
10506        skipCurrentReceiverLocked(app);
10507    }
10508
10509    void skipCurrentReceiverLocked(ProcessRecord app) {
10510        for (BroadcastQueue queue : mBroadcastQueues) {
10511            queue.skipCurrentReceiverLocked(app);
10512        }
10513    }
10514
10515    /**
10516     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10517     * The application process will exit immediately after this call returns.
10518     * @param app object of the crashing app, null for the system server
10519     * @param crashInfo describing the exception
10520     */
10521    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10522        ProcessRecord r = findAppProcess(app, "Crash");
10523        final String processName = app == null ? "system_server"
10524                : (r == null ? "unknown" : r.processName);
10525
10526        handleApplicationCrashInner("crash", r, processName, crashInfo);
10527    }
10528
10529    /* Native crash reporting uses this inner version because it needs to be somewhat
10530     * decoupled from the AM-managed cleanup lifecycle
10531     */
10532    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10533            ApplicationErrorReport.CrashInfo crashInfo) {
10534        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10535                UserHandle.getUserId(Binder.getCallingUid()), processName,
10536                r == null ? -1 : r.info.flags,
10537                crashInfo.exceptionClassName,
10538                crashInfo.exceptionMessage,
10539                crashInfo.throwFileName,
10540                crashInfo.throwLineNumber);
10541
10542        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10543
10544        crashApplication(r, crashInfo);
10545    }
10546
10547    public void handleApplicationStrictModeViolation(
10548            IBinder app,
10549            int violationMask,
10550            StrictMode.ViolationInfo info) {
10551        ProcessRecord r = findAppProcess(app, "StrictMode");
10552        if (r == null) {
10553            return;
10554        }
10555
10556        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10557            Integer stackFingerprint = info.hashCode();
10558            boolean logIt = true;
10559            synchronized (mAlreadyLoggedViolatedStacks) {
10560                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10561                    logIt = false;
10562                    // TODO: sub-sample into EventLog for these, with
10563                    // the info.durationMillis?  Then we'd get
10564                    // the relative pain numbers, without logging all
10565                    // the stack traces repeatedly.  We'd want to do
10566                    // likewise in the client code, which also does
10567                    // dup suppression, before the Binder call.
10568                } else {
10569                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10570                        mAlreadyLoggedViolatedStacks.clear();
10571                    }
10572                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10573                }
10574            }
10575            if (logIt) {
10576                logStrictModeViolationToDropBox(r, info);
10577            }
10578        }
10579
10580        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10581            AppErrorResult result = new AppErrorResult();
10582            synchronized (this) {
10583                final long origId = Binder.clearCallingIdentity();
10584
10585                Message msg = Message.obtain();
10586                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10587                HashMap<String, Object> data = new HashMap<String, Object>();
10588                data.put("result", result);
10589                data.put("app", r);
10590                data.put("violationMask", violationMask);
10591                data.put("info", info);
10592                msg.obj = data;
10593                mHandler.sendMessage(msg);
10594
10595                Binder.restoreCallingIdentity(origId);
10596            }
10597            int res = result.get();
10598            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10599        }
10600    }
10601
10602    // Depending on the policy in effect, there could be a bunch of
10603    // these in quick succession so we try to batch these together to
10604    // minimize disk writes, number of dropbox entries, and maximize
10605    // compression, by having more fewer, larger records.
10606    private void logStrictModeViolationToDropBox(
10607            ProcessRecord process,
10608            StrictMode.ViolationInfo info) {
10609        if (info == null) {
10610            return;
10611        }
10612        final boolean isSystemApp = process == null ||
10613                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10614                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10615        final String processName = process == null ? "unknown" : process.processName;
10616        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10617        final DropBoxManager dbox = (DropBoxManager)
10618                mContext.getSystemService(Context.DROPBOX_SERVICE);
10619
10620        // Exit early if the dropbox isn't configured to accept this report type.
10621        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10622
10623        boolean bufferWasEmpty;
10624        boolean needsFlush;
10625        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10626        synchronized (sb) {
10627            bufferWasEmpty = sb.length() == 0;
10628            appendDropBoxProcessHeaders(process, processName, sb);
10629            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10630            sb.append("System-App: ").append(isSystemApp).append("\n");
10631            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10632            if (info.violationNumThisLoop != 0) {
10633                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10634            }
10635            if (info.numAnimationsRunning != 0) {
10636                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10637            }
10638            if (info.broadcastIntentAction != null) {
10639                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10640            }
10641            if (info.durationMillis != -1) {
10642                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10643            }
10644            if (info.numInstances != -1) {
10645                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10646            }
10647            if (info.tags != null) {
10648                for (String tag : info.tags) {
10649                    sb.append("Span-Tag: ").append(tag).append("\n");
10650                }
10651            }
10652            sb.append("\n");
10653            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10654                sb.append(info.crashInfo.stackTrace);
10655            }
10656            sb.append("\n");
10657
10658            // Only buffer up to ~64k.  Various logging bits truncate
10659            // things at 128k.
10660            needsFlush = (sb.length() > 64 * 1024);
10661        }
10662
10663        // Flush immediately if the buffer's grown too large, or this
10664        // is a non-system app.  Non-system apps are isolated with a
10665        // different tag & policy and not batched.
10666        //
10667        // Batching is useful during internal testing with
10668        // StrictMode settings turned up high.  Without batching,
10669        // thousands of separate files could be created on boot.
10670        if (!isSystemApp || needsFlush) {
10671            new Thread("Error dump: " + dropboxTag) {
10672                @Override
10673                public void run() {
10674                    String report;
10675                    synchronized (sb) {
10676                        report = sb.toString();
10677                        sb.delete(0, sb.length());
10678                        sb.trimToSize();
10679                    }
10680                    if (report.length() != 0) {
10681                        dbox.addText(dropboxTag, report);
10682                    }
10683                }
10684            }.start();
10685            return;
10686        }
10687
10688        // System app batching:
10689        if (!bufferWasEmpty) {
10690            // An existing dropbox-writing thread is outstanding, so
10691            // we don't need to start it up.  The existing thread will
10692            // catch the buffer appends we just did.
10693            return;
10694        }
10695
10696        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10697        // (After this point, we shouldn't access AMS internal data structures.)
10698        new Thread("Error dump: " + dropboxTag) {
10699            @Override
10700            public void run() {
10701                // 5 second sleep to let stacks arrive and be batched together
10702                try {
10703                    Thread.sleep(5000);  // 5 seconds
10704                } catch (InterruptedException e) {}
10705
10706                String errorReport;
10707                synchronized (mStrictModeBuffer) {
10708                    errorReport = mStrictModeBuffer.toString();
10709                    if (errorReport.length() == 0) {
10710                        return;
10711                    }
10712                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10713                    mStrictModeBuffer.trimToSize();
10714                }
10715                dbox.addText(dropboxTag, errorReport);
10716            }
10717        }.start();
10718    }
10719
10720    /**
10721     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10722     * @param app object of the crashing app, null for the system server
10723     * @param tag reported by the caller
10724     * @param crashInfo describing the context of the error
10725     * @return true if the process should exit immediately (WTF is fatal)
10726     */
10727    public boolean handleApplicationWtf(IBinder app, String tag,
10728            ApplicationErrorReport.CrashInfo crashInfo) {
10729        ProcessRecord r = findAppProcess(app, "WTF");
10730        final String processName = app == null ? "system_server"
10731                : (r == null ? "unknown" : r.processName);
10732
10733        EventLog.writeEvent(EventLogTags.AM_WTF,
10734                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10735                processName,
10736                r == null ? -1 : r.info.flags,
10737                tag, crashInfo.exceptionMessage);
10738
10739        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10740
10741        if (r != null && r.pid != Process.myPid() &&
10742                Settings.Global.getInt(mContext.getContentResolver(),
10743                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10744            crashApplication(r, crashInfo);
10745            return true;
10746        } else {
10747            return false;
10748        }
10749    }
10750
10751    /**
10752     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10753     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10754     */
10755    private ProcessRecord findAppProcess(IBinder app, String reason) {
10756        if (app == null) {
10757            return null;
10758        }
10759
10760        synchronized (this) {
10761            final int NP = mProcessNames.getMap().size();
10762            for (int ip=0; ip<NP; ip++) {
10763                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10764                final int NA = apps.size();
10765                for (int ia=0; ia<NA; ia++) {
10766                    ProcessRecord p = apps.valueAt(ia);
10767                    if (p.thread != null && p.thread.asBinder() == app) {
10768                        return p;
10769                    }
10770                }
10771            }
10772
10773            Slog.w(TAG, "Can't find mystery application for " + reason
10774                    + " from pid=" + Binder.getCallingPid()
10775                    + " uid=" + Binder.getCallingUid() + ": " + app);
10776            return null;
10777        }
10778    }
10779
10780    /**
10781     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10782     * to append various headers to the dropbox log text.
10783     */
10784    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10785            StringBuilder sb) {
10786        // Watchdog thread ends up invoking this function (with
10787        // a null ProcessRecord) to add the stack file to dropbox.
10788        // Do not acquire a lock on this (am) in such cases, as it
10789        // could cause a potential deadlock, if and when watchdog
10790        // is invoked due to unavailability of lock on am and it
10791        // would prevent watchdog from killing system_server.
10792        if (process == null) {
10793            sb.append("Process: ").append(processName).append("\n");
10794            return;
10795        }
10796        // Note: ProcessRecord 'process' is guarded by the service
10797        // instance.  (notably process.pkgList, which could otherwise change
10798        // concurrently during execution of this method)
10799        synchronized (this) {
10800            sb.append("Process: ").append(processName).append("\n");
10801            int flags = process.info.flags;
10802            IPackageManager pm = AppGlobals.getPackageManager();
10803            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10804            for (int ip=0; ip<process.pkgList.size(); ip++) {
10805                String pkg = process.pkgList.keyAt(ip);
10806                sb.append("Package: ").append(pkg);
10807                try {
10808                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10809                    if (pi != null) {
10810                        sb.append(" v").append(pi.versionCode);
10811                        if (pi.versionName != null) {
10812                            sb.append(" (").append(pi.versionName).append(")");
10813                        }
10814                    }
10815                } catch (RemoteException e) {
10816                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10817                }
10818                sb.append("\n");
10819            }
10820        }
10821    }
10822
10823    private static String processClass(ProcessRecord process) {
10824        if (process == null || process.pid == MY_PID) {
10825            return "system_server";
10826        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10827            return "system_app";
10828        } else {
10829            return "data_app";
10830        }
10831    }
10832
10833    /**
10834     * Write a description of an error (crash, WTF, ANR) to the drop box.
10835     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10836     * @param process which caused the error, null means the system server
10837     * @param activity which triggered the error, null if unknown
10838     * @param parent activity related to the error, null if unknown
10839     * @param subject line related to the error, null if absent
10840     * @param report in long form describing the error, null if absent
10841     * @param logFile to include in the report, null if none
10842     * @param crashInfo giving an application stack trace, null if absent
10843     */
10844    public void addErrorToDropBox(String eventType,
10845            ProcessRecord process, String processName, ActivityRecord activity,
10846            ActivityRecord parent, String subject,
10847            final String report, final File logFile,
10848            final ApplicationErrorReport.CrashInfo crashInfo) {
10849        // NOTE -- this must never acquire the ActivityManagerService lock,
10850        // otherwise the watchdog may be prevented from resetting the system.
10851
10852        final String dropboxTag = processClass(process) + "_" + eventType;
10853        final DropBoxManager dbox = (DropBoxManager)
10854                mContext.getSystemService(Context.DROPBOX_SERVICE);
10855
10856        // Exit early if the dropbox isn't configured to accept this report type.
10857        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10858
10859        final StringBuilder sb = new StringBuilder(1024);
10860        appendDropBoxProcessHeaders(process, processName, sb);
10861        if (activity != null) {
10862            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10863        }
10864        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10865            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10866        }
10867        if (parent != null && parent != activity) {
10868            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10869        }
10870        if (subject != null) {
10871            sb.append("Subject: ").append(subject).append("\n");
10872        }
10873        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10874        if (Debug.isDebuggerConnected()) {
10875            sb.append("Debugger: Connected\n");
10876        }
10877        sb.append("\n");
10878
10879        // Do the rest in a worker thread to avoid blocking the caller on I/O
10880        // (After this point, we shouldn't access AMS internal data structures.)
10881        Thread worker = new Thread("Error dump: " + dropboxTag) {
10882            @Override
10883            public void run() {
10884                if (report != null) {
10885                    sb.append(report);
10886                }
10887                if (logFile != null) {
10888                    try {
10889                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10890                                    "\n\n[[TRUNCATED]]"));
10891                    } catch (IOException e) {
10892                        Slog.e(TAG, "Error reading " + logFile, e);
10893                    }
10894                }
10895                if (crashInfo != null && crashInfo.stackTrace != null) {
10896                    sb.append(crashInfo.stackTrace);
10897                }
10898
10899                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10900                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10901                if (lines > 0) {
10902                    sb.append("\n");
10903
10904                    // Merge several logcat streams, and take the last N lines
10905                    InputStreamReader input = null;
10906                    try {
10907                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10908                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10909                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10910
10911                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10912                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10913                        input = new InputStreamReader(logcat.getInputStream());
10914
10915                        int num;
10916                        char[] buf = new char[8192];
10917                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10918                    } catch (IOException e) {
10919                        Slog.e(TAG, "Error running logcat", e);
10920                    } finally {
10921                        if (input != null) try { input.close(); } catch (IOException e) {}
10922                    }
10923                }
10924
10925                dbox.addText(dropboxTag, sb.toString());
10926            }
10927        };
10928
10929        if (process == null) {
10930            // If process is null, we are being called from some internal code
10931            // and may be about to die -- run this synchronously.
10932            worker.run();
10933        } else {
10934            worker.start();
10935        }
10936    }
10937
10938    /**
10939     * Bring up the "unexpected error" dialog box for a crashing app.
10940     * Deal with edge cases (intercepts from instrumented applications,
10941     * ActivityController, error intent receivers, that sort of thing).
10942     * @param r the application crashing
10943     * @param crashInfo describing the failure
10944     */
10945    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10946        long timeMillis = System.currentTimeMillis();
10947        String shortMsg = crashInfo.exceptionClassName;
10948        String longMsg = crashInfo.exceptionMessage;
10949        String stackTrace = crashInfo.stackTrace;
10950        if (shortMsg != null && longMsg != null) {
10951            longMsg = shortMsg + ": " + longMsg;
10952        } else if (shortMsg != null) {
10953            longMsg = shortMsg;
10954        }
10955
10956        AppErrorResult result = new AppErrorResult();
10957        synchronized (this) {
10958            if (mController != null) {
10959                try {
10960                    String name = r != null ? r.processName : null;
10961                    int pid = r != null ? r.pid : Binder.getCallingPid();
10962                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10963                    if (!mController.appCrashed(name, pid,
10964                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10965                        Slog.w(TAG, "Force-killing crashed app " + name
10966                                + " at watcher's request");
10967                        Process.killProcess(pid);
10968                        if (r != null) {
10969                            Process.killProcessGroup(uid, pid);
10970                        }
10971                        return;
10972                    }
10973                } catch (RemoteException e) {
10974                    mController = null;
10975                    Watchdog.getInstance().setActivityController(null);
10976                }
10977            }
10978
10979            final long origId = Binder.clearCallingIdentity();
10980
10981            // If this process is running instrumentation, finish it.
10982            if (r != null && r.instrumentationClass != null) {
10983                Slog.w(TAG, "Error in app " + r.processName
10984                      + " running instrumentation " + r.instrumentationClass + ":");
10985                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10986                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10987                Bundle info = new Bundle();
10988                info.putString("shortMsg", shortMsg);
10989                info.putString("longMsg", longMsg);
10990                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10991                Binder.restoreCallingIdentity(origId);
10992                return;
10993            }
10994
10995            // If we can't identify the process or it's already exceeded its crash quota,
10996            // quit right away without showing a crash dialog.
10997            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10998                Binder.restoreCallingIdentity(origId);
10999                return;
11000            }
11001
11002            Message msg = Message.obtain();
11003            msg.what = SHOW_ERROR_MSG;
11004            HashMap data = new HashMap();
11005            data.put("result", result);
11006            data.put("app", r);
11007            msg.obj = data;
11008            mHandler.sendMessage(msg);
11009
11010            Binder.restoreCallingIdentity(origId);
11011        }
11012
11013        int res = result.get();
11014
11015        Intent appErrorIntent = null;
11016        synchronized (this) {
11017            if (r != null && !r.isolated) {
11018                // XXX Can't keep track of crash time for isolated processes,
11019                // since they don't have a persistent identity.
11020                mProcessCrashTimes.put(r.info.processName, r.uid,
11021                        SystemClock.uptimeMillis());
11022            }
11023            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11024                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11025            }
11026        }
11027
11028        if (appErrorIntent != null) {
11029            try {
11030                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11031            } catch (ActivityNotFoundException e) {
11032                Slog.w(TAG, "bug report receiver dissappeared", e);
11033            }
11034        }
11035    }
11036
11037    Intent createAppErrorIntentLocked(ProcessRecord r,
11038            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11039        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11040        if (report == null) {
11041            return null;
11042        }
11043        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11044        result.setComponent(r.errorReportReceiver);
11045        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11046        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11047        return result;
11048    }
11049
11050    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11051            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11052        if (r.errorReportReceiver == null) {
11053            return null;
11054        }
11055
11056        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11057            return null;
11058        }
11059
11060        ApplicationErrorReport report = new ApplicationErrorReport();
11061        report.packageName = r.info.packageName;
11062        report.installerPackageName = r.errorReportReceiver.getPackageName();
11063        report.processName = r.processName;
11064        report.time = timeMillis;
11065        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11066
11067        if (r.crashing || r.forceCrashReport) {
11068            report.type = ApplicationErrorReport.TYPE_CRASH;
11069            report.crashInfo = crashInfo;
11070        } else if (r.notResponding) {
11071            report.type = ApplicationErrorReport.TYPE_ANR;
11072            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11073
11074            report.anrInfo.activity = r.notRespondingReport.tag;
11075            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11076            report.anrInfo.info = r.notRespondingReport.longMsg;
11077        }
11078
11079        return report;
11080    }
11081
11082    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11083        enforceNotIsolatedCaller("getProcessesInErrorState");
11084        // assume our apps are happy - lazy create the list
11085        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11086
11087        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11088                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11089        int userId = UserHandle.getUserId(Binder.getCallingUid());
11090
11091        synchronized (this) {
11092
11093            // iterate across all processes
11094            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11095                ProcessRecord app = mLruProcesses.get(i);
11096                if (!allUsers && app.userId != userId) {
11097                    continue;
11098                }
11099                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11100                    // This one's in trouble, so we'll generate a report for it
11101                    // crashes are higher priority (in case there's a crash *and* an anr)
11102                    ActivityManager.ProcessErrorStateInfo report = null;
11103                    if (app.crashing) {
11104                        report = app.crashingReport;
11105                    } else if (app.notResponding) {
11106                        report = app.notRespondingReport;
11107                    }
11108
11109                    if (report != null) {
11110                        if (errList == null) {
11111                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11112                        }
11113                        errList.add(report);
11114                    } else {
11115                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11116                                " crashing = " + app.crashing +
11117                                " notResponding = " + app.notResponding);
11118                    }
11119                }
11120            }
11121        }
11122
11123        return errList;
11124    }
11125
11126    static int procStateToImportance(int procState, int memAdj,
11127            ActivityManager.RunningAppProcessInfo currApp) {
11128        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11129        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11130            currApp.lru = memAdj;
11131        } else {
11132            currApp.lru = 0;
11133        }
11134        return imp;
11135    }
11136
11137    private void fillInProcMemInfo(ProcessRecord app,
11138            ActivityManager.RunningAppProcessInfo outInfo) {
11139        outInfo.pid = app.pid;
11140        outInfo.uid = app.info.uid;
11141        if (mHeavyWeightProcess == app) {
11142            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11143        }
11144        if (app.persistent) {
11145            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11146        }
11147        if (app.activities.size() > 0) {
11148            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11149        }
11150        outInfo.lastTrimLevel = app.trimMemoryLevel;
11151        int adj = app.curAdj;
11152        int procState = app.curProcState;
11153        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11154        outInfo.importanceReasonCode = app.adjTypeCode;
11155        outInfo.processState = app.curProcState;
11156    }
11157
11158    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11159        enforceNotIsolatedCaller("getRunningAppProcesses");
11160        // Lazy instantiation of list
11161        List<ActivityManager.RunningAppProcessInfo> runList = null;
11162        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11163                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11164        int userId = UserHandle.getUserId(Binder.getCallingUid());
11165        synchronized (this) {
11166            // Iterate across all processes
11167            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11168                ProcessRecord app = mLruProcesses.get(i);
11169                if (!allUsers && app.userId != userId) {
11170                    continue;
11171                }
11172                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11173                    // Generate process state info for running application
11174                    ActivityManager.RunningAppProcessInfo currApp =
11175                        new ActivityManager.RunningAppProcessInfo(app.processName,
11176                                app.pid, app.getPackageList());
11177                    fillInProcMemInfo(app, currApp);
11178                    if (app.adjSource instanceof ProcessRecord) {
11179                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11180                        currApp.importanceReasonImportance =
11181                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11182                                        app.adjSourceProcState);
11183                    } else if (app.adjSource instanceof ActivityRecord) {
11184                        ActivityRecord r = (ActivityRecord)app.adjSource;
11185                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11186                    }
11187                    if (app.adjTarget instanceof ComponentName) {
11188                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11189                    }
11190                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11191                    //        + " lru=" + currApp.lru);
11192                    if (runList == null) {
11193                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11194                    }
11195                    runList.add(currApp);
11196                }
11197            }
11198        }
11199        return runList;
11200    }
11201
11202    public List<ApplicationInfo> getRunningExternalApplications() {
11203        enforceNotIsolatedCaller("getRunningExternalApplications");
11204        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11205        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11206        if (runningApps != null && runningApps.size() > 0) {
11207            Set<String> extList = new HashSet<String>();
11208            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11209                if (app.pkgList != null) {
11210                    for (String pkg : app.pkgList) {
11211                        extList.add(pkg);
11212                    }
11213                }
11214            }
11215            IPackageManager pm = AppGlobals.getPackageManager();
11216            for (String pkg : extList) {
11217                try {
11218                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11219                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11220                        retList.add(info);
11221                    }
11222                } catch (RemoteException e) {
11223                }
11224            }
11225        }
11226        return retList;
11227    }
11228
11229    @Override
11230    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11231        enforceNotIsolatedCaller("getMyMemoryState");
11232        synchronized (this) {
11233            ProcessRecord proc;
11234            synchronized (mPidsSelfLocked) {
11235                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11236            }
11237            fillInProcMemInfo(proc, outInfo);
11238        }
11239    }
11240
11241    @Override
11242    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11243        if (checkCallingPermission(android.Manifest.permission.DUMP)
11244                != PackageManager.PERMISSION_GRANTED) {
11245            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11246                    + Binder.getCallingPid()
11247                    + ", uid=" + Binder.getCallingUid()
11248                    + " without permission "
11249                    + android.Manifest.permission.DUMP);
11250            return;
11251        }
11252
11253        boolean dumpAll = false;
11254        boolean dumpClient = false;
11255        String dumpPackage = null;
11256
11257        int opti = 0;
11258        while (opti < args.length) {
11259            String opt = args[opti];
11260            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11261                break;
11262            }
11263            opti++;
11264            if ("-a".equals(opt)) {
11265                dumpAll = true;
11266            } else if ("-c".equals(opt)) {
11267                dumpClient = true;
11268            } else if ("-h".equals(opt)) {
11269                pw.println("Activity manager dump options:");
11270                pw.println("  [-a] [-c] [-h] [cmd] ...");
11271                pw.println("  cmd may be one of:");
11272                pw.println("    a[ctivities]: activity stack state");
11273                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11274                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11275                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11276                pw.println("    o[om]: out of memory management");
11277                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11278                pw.println("    provider [COMP_SPEC]: provider client-side state");
11279                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11280                pw.println("    service [COMP_SPEC]: service client-side state");
11281                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11282                pw.println("    all: dump all activities");
11283                pw.println("    top: dump the top activity");
11284                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11285                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11286                pw.println("    a partial substring in a component name, a");
11287                pw.println("    hex object identifier.");
11288                pw.println("  -a: include all available server state.");
11289                pw.println("  -c: include client state.");
11290                return;
11291            } else {
11292                pw.println("Unknown argument: " + opt + "; use -h for help");
11293            }
11294        }
11295
11296        long origId = Binder.clearCallingIdentity();
11297        boolean more = false;
11298        // Is the caller requesting to dump a particular piece of data?
11299        if (opti < args.length) {
11300            String cmd = args[opti];
11301            opti++;
11302            if ("activities".equals(cmd) || "a".equals(cmd)) {
11303                synchronized (this) {
11304                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11305                }
11306            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11307                String[] newArgs;
11308                String name;
11309                if (opti >= args.length) {
11310                    name = null;
11311                    newArgs = EMPTY_STRING_ARRAY;
11312                } else {
11313                    name = args[opti];
11314                    opti++;
11315                    newArgs = new String[args.length - opti];
11316                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11317                            args.length - opti);
11318                }
11319                synchronized (this) {
11320                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11321                }
11322            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11323                String[] newArgs;
11324                String name;
11325                if (opti >= args.length) {
11326                    name = null;
11327                    newArgs = EMPTY_STRING_ARRAY;
11328                } else {
11329                    name = args[opti];
11330                    opti++;
11331                    newArgs = new String[args.length - opti];
11332                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11333                            args.length - opti);
11334                }
11335                synchronized (this) {
11336                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11337                }
11338            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11339                String[] newArgs;
11340                String name;
11341                if (opti >= args.length) {
11342                    name = null;
11343                    newArgs = EMPTY_STRING_ARRAY;
11344                } else {
11345                    name = args[opti];
11346                    opti++;
11347                    newArgs = new String[args.length - opti];
11348                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11349                            args.length - opti);
11350                }
11351                synchronized (this) {
11352                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11353                }
11354            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11355                synchronized (this) {
11356                    dumpOomLocked(fd, pw, args, opti, true);
11357                }
11358            } else if ("provider".equals(cmd)) {
11359                String[] newArgs;
11360                String name;
11361                if (opti >= args.length) {
11362                    name = null;
11363                    newArgs = EMPTY_STRING_ARRAY;
11364                } else {
11365                    name = args[opti];
11366                    opti++;
11367                    newArgs = new String[args.length - opti];
11368                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11369                }
11370                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11371                    pw.println("No providers match: " + name);
11372                    pw.println("Use -h for help.");
11373                }
11374            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11375                synchronized (this) {
11376                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11377                }
11378            } else if ("service".equals(cmd)) {
11379                String[] newArgs;
11380                String name;
11381                if (opti >= args.length) {
11382                    name = null;
11383                    newArgs = EMPTY_STRING_ARRAY;
11384                } else {
11385                    name = args[opti];
11386                    opti++;
11387                    newArgs = new String[args.length - opti];
11388                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11389                            args.length - opti);
11390                }
11391                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11392                    pw.println("No services match: " + name);
11393                    pw.println("Use -h for help.");
11394                }
11395            } else if ("package".equals(cmd)) {
11396                String[] newArgs;
11397                if (opti >= args.length) {
11398                    pw.println("package: no package name specified");
11399                    pw.println("Use -h for help.");
11400                } else {
11401                    dumpPackage = args[opti];
11402                    opti++;
11403                    newArgs = new String[args.length - opti];
11404                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11405                            args.length - opti);
11406                    args = newArgs;
11407                    opti = 0;
11408                    more = true;
11409                }
11410            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11411                synchronized (this) {
11412                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11413                }
11414            } else {
11415                // Dumping a single activity?
11416                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11417                    pw.println("Bad activity command, or no activities match: " + cmd);
11418                    pw.println("Use -h for help.");
11419                }
11420            }
11421            if (!more) {
11422                Binder.restoreCallingIdentity(origId);
11423                return;
11424            }
11425        }
11426
11427        // No piece of data specified, dump everything.
11428        synchronized (this) {
11429            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11430            pw.println();
11431            if (dumpAll) {
11432                pw.println("-------------------------------------------------------------------------------");
11433            }
11434            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11435            pw.println();
11436            if (dumpAll) {
11437                pw.println("-------------------------------------------------------------------------------");
11438            }
11439            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11440            pw.println();
11441            if (dumpAll) {
11442                pw.println("-------------------------------------------------------------------------------");
11443            }
11444            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11445            pw.println();
11446            if (dumpAll) {
11447                pw.println("-------------------------------------------------------------------------------");
11448            }
11449            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11450            pw.println();
11451            if (dumpAll) {
11452                pw.println("-------------------------------------------------------------------------------");
11453            }
11454            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11455        }
11456        Binder.restoreCallingIdentity(origId);
11457    }
11458
11459    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11460            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11461        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11462
11463        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11464                dumpPackage);
11465        boolean needSep = printedAnything;
11466
11467        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11468                dumpPackage, needSep, "  mFocusedActivity: ");
11469        if (printed) {
11470            printedAnything = true;
11471            needSep = false;
11472        }
11473
11474        if (dumpPackage == null) {
11475            if (needSep) {
11476                pw.println();
11477            }
11478            needSep = true;
11479            printedAnything = true;
11480            mStackSupervisor.dump(pw, "  ");
11481        }
11482
11483        if (mRecentTasks.size() > 0) {
11484            boolean printedHeader = false;
11485
11486            final int N = mRecentTasks.size();
11487            for (int i=0; i<N; i++) {
11488                TaskRecord tr = mRecentTasks.get(i);
11489                if (dumpPackage != null) {
11490                    if (tr.realActivity == null ||
11491                            !dumpPackage.equals(tr.realActivity)) {
11492                        continue;
11493                    }
11494                }
11495                if (!printedHeader) {
11496                    if (needSep) {
11497                        pw.println();
11498                    }
11499                    pw.println("  Recent tasks:");
11500                    printedHeader = true;
11501                    printedAnything = true;
11502                }
11503                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11504                        pw.println(tr);
11505                if (dumpAll) {
11506                    mRecentTasks.get(i).dump(pw, "    ");
11507                }
11508            }
11509        }
11510
11511        if (!printedAnything) {
11512            pw.println("  (nothing)");
11513        }
11514    }
11515
11516    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11517            int opti, boolean dumpAll, String dumpPackage) {
11518        boolean needSep = false;
11519        boolean printedAnything = false;
11520        int numPers = 0;
11521
11522        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11523
11524        if (dumpAll) {
11525            final int NP = mProcessNames.getMap().size();
11526            for (int ip=0; ip<NP; ip++) {
11527                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11528                final int NA = procs.size();
11529                for (int ia=0; ia<NA; ia++) {
11530                    ProcessRecord r = procs.valueAt(ia);
11531                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11532                        continue;
11533                    }
11534                    if (!needSep) {
11535                        pw.println("  All known processes:");
11536                        needSep = true;
11537                        printedAnything = true;
11538                    }
11539                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11540                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11541                        pw.print(" "); pw.println(r);
11542                    r.dump(pw, "    ");
11543                    if (r.persistent) {
11544                        numPers++;
11545                    }
11546                }
11547            }
11548        }
11549
11550        if (mIsolatedProcesses.size() > 0) {
11551            boolean printed = false;
11552            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11553                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11554                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11555                    continue;
11556                }
11557                if (!printed) {
11558                    if (needSep) {
11559                        pw.println();
11560                    }
11561                    pw.println("  Isolated process list (sorted by uid):");
11562                    printedAnything = true;
11563                    printed = true;
11564                    needSep = true;
11565                }
11566                pw.println(String.format("%sIsolated #%2d: %s",
11567                        "    ", i, r.toString()));
11568            }
11569        }
11570
11571        if (mLruProcesses.size() > 0) {
11572            if (needSep) {
11573                pw.println();
11574            }
11575            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11576                    pw.print(" total, non-act at ");
11577                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11578                    pw.print(", non-svc at ");
11579                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11580                    pw.println("):");
11581            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11582            needSep = true;
11583            printedAnything = true;
11584        }
11585
11586        if (dumpAll || dumpPackage != null) {
11587            synchronized (mPidsSelfLocked) {
11588                boolean printed = false;
11589                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11590                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11591                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11592                        continue;
11593                    }
11594                    if (!printed) {
11595                        if (needSep) pw.println();
11596                        needSep = true;
11597                        pw.println("  PID mappings:");
11598                        printed = true;
11599                        printedAnything = true;
11600                    }
11601                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11602                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11603                }
11604            }
11605        }
11606
11607        if (mForegroundProcesses.size() > 0) {
11608            synchronized (mPidsSelfLocked) {
11609                boolean printed = false;
11610                for (int i=0; i<mForegroundProcesses.size(); i++) {
11611                    ProcessRecord r = mPidsSelfLocked.get(
11612                            mForegroundProcesses.valueAt(i).pid);
11613                    if (dumpPackage != null && (r == null
11614                            || !r.pkgList.containsKey(dumpPackage))) {
11615                        continue;
11616                    }
11617                    if (!printed) {
11618                        if (needSep) pw.println();
11619                        needSep = true;
11620                        pw.println("  Foreground Processes:");
11621                        printed = true;
11622                        printedAnything = true;
11623                    }
11624                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11625                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11626                }
11627            }
11628        }
11629
11630        if (mPersistentStartingProcesses.size() > 0) {
11631            if (needSep) pw.println();
11632            needSep = true;
11633            printedAnything = true;
11634            pw.println("  Persisent processes that are starting:");
11635            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11636                    "Starting Norm", "Restarting PERS", dumpPackage);
11637        }
11638
11639        if (mRemovedProcesses.size() > 0) {
11640            if (needSep) pw.println();
11641            needSep = true;
11642            printedAnything = true;
11643            pw.println("  Processes that are being removed:");
11644            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11645                    "Removed Norm", "Removed PERS", dumpPackage);
11646        }
11647
11648        if (mProcessesOnHold.size() > 0) {
11649            if (needSep) pw.println();
11650            needSep = true;
11651            printedAnything = true;
11652            pw.println("  Processes that are on old until the system is ready:");
11653            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11654                    "OnHold Norm", "OnHold PERS", dumpPackage);
11655        }
11656
11657        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11658
11659        if (mProcessCrashTimes.getMap().size() > 0) {
11660            boolean printed = false;
11661            long now = SystemClock.uptimeMillis();
11662            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11663            final int NP = pmap.size();
11664            for (int ip=0; ip<NP; ip++) {
11665                String pname = pmap.keyAt(ip);
11666                SparseArray<Long> uids = pmap.valueAt(ip);
11667                final int N = uids.size();
11668                for (int i=0; i<N; i++) {
11669                    int puid = uids.keyAt(i);
11670                    ProcessRecord r = mProcessNames.get(pname, puid);
11671                    if (dumpPackage != null && (r == null
11672                            || !r.pkgList.containsKey(dumpPackage))) {
11673                        continue;
11674                    }
11675                    if (!printed) {
11676                        if (needSep) pw.println();
11677                        needSep = true;
11678                        pw.println("  Time since processes crashed:");
11679                        printed = true;
11680                        printedAnything = true;
11681                    }
11682                    pw.print("    Process "); pw.print(pname);
11683                            pw.print(" uid "); pw.print(puid);
11684                            pw.print(": last crashed ");
11685                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11686                            pw.println(" ago");
11687                }
11688            }
11689        }
11690
11691        if (mBadProcesses.getMap().size() > 0) {
11692            boolean printed = false;
11693            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11694            final int NP = pmap.size();
11695            for (int ip=0; ip<NP; ip++) {
11696                String pname = pmap.keyAt(ip);
11697                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11698                final int N = uids.size();
11699                for (int i=0; i<N; i++) {
11700                    int puid = uids.keyAt(i);
11701                    ProcessRecord r = mProcessNames.get(pname, puid);
11702                    if (dumpPackage != null && (r == null
11703                            || !r.pkgList.containsKey(dumpPackage))) {
11704                        continue;
11705                    }
11706                    if (!printed) {
11707                        if (needSep) pw.println();
11708                        needSep = true;
11709                        pw.println("  Bad processes:");
11710                        printedAnything = true;
11711                    }
11712                    BadProcessInfo info = uids.valueAt(i);
11713                    pw.print("    Bad process "); pw.print(pname);
11714                            pw.print(" uid "); pw.print(puid);
11715                            pw.print(": crashed at time "); pw.println(info.time);
11716                    if (info.shortMsg != null) {
11717                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11718                    }
11719                    if (info.longMsg != null) {
11720                        pw.print("      Long msg: "); pw.println(info.longMsg);
11721                    }
11722                    if (info.stack != null) {
11723                        pw.println("      Stack:");
11724                        int lastPos = 0;
11725                        for (int pos=0; pos<info.stack.length(); pos++) {
11726                            if (info.stack.charAt(pos) == '\n') {
11727                                pw.print("        ");
11728                                pw.write(info.stack, lastPos, pos-lastPos);
11729                                pw.println();
11730                                lastPos = pos+1;
11731                            }
11732                        }
11733                        if (lastPos < info.stack.length()) {
11734                            pw.print("        ");
11735                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11736                            pw.println();
11737                        }
11738                    }
11739                }
11740            }
11741        }
11742
11743        if (dumpPackage == null) {
11744            pw.println();
11745            needSep = false;
11746            pw.println("  mStartedUsers:");
11747            for (int i=0; i<mStartedUsers.size(); i++) {
11748                UserStartedState uss = mStartedUsers.valueAt(i);
11749                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11750                        pw.print(": "); uss.dump("", pw);
11751            }
11752            pw.print("  mStartedUserArray: [");
11753            for (int i=0; i<mStartedUserArray.length; i++) {
11754                if (i > 0) pw.print(", ");
11755                pw.print(mStartedUserArray[i]);
11756            }
11757            pw.println("]");
11758            pw.print("  mUserLru: [");
11759            for (int i=0; i<mUserLru.size(); i++) {
11760                if (i > 0) pw.print(", ");
11761                pw.print(mUserLru.get(i));
11762            }
11763            pw.println("]");
11764            if (dumpAll) {
11765                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11766            }
11767            synchronized (mUserProfileGroupIdsSelfLocked) {
11768                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11769                    pw.println("  mUserProfileGroupIds:");
11770                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11771                        pw.print("    User #");
11772                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11773                        pw.print(" -> profile #");
11774                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11775                    }
11776                }
11777            }
11778        }
11779        if (mHomeProcess != null && (dumpPackage == null
11780                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11781            if (needSep) {
11782                pw.println();
11783                needSep = false;
11784            }
11785            pw.println("  mHomeProcess: " + mHomeProcess);
11786        }
11787        if (mPreviousProcess != null && (dumpPackage == null
11788                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11789            if (needSep) {
11790                pw.println();
11791                needSep = false;
11792            }
11793            pw.println("  mPreviousProcess: " + mPreviousProcess);
11794        }
11795        if (dumpAll) {
11796            StringBuilder sb = new StringBuilder(128);
11797            sb.append("  mPreviousProcessVisibleTime: ");
11798            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11799            pw.println(sb);
11800        }
11801        if (mHeavyWeightProcess != null && (dumpPackage == null
11802                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11803            if (needSep) {
11804                pw.println();
11805                needSep = false;
11806            }
11807            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11808        }
11809        if (dumpPackage == null) {
11810            pw.println("  mConfiguration: " + mConfiguration);
11811        }
11812        if (dumpAll) {
11813            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11814            if (mCompatModePackages.getPackages().size() > 0) {
11815                boolean printed = false;
11816                for (Map.Entry<String, Integer> entry
11817                        : mCompatModePackages.getPackages().entrySet()) {
11818                    String pkg = entry.getKey();
11819                    int mode = entry.getValue();
11820                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11821                        continue;
11822                    }
11823                    if (!printed) {
11824                        pw.println("  mScreenCompatPackages:");
11825                        printed = true;
11826                    }
11827                    pw.print("    "); pw.print(pkg); pw.print(": ");
11828                            pw.print(mode); pw.println();
11829                }
11830            }
11831        }
11832        if (dumpPackage == null) {
11833            if (mSleeping || mWentToSleep || mLockScreenShown) {
11834                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11835                        + " mLockScreenShown " + mLockScreenShown);
11836            }
11837            if (mShuttingDown || mRunningVoice) {
11838                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11839            }
11840        }
11841        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11842                || mOrigWaitForDebugger) {
11843            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11844                    || dumpPackage.equals(mOrigDebugApp)) {
11845                if (needSep) {
11846                    pw.println();
11847                    needSep = false;
11848                }
11849                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11850                        + " mDebugTransient=" + mDebugTransient
11851                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11852            }
11853        }
11854        if (mOpenGlTraceApp != null) {
11855            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11856                if (needSep) {
11857                    pw.println();
11858                    needSep = false;
11859                }
11860                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11861            }
11862        }
11863        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11864                || mProfileFd != null) {
11865            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11866                if (needSep) {
11867                    pw.println();
11868                    needSep = false;
11869                }
11870                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11871                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11872                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11873                        + mAutoStopProfiler);
11874            }
11875        }
11876        if (dumpPackage == null) {
11877            if (mAlwaysFinishActivities || mController != null) {
11878                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11879                        + " mController=" + mController);
11880            }
11881            if (dumpAll) {
11882                pw.println("  Total persistent processes: " + numPers);
11883                pw.println("  mProcessesReady=" + mProcessesReady
11884                        + " mSystemReady=" + mSystemReady);
11885                pw.println("  mBooting=" + mBooting
11886                        + " mBooted=" + mBooted
11887                        + " mFactoryTest=" + mFactoryTest);
11888                pw.print("  mLastPowerCheckRealtime=");
11889                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11890                        pw.println("");
11891                pw.print("  mLastPowerCheckUptime=");
11892                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11893                        pw.println("");
11894                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11895                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11896                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11897                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11898                        + " (" + mLruProcesses.size() + " total)"
11899                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11900                        + " mNumServiceProcs=" + mNumServiceProcs
11901                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11902                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11903                        + " mLastMemoryLevel" + mLastMemoryLevel
11904                        + " mLastNumProcesses" + mLastNumProcesses);
11905                long now = SystemClock.uptimeMillis();
11906                pw.print("  mLastIdleTime=");
11907                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11908                        pw.print(" mLowRamSinceLastIdle=");
11909                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11910                        pw.println();
11911            }
11912        }
11913
11914        if (!printedAnything) {
11915            pw.println("  (nothing)");
11916        }
11917    }
11918
11919    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11920            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11921        if (mProcessesToGc.size() > 0) {
11922            boolean printed = false;
11923            long now = SystemClock.uptimeMillis();
11924            for (int i=0; i<mProcessesToGc.size(); i++) {
11925                ProcessRecord proc = mProcessesToGc.get(i);
11926                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11927                    continue;
11928                }
11929                if (!printed) {
11930                    if (needSep) pw.println();
11931                    needSep = true;
11932                    pw.println("  Processes that are waiting to GC:");
11933                    printed = true;
11934                }
11935                pw.print("    Process "); pw.println(proc);
11936                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11937                        pw.print(", last gced=");
11938                        pw.print(now-proc.lastRequestedGc);
11939                        pw.print(" ms ago, last lowMem=");
11940                        pw.print(now-proc.lastLowMemory);
11941                        pw.println(" ms ago");
11942
11943            }
11944        }
11945        return needSep;
11946    }
11947
11948    void printOomLevel(PrintWriter pw, String name, int adj) {
11949        pw.print("    ");
11950        if (adj >= 0) {
11951            pw.print(' ');
11952            if (adj < 10) pw.print(' ');
11953        } else {
11954            if (adj > -10) pw.print(' ');
11955        }
11956        pw.print(adj);
11957        pw.print(": ");
11958        pw.print(name);
11959        pw.print(" (");
11960        pw.print(mProcessList.getMemLevel(adj)/1024);
11961        pw.println(" kB)");
11962    }
11963
11964    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11965            int opti, boolean dumpAll) {
11966        boolean needSep = false;
11967
11968        if (mLruProcesses.size() > 0) {
11969            if (needSep) pw.println();
11970            needSep = true;
11971            pw.println("  OOM levels:");
11972            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11973            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11974            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11975            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11976            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11977            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11978            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11979            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11980            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11981            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11982            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11983            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11984            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11985
11986            if (needSep) pw.println();
11987            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11988                    pw.print(" total, non-act at ");
11989                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11990                    pw.print(", non-svc at ");
11991                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11992                    pw.println("):");
11993            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11994            needSep = true;
11995        }
11996
11997        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11998
11999        pw.println();
12000        pw.println("  mHomeProcess: " + mHomeProcess);
12001        pw.println("  mPreviousProcess: " + mPreviousProcess);
12002        if (mHeavyWeightProcess != null) {
12003            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12004        }
12005
12006        return true;
12007    }
12008
12009    /**
12010     * There are three ways to call this:
12011     *  - no provider specified: dump all the providers
12012     *  - a flattened component name that matched an existing provider was specified as the
12013     *    first arg: dump that one provider
12014     *  - the first arg isn't the flattened component name of an existing provider:
12015     *    dump all providers whose component contains the first arg as a substring
12016     */
12017    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12018            int opti, boolean dumpAll) {
12019        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12020    }
12021
12022    static class ItemMatcher {
12023        ArrayList<ComponentName> components;
12024        ArrayList<String> strings;
12025        ArrayList<Integer> objects;
12026        boolean all;
12027
12028        ItemMatcher() {
12029            all = true;
12030        }
12031
12032        void build(String name) {
12033            ComponentName componentName = ComponentName.unflattenFromString(name);
12034            if (componentName != null) {
12035                if (components == null) {
12036                    components = new ArrayList<ComponentName>();
12037                }
12038                components.add(componentName);
12039                all = false;
12040            } else {
12041                int objectId = 0;
12042                // Not a '/' separated full component name; maybe an object ID?
12043                try {
12044                    objectId = Integer.parseInt(name, 16);
12045                    if (objects == null) {
12046                        objects = new ArrayList<Integer>();
12047                    }
12048                    objects.add(objectId);
12049                    all = false;
12050                } catch (RuntimeException e) {
12051                    // Not an integer; just do string match.
12052                    if (strings == null) {
12053                        strings = new ArrayList<String>();
12054                    }
12055                    strings.add(name);
12056                    all = false;
12057                }
12058            }
12059        }
12060
12061        int build(String[] args, int opti) {
12062            for (; opti<args.length; opti++) {
12063                String name = args[opti];
12064                if ("--".equals(name)) {
12065                    return opti+1;
12066                }
12067                build(name);
12068            }
12069            return opti;
12070        }
12071
12072        boolean match(Object object, ComponentName comp) {
12073            if (all) {
12074                return true;
12075            }
12076            if (components != null) {
12077                for (int i=0; i<components.size(); i++) {
12078                    if (components.get(i).equals(comp)) {
12079                        return true;
12080                    }
12081                }
12082            }
12083            if (objects != null) {
12084                for (int i=0; i<objects.size(); i++) {
12085                    if (System.identityHashCode(object) == objects.get(i)) {
12086                        return true;
12087                    }
12088                }
12089            }
12090            if (strings != null) {
12091                String flat = comp.flattenToString();
12092                for (int i=0; i<strings.size(); i++) {
12093                    if (flat.contains(strings.get(i))) {
12094                        return true;
12095                    }
12096                }
12097            }
12098            return false;
12099        }
12100    }
12101
12102    /**
12103     * There are three things that cmd can be:
12104     *  - a flattened component name that matches an existing activity
12105     *  - the cmd arg isn't the flattened component name of an existing activity:
12106     *    dump all activity whose component contains the cmd as a substring
12107     *  - A hex number of the ActivityRecord object instance.
12108     */
12109    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12110            int opti, boolean dumpAll) {
12111        ArrayList<ActivityRecord> activities;
12112
12113        synchronized (this) {
12114            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12115        }
12116
12117        if (activities.size() <= 0) {
12118            return false;
12119        }
12120
12121        String[] newArgs = new String[args.length - opti];
12122        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12123
12124        TaskRecord lastTask = null;
12125        boolean needSep = false;
12126        for (int i=activities.size()-1; i>=0; i--) {
12127            ActivityRecord r = activities.get(i);
12128            if (needSep) {
12129                pw.println();
12130            }
12131            needSep = true;
12132            synchronized (this) {
12133                if (lastTask != r.task) {
12134                    lastTask = r.task;
12135                    pw.print("TASK "); pw.print(lastTask.affinity);
12136                            pw.print(" id="); pw.println(lastTask.taskId);
12137                    if (dumpAll) {
12138                        lastTask.dump(pw, "  ");
12139                    }
12140                }
12141            }
12142            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12143        }
12144        return true;
12145    }
12146
12147    /**
12148     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12149     * there is a thread associated with the activity.
12150     */
12151    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12152            final ActivityRecord r, String[] args, boolean dumpAll) {
12153        String innerPrefix = prefix + "  ";
12154        synchronized (this) {
12155            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12156                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12157                    pw.print(" pid=");
12158                    if (r.app != null) pw.println(r.app.pid);
12159                    else pw.println("(not running)");
12160            if (dumpAll) {
12161                r.dump(pw, innerPrefix);
12162            }
12163        }
12164        if (r.app != null && r.app.thread != null) {
12165            // flush anything that is already in the PrintWriter since the thread is going
12166            // to write to the file descriptor directly
12167            pw.flush();
12168            try {
12169                TransferPipe tp = new TransferPipe();
12170                try {
12171                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12172                            r.appToken, innerPrefix, args);
12173                    tp.go(fd);
12174                } finally {
12175                    tp.kill();
12176                }
12177            } catch (IOException e) {
12178                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12179            } catch (RemoteException e) {
12180                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12181            }
12182        }
12183    }
12184
12185    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12186            int opti, boolean dumpAll, String dumpPackage) {
12187        boolean needSep = false;
12188        boolean onlyHistory = false;
12189        boolean printedAnything = false;
12190
12191        if ("history".equals(dumpPackage)) {
12192            if (opti < args.length && "-s".equals(args[opti])) {
12193                dumpAll = false;
12194            }
12195            onlyHistory = true;
12196            dumpPackage = null;
12197        }
12198
12199        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12200        if (!onlyHistory && dumpAll) {
12201            if (mRegisteredReceivers.size() > 0) {
12202                boolean printed = false;
12203                Iterator it = mRegisteredReceivers.values().iterator();
12204                while (it.hasNext()) {
12205                    ReceiverList r = (ReceiverList)it.next();
12206                    if (dumpPackage != null && (r.app == null ||
12207                            !dumpPackage.equals(r.app.info.packageName))) {
12208                        continue;
12209                    }
12210                    if (!printed) {
12211                        pw.println("  Registered Receivers:");
12212                        needSep = true;
12213                        printed = true;
12214                        printedAnything = true;
12215                    }
12216                    pw.print("  * "); pw.println(r);
12217                    r.dump(pw, "    ");
12218                }
12219            }
12220
12221            if (mReceiverResolver.dump(pw, needSep ?
12222                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12223                    "    ", dumpPackage, false)) {
12224                needSep = true;
12225                printedAnything = true;
12226            }
12227        }
12228
12229        for (BroadcastQueue q : mBroadcastQueues) {
12230            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12231            printedAnything |= needSep;
12232        }
12233
12234        needSep = true;
12235
12236        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12237            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12238                if (needSep) {
12239                    pw.println();
12240                }
12241                needSep = true;
12242                printedAnything = true;
12243                pw.print("  Sticky broadcasts for user ");
12244                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12245                StringBuilder sb = new StringBuilder(128);
12246                for (Map.Entry<String, ArrayList<Intent>> ent
12247                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12248                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12249                    if (dumpAll) {
12250                        pw.println(":");
12251                        ArrayList<Intent> intents = ent.getValue();
12252                        final int N = intents.size();
12253                        for (int i=0; i<N; i++) {
12254                            sb.setLength(0);
12255                            sb.append("    Intent: ");
12256                            intents.get(i).toShortString(sb, false, true, false, false);
12257                            pw.println(sb.toString());
12258                            Bundle bundle = intents.get(i).getExtras();
12259                            if (bundle != null) {
12260                                pw.print("      ");
12261                                pw.println(bundle.toString());
12262                            }
12263                        }
12264                    } else {
12265                        pw.println("");
12266                    }
12267                }
12268            }
12269        }
12270
12271        if (!onlyHistory && dumpAll) {
12272            pw.println();
12273            for (BroadcastQueue queue : mBroadcastQueues) {
12274                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12275                        + queue.mBroadcastsScheduled);
12276            }
12277            pw.println("  mHandler:");
12278            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12279            needSep = true;
12280            printedAnything = true;
12281        }
12282
12283        if (!printedAnything) {
12284            pw.println("  (nothing)");
12285        }
12286    }
12287
12288    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12289            int opti, boolean dumpAll, String dumpPackage) {
12290        boolean needSep;
12291        boolean printedAnything = false;
12292
12293        ItemMatcher matcher = new ItemMatcher();
12294        matcher.build(args, opti);
12295
12296        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12297
12298        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12299        printedAnything |= needSep;
12300
12301        if (mLaunchingProviders.size() > 0) {
12302            boolean printed = false;
12303            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12304                ContentProviderRecord r = mLaunchingProviders.get(i);
12305                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12306                    continue;
12307                }
12308                if (!printed) {
12309                    if (needSep) pw.println();
12310                    needSep = true;
12311                    pw.println("  Launching content providers:");
12312                    printed = true;
12313                    printedAnything = true;
12314                }
12315                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12316                        pw.println(r);
12317            }
12318        }
12319
12320        if (mGrantedUriPermissions.size() > 0) {
12321            boolean printed = false;
12322            int dumpUid = -2;
12323            if (dumpPackage != null) {
12324                try {
12325                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12326                } catch (NameNotFoundException e) {
12327                    dumpUid = -1;
12328                }
12329            }
12330            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12331                int uid = mGrantedUriPermissions.keyAt(i);
12332                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12333                    continue;
12334                }
12335                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12336                if (!printed) {
12337                    if (needSep) pw.println();
12338                    needSep = true;
12339                    pw.println("  Granted Uri Permissions:");
12340                    printed = true;
12341                    printedAnything = true;
12342                }
12343                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12344                for (UriPermission perm : perms.values()) {
12345                    pw.print("    "); pw.println(perm);
12346                    if (dumpAll) {
12347                        perm.dump(pw, "      ");
12348                    }
12349                }
12350            }
12351        }
12352
12353        if (!printedAnything) {
12354            pw.println("  (nothing)");
12355        }
12356    }
12357
12358    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12359            int opti, boolean dumpAll, String dumpPackage) {
12360        boolean printed = false;
12361
12362        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12363
12364        if (mIntentSenderRecords.size() > 0) {
12365            Iterator<WeakReference<PendingIntentRecord>> it
12366                    = mIntentSenderRecords.values().iterator();
12367            while (it.hasNext()) {
12368                WeakReference<PendingIntentRecord> ref = it.next();
12369                PendingIntentRecord rec = ref != null ? ref.get(): null;
12370                if (dumpPackage != null && (rec == null
12371                        || !dumpPackage.equals(rec.key.packageName))) {
12372                    continue;
12373                }
12374                printed = true;
12375                if (rec != null) {
12376                    pw.print("  * "); pw.println(rec);
12377                    if (dumpAll) {
12378                        rec.dump(pw, "    ");
12379                    }
12380                } else {
12381                    pw.print("  * "); pw.println(ref);
12382                }
12383            }
12384        }
12385
12386        if (!printed) {
12387            pw.println("  (nothing)");
12388        }
12389    }
12390
12391    private static final int dumpProcessList(PrintWriter pw,
12392            ActivityManagerService service, List list,
12393            String prefix, String normalLabel, String persistentLabel,
12394            String dumpPackage) {
12395        int numPers = 0;
12396        final int N = list.size()-1;
12397        for (int i=N; i>=0; i--) {
12398            ProcessRecord r = (ProcessRecord)list.get(i);
12399            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12400                continue;
12401            }
12402            pw.println(String.format("%s%s #%2d: %s",
12403                    prefix, (r.persistent ? persistentLabel : normalLabel),
12404                    i, r.toString()));
12405            if (r.persistent) {
12406                numPers++;
12407            }
12408        }
12409        return numPers;
12410    }
12411
12412    private static final boolean dumpProcessOomList(PrintWriter pw,
12413            ActivityManagerService service, List<ProcessRecord> origList,
12414            String prefix, String normalLabel, String persistentLabel,
12415            boolean inclDetails, String dumpPackage) {
12416
12417        ArrayList<Pair<ProcessRecord, Integer>> list
12418                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12419        for (int i=0; i<origList.size(); i++) {
12420            ProcessRecord r = origList.get(i);
12421            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12422                continue;
12423            }
12424            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12425        }
12426
12427        if (list.size() <= 0) {
12428            return false;
12429        }
12430
12431        Comparator<Pair<ProcessRecord, Integer>> comparator
12432                = new Comparator<Pair<ProcessRecord, Integer>>() {
12433            @Override
12434            public int compare(Pair<ProcessRecord, Integer> object1,
12435                    Pair<ProcessRecord, Integer> object2) {
12436                if (object1.first.setAdj != object2.first.setAdj) {
12437                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12438                }
12439                if (object1.second.intValue() != object2.second.intValue()) {
12440                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12441                }
12442                return 0;
12443            }
12444        };
12445
12446        Collections.sort(list, comparator);
12447
12448        final long curRealtime = SystemClock.elapsedRealtime();
12449        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12450        final long curUptime = SystemClock.uptimeMillis();
12451        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12452
12453        for (int i=list.size()-1; i>=0; i--) {
12454            ProcessRecord r = list.get(i).first;
12455            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12456            char schedGroup;
12457            switch (r.setSchedGroup) {
12458                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12459                    schedGroup = 'B';
12460                    break;
12461                case Process.THREAD_GROUP_DEFAULT:
12462                    schedGroup = 'F';
12463                    break;
12464                default:
12465                    schedGroup = '?';
12466                    break;
12467            }
12468            char foreground;
12469            if (r.foregroundActivities) {
12470                foreground = 'A';
12471            } else if (r.foregroundServices) {
12472                foreground = 'S';
12473            } else {
12474                foreground = ' ';
12475            }
12476            String procState = ProcessList.makeProcStateString(r.curProcState);
12477            pw.print(prefix);
12478            pw.print(r.persistent ? persistentLabel : normalLabel);
12479            pw.print(" #");
12480            int num = (origList.size()-1)-list.get(i).second;
12481            if (num < 10) pw.print(' ');
12482            pw.print(num);
12483            pw.print(": ");
12484            pw.print(oomAdj);
12485            pw.print(' ');
12486            pw.print(schedGroup);
12487            pw.print('/');
12488            pw.print(foreground);
12489            pw.print('/');
12490            pw.print(procState);
12491            pw.print(" trm:");
12492            if (r.trimMemoryLevel < 10) pw.print(' ');
12493            pw.print(r.trimMemoryLevel);
12494            pw.print(' ');
12495            pw.print(r.toShortString());
12496            pw.print(" (");
12497            pw.print(r.adjType);
12498            pw.println(')');
12499            if (r.adjSource != null || r.adjTarget != null) {
12500                pw.print(prefix);
12501                pw.print("    ");
12502                if (r.adjTarget instanceof ComponentName) {
12503                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12504                } else if (r.adjTarget != null) {
12505                    pw.print(r.adjTarget.toString());
12506                } else {
12507                    pw.print("{null}");
12508                }
12509                pw.print("<=");
12510                if (r.adjSource instanceof ProcessRecord) {
12511                    pw.print("Proc{");
12512                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12513                    pw.println("}");
12514                } else if (r.adjSource != null) {
12515                    pw.println(r.adjSource.toString());
12516                } else {
12517                    pw.println("{null}");
12518                }
12519            }
12520            if (inclDetails) {
12521                pw.print(prefix);
12522                pw.print("    ");
12523                pw.print("oom: max="); pw.print(r.maxAdj);
12524                pw.print(" curRaw="); pw.print(r.curRawAdj);
12525                pw.print(" setRaw="); pw.print(r.setRawAdj);
12526                pw.print(" cur="); pw.print(r.curAdj);
12527                pw.print(" set="); pw.println(r.setAdj);
12528                pw.print(prefix);
12529                pw.print("    ");
12530                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12531                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12532                pw.print(" lastPss="); pw.print(r.lastPss);
12533                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12534                pw.print(prefix);
12535                pw.print("    ");
12536                pw.print("cached="); pw.print(r.cached);
12537                pw.print(" empty="); pw.print(r.empty);
12538                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12539
12540                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12541                    if (r.lastWakeTime != 0) {
12542                        long wtime;
12543                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12544                        synchronized (stats) {
12545                            wtime = stats.getProcessWakeTime(r.info.uid,
12546                                    r.pid, curRealtime);
12547                        }
12548                        long timeUsed = wtime - r.lastWakeTime;
12549                        pw.print(prefix);
12550                        pw.print("    ");
12551                        pw.print("keep awake over ");
12552                        TimeUtils.formatDuration(realtimeSince, pw);
12553                        pw.print(" used ");
12554                        TimeUtils.formatDuration(timeUsed, pw);
12555                        pw.print(" (");
12556                        pw.print((timeUsed*100)/realtimeSince);
12557                        pw.println("%)");
12558                    }
12559                    if (r.lastCpuTime != 0) {
12560                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12561                        pw.print(prefix);
12562                        pw.print("    ");
12563                        pw.print("run cpu over ");
12564                        TimeUtils.formatDuration(uptimeSince, pw);
12565                        pw.print(" used ");
12566                        TimeUtils.formatDuration(timeUsed, pw);
12567                        pw.print(" (");
12568                        pw.print((timeUsed*100)/uptimeSince);
12569                        pw.println("%)");
12570                    }
12571                }
12572            }
12573        }
12574        return true;
12575    }
12576
12577    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12578        ArrayList<ProcessRecord> procs;
12579        synchronized (this) {
12580            if (args != null && args.length > start
12581                    && args[start].charAt(0) != '-') {
12582                procs = new ArrayList<ProcessRecord>();
12583                int pid = -1;
12584                try {
12585                    pid = Integer.parseInt(args[start]);
12586                } catch (NumberFormatException e) {
12587                }
12588                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12589                    ProcessRecord proc = mLruProcesses.get(i);
12590                    if (proc.pid == pid) {
12591                        procs.add(proc);
12592                    } else if (proc.processName.equals(args[start])) {
12593                        procs.add(proc);
12594                    }
12595                }
12596                if (procs.size() <= 0) {
12597                    return null;
12598                }
12599            } else {
12600                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12601            }
12602        }
12603        return procs;
12604    }
12605
12606    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12607            PrintWriter pw, String[] args) {
12608        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12609        if (procs == null) {
12610            pw.println("No process found for: " + args[0]);
12611            return;
12612        }
12613
12614        long uptime = SystemClock.uptimeMillis();
12615        long realtime = SystemClock.elapsedRealtime();
12616        pw.println("Applications Graphics Acceleration Info:");
12617        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12618
12619        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12620            ProcessRecord r = procs.get(i);
12621            if (r.thread != null) {
12622                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12623                pw.flush();
12624                try {
12625                    TransferPipe tp = new TransferPipe();
12626                    try {
12627                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12628                        tp.go(fd);
12629                    } finally {
12630                        tp.kill();
12631                    }
12632                } catch (IOException e) {
12633                    pw.println("Failure while dumping the app: " + r);
12634                    pw.flush();
12635                } catch (RemoteException e) {
12636                    pw.println("Got a RemoteException while dumping the app " + r);
12637                    pw.flush();
12638                }
12639            }
12640        }
12641    }
12642
12643    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12644        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12645        if (procs == null) {
12646            pw.println("No process found for: " + args[0]);
12647            return;
12648        }
12649
12650        pw.println("Applications Database Info:");
12651
12652        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12653            ProcessRecord r = procs.get(i);
12654            if (r.thread != null) {
12655                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12656                pw.flush();
12657                try {
12658                    TransferPipe tp = new TransferPipe();
12659                    try {
12660                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12661                        tp.go(fd);
12662                    } finally {
12663                        tp.kill();
12664                    }
12665                } catch (IOException e) {
12666                    pw.println("Failure while dumping the app: " + r);
12667                    pw.flush();
12668                } catch (RemoteException e) {
12669                    pw.println("Got a RemoteException while dumping the app " + r);
12670                    pw.flush();
12671                }
12672            }
12673        }
12674    }
12675
12676    final static class MemItem {
12677        final boolean isProc;
12678        final String label;
12679        final String shortLabel;
12680        final long pss;
12681        final int id;
12682        final boolean hasActivities;
12683        ArrayList<MemItem> subitems;
12684
12685        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12686                boolean _hasActivities) {
12687            isProc = true;
12688            label = _label;
12689            shortLabel = _shortLabel;
12690            pss = _pss;
12691            id = _id;
12692            hasActivities = _hasActivities;
12693        }
12694
12695        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12696            isProc = false;
12697            label = _label;
12698            shortLabel = _shortLabel;
12699            pss = _pss;
12700            id = _id;
12701            hasActivities = false;
12702        }
12703    }
12704
12705    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12706            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12707        if (sort && !isCompact) {
12708            Collections.sort(items, new Comparator<MemItem>() {
12709                @Override
12710                public int compare(MemItem lhs, MemItem rhs) {
12711                    if (lhs.pss < rhs.pss) {
12712                        return 1;
12713                    } else if (lhs.pss > rhs.pss) {
12714                        return -1;
12715                    }
12716                    return 0;
12717                }
12718            });
12719        }
12720
12721        for (int i=0; i<items.size(); i++) {
12722            MemItem mi = items.get(i);
12723            if (!isCompact) {
12724                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12725            } else if (mi.isProc) {
12726                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12727                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12728                pw.println(mi.hasActivities ? ",a" : ",e");
12729            } else {
12730                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12731                pw.println(mi.pss);
12732            }
12733            if (mi.subitems != null) {
12734                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12735                        true, isCompact);
12736            }
12737        }
12738    }
12739
12740    // These are in KB.
12741    static final long[] DUMP_MEM_BUCKETS = new long[] {
12742        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12743        120*1024, 160*1024, 200*1024,
12744        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12745        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12746    };
12747
12748    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12749            boolean stackLike) {
12750        int start = label.lastIndexOf('.');
12751        if (start >= 0) start++;
12752        else start = 0;
12753        int end = label.length();
12754        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12755            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12756                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12757                out.append(bucket);
12758                out.append(stackLike ? "MB." : "MB ");
12759                out.append(label, start, end);
12760                return;
12761            }
12762        }
12763        out.append(memKB/1024);
12764        out.append(stackLike ? "MB." : "MB ");
12765        out.append(label, start, end);
12766    }
12767
12768    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12769            ProcessList.NATIVE_ADJ,
12770            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12771            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12772            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12773            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12774            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12775    };
12776    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12777            "Native",
12778            "System", "Persistent", "Foreground",
12779            "Visible", "Perceptible",
12780            "Heavy Weight", "Backup",
12781            "A Services", "Home",
12782            "Previous", "B Services", "Cached"
12783    };
12784    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12785            "native",
12786            "sys", "pers", "fore",
12787            "vis", "percept",
12788            "heavy", "backup",
12789            "servicea", "home",
12790            "prev", "serviceb", "cached"
12791    };
12792
12793    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12794            long realtime, boolean isCheckinRequest, boolean isCompact) {
12795        if (isCheckinRequest || isCompact) {
12796            // short checkin version
12797            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12798        } else {
12799            pw.println("Applications Memory Usage (kB):");
12800            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12801        }
12802    }
12803
12804    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12805            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12806        boolean dumpDetails = false;
12807        boolean dumpFullDetails = false;
12808        boolean dumpDalvik = false;
12809        boolean oomOnly = false;
12810        boolean isCompact = false;
12811        boolean localOnly = false;
12812
12813        int opti = 0;
12814        while (opti < args.length) {
12815            String opt = args[opti];
12816            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12817                break;
12818            }
12819            opti++;
12820            if ("-a".equals(opt)) {
12821                dumpDetails = true;
12822                dumpFullDetails = true;
12823                dumpDalvik = true;
12824            } else if ("-d".equals(opt)) {
12825                dumpDalvik = true;
12826            } else if ("-c".equals(opt)) {
12827                isCompact = true;
12828            } else if ("--oom".equals(opt)) {
12829                oomOnly = true;
12830            } else if ("--local".equals(opt)) {
12831                localOnly = true;
12832            } else if ("-h".equals(opt)) {
12833                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12834                pw.println("  -a: include all available information for each process.");
12835                pw.println("  -d: include dalvik details when dumping process details.");
12836                pw.println("  -c: dump in a compact machine-parseable representation.");
12837                pw.println("  --oom: only show processes organized by oom adj.");
12838                pw.println("  --local: only collect details locally, don't call process.");
12839                pw.println("If [process] is specified it can be the name or ");
12840                pw.println("pid of a specific process to dump.");
12841                return;
12842            } else {
12843                pw.println("Unknown argument: " + opt + "; use -h for help");
12844            }
12845        }
12846
12847        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12848        long uptime = SystemClock.uptimeMillis();
12849        long realtime = SystemClock.elapsedRealtime();
12850        final long[] tmpLong = new long[1];
12851
12852        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12853        if (procs == null) {
12854            // No Java processes.  Maybe they want to print a native process.
12855            if (args != null && args.length > opti
12856                    && args[opti].charAt(0) != '-') {
12857                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12858                        = new ArrayList<ProcessCpuTracker.Stats>();
12859                updateCpuStatsNow();
12860                int findPid = -1;
12861                try {
12862                    findPid = Integer.parseInt(args[opti]);
12863                } catch (NumberFormatException e) {
12864                }
12865                synchronized (mProcessCpuThread) {
12866                    final int N = mProcessCpuTracker.countStats();
12867                    for (int i=0; i<N; i++) {
12868                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12869                        if (st.pid == findPid || (st.baseName != null
12870                                && st.baseName.equals(args[opti]))) {
12871                            nativeProcs.add(st);
12872                        }
12873                    }
12874                }
12875                if (nativeProcs.size() > 0) {
12876                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12877                            isCompact);
12878                    Debug.MemoryInfo mi = null;
12879                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12880                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12881                        final int pid = r.pid;
12882                        if (!isCheckinRequest && dumpDetails) {
12883                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12884                        }
12885                        if (mi == null) {
12886                            mi = new Debug.MemoryInfo();
12887                        }
12888                        if (dumpDetails || (!brief && !oomOnly)) {
12889                            Debug.getMemoryInfo(pid, mi);
12890                        } else {
12891                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12892                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12893                        }
12894                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12895                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12896                        if (isCheckinRequest) {
12897                            pw.println();
12898                        }
12899                    }
12900                    return;
12901                }
12902            }
12903            pw.println("No process found for: " + args[opti]);
12904            return;
12905        }
12906
12907        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12908            dumpDetails = true;
12909        }
12910
12911        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12912
12913        String[] innerArgs = new String[args.length-opti];
12914        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12915
12916        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12917        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12918        long nativePss=0, dalvikPss=0, otherPss=0;
12919        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12920
12921        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12922        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12923                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12924
12925        long totalPss = 0;
12926        long cachedPss = 0;
12927
12928        Debug.MemoryInfo mi = null;
12929        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12930            final ProcessRecord r = procs.get(i);
12931            final IApplicationThread thread;
12932            final int pid;
12933            final int oomAdj;
12934            final boolean hasActivities;
12935            synchronized (this) {
12936                thread = r.thread;
12937                pid = r.pid;
12938                oomAdj = r.getSetAdjWithServices();
12939                hasActivities = r.activities.size() > 0;
12940            }
12941            if (thread != null) {
12942                if (!isCheckinRequest && dumpDetails) {
12943                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12944                }
12945                if (mi == null) {
12946                    mi = new Debug.MemoryInfo();
12947                }
12948                if (dumpDetails || (!brief && !oomOnly)) {
12949                    Debug.getMemoryInfo(pid, mi);
12950                } else {
12951                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12952                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12953                }
12954                if (dumpDetails) {
12955                    if (localOnly) {
12956                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12957                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12958                        if (isCheckinRequest) {
12959                            pw.println();
12960                        }
12961                    } else {
12962                        try {
12963                            pw.flush();
12964                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12965                                    dumpDalvik, innerArgs);
12966                        } catch (RemoteException e) {
12967                            if (!isCheckinRequest) {
12968                                pw.println("Got RemoteException!");
12969                                pw.flush();
12970                            }
12971                        }
12972                    }
12973                }
12974
12975                final long myTotalPss = mi.getTotalPss();
12976                final long myTotalUss = mi.getTotalUss();
12977
12978                synchronized (this) {
12979                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12980                        // Record this for posterity if the process has been stable.
12981                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12982                    }
12983                }
12984
12985                if (!isCheckinRequest && mi != null) {
12986                    totalPss += myTotalPss;
12987                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12988                            (hasActivities ? " / activities)" : ")"),
12989                            r.processName, myTotalPss, pid, hasActivities);
12990                    procMems.add(pssItem);
12991                    procMemsMap.put(pid, pssItem);
12992
12993                    nativePss += mi.nativePss;
12994                    dalvikPss += mi.dalvikPss;
12995                    otherPss += mi.otherPss;
12996                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12997                        long mem = mi.getOtherPss(j);
12998                        miscPss[j] += mem;
12999                        otherPss -= mem;
13000                    }
13001
13002                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13003                        cachedPss += myTotalPss;
13004                    }
13005
13006                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13007                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13008                                || oomIndex == (oomPss.length-1)) {
13009                            oomPss[oomIndex] += myTotalPss;
13010                            if (oomProcs[oomIndex] == null) {
13011                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13012                            }
13013                            oomProcs[oomIndex].add(pssItem);
13014                            break;
13015                        }
13016                    }
13017                }
13018            }
13019        }
13020
13021        long nativeProcTotalPss = 0;
13022
13023        if (!isCheckinRequest && procs.size() > 1) {
13024            // If we are showing aggregations, also look for native processes to
13025            // include so that our aggregations are more accurate.
13026            updateCpuStatsNow();
13027            synchronized (mProcessCpuThread) {
13028                final int N = mProcessCpuTracker.countStats();
13029                for (int i=0; i<N; i++) {
13030                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13031                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13032                        if (mi == null) {
13033                            mi = new Debug.MemoryInfo();
13034                        }
13035                        if (!brief && !oomOnly) {
13036                            Debug.getMemoryInfo(st.pid, mi);
13037                        } else {
13038                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13039                            mi.nativePrivateDirty = (int)tmpLong[0];
13040                        }
13041
13042                        final long myTotalPss = mi.getTotalPss();
13043                        totalPss += myTotalPss;
13044                        nativeProcTotalPss += myTotalPss;
13045
13046                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13047                                st.name, myTotalPss, st.pid, false);
13048                        procMems.add(pssItem);
13049
13050                        nativePss += mi.nativePss;
13051                        dalvikPss += mi.dalvikPss;
13052                        otherPss += mi.otherPss;
13053                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13054                            long mem = mi.getOtherPss(j);
13055                            miscPss[j] += mem;
13056                            otherPss -= mem;
13057                        }
13058                        oomPss[0] += myTotalPss;
13059                        if (oomProcs[0] == null) {
13060                            oomProcs[0] = new ArrayList<MemItem>();
13061                        }
13062                        oomProcs[0].add(pssItem);
13063                    }
13064                }
13065            }
13066
13067            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13068
13069            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13070            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13071            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13072            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13073                String label = Debug.MemoryInfo.getOtherLabel(j);
13074                catMems.add(new MemItem(label, label, miscPss[j], j));
13075            }
13076
13077            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13078            for (int j=0; j<oomPss.length; j++) {
13079                if (oomPss[j] != 0) {
13080                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13081                            : DUMP_MEM_OOM_LABEL[j];
13082                    MemItem item = new MemItem(label, label, oomPss[j],
13083                            DUMP_MEM_OOM_ADJ[j]);
13084                    item.subitems = oomProcs[j];
13085                    oomMems.add(item);
13086                }
13087            }
13088
13089            if (!brief && !oomOnly && !isCompact) {
13090                pw.println();
13091                pw.println("Total PSS by process:");
13092                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13093                pw.println();
13094            }
13095            if (!isCompact) {
13096                pw.println("Total PSS by OOM adjustment:");
13097            }
13098            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13099            if (!brief && !oomOnly) {
13100                PrintWriter out = categoryPw != null ? categoryPw : pw;
13101                if (!isCompact) {
13102                    out.println();
13103                    out.println("Total PSS by category:");
13104                }
13105                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13106            }
13107            if (!isCompact) {
13108                pw.println();
13109            }
13110            MemInfoReader memInfo = new MemInfoReader();
13111            memInfo.readMemInfo();
13112            if (nativeProcTotalPss > 0) {
13113                synchronized (this) {
13114                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13115                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13116                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13117                            nativeProcTotalPss);
13118                }
13119            }
13120            if (!brief) {
13121                if (!isCompact) {
13122                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13123                    pw.print(" kB (status ");
13124                    switch (mLastMemoryLevel) {
13125                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13126                            pw.println("normal)");
13127                            break;
13128                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13129                            pw.println("moderate)");
13130                            break;
13131                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13132                            pw.println("low)");
13133                            break;
13134                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13135                            pw.println("critical)");
13136                            break;
13137                        default:
13138                            pw.print(mLastMemoryLevel);
13139                            pw.println(")");
13140                            break;
13141                    }
13142                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13143                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13144                            pw.print(cachedPss); pw.print(" cached pss + ");
13145                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13146                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13147                } else {
13148                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13149                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13150                            + memInfo.getFreeSizeKb()); pw.print(",");
13151                    pw.println(totalPss - cachedPss);
13152                }
13153            }
13154            if (!isCompact) {
13155                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13156                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13157                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13158                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13159                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13160                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13161                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13162                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13163                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13164                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13165                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13166            }
13167            if (!brief) {
13168                if (memInfo.getZramTotalSizeKb() != 0) {
13169                    if (!isCompact) {
13170                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13171                                pw.print(" kB physical used for ");
13172                                pw.print(memInfo.getSwapTotalSizeKb()
13173                                        - memInfo.getSwapFreeSizeKb());
13174                                pw.print(" kB in swap (");
13175                                pw.print(memInfo.getSwapTotalSizeKb());
13176                                pw.println(" kB total swap)");
13177                    } else {
13178                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13179                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13180                                pw.println(memInfo.getSwapFreeSizeKb());
13181                    }
13182                }
13183                final int[] SINGLE_LONG_FORMAT = new int[] {
13184                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13185                };
13186                long[] longOut = new long[1];
13187                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13188                        SINGLE_LONG_FORMAT, null, longOut, null);
13189                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13190                longOut[0] = 0;
13191                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13192                        SINGLE_LONG_FORMAT, null, longOut, null);
13193                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13194                longOut[0] = 0;
13195                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13196                        SINGLE_LONG_FORMAT, null, longOut, null);
13197                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13198                longOut[0] = 0;
13199                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13200                        SINGLE_LONG_FORMAT, null, longOut, null);
13201                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13202                if (!isCompact) {
13203                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13204                        pw.print("      KSM: "); pw.print(sharing);
13205                                pw.print(" kB saved from shared ");
13206                                pw.print(shared); pw.println(" kB");
13207                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13208                                pw.print(voltile); pw.println(" kB volatile");
13209                    }
13210                    pw.print("   Tuning: ");
13211                    pw.print(ActivityManager.staticGetMemoryClass());
13212                    pw.print(" (large ");
13213                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13214                    pw.print("), oom ");
13215                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13216                    pw.print(" kB");
13217                    pw.print(", restore limit ");
13218                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13219                    pw.print(" kB");
13220                    if (ActivityManager.isLowRamDeviceStatic()) {
13221                        pw.print(" (low-ram)");
13222                    }
13223                    if (ActivityManager.isHighEndGfx()) {
13224                        pw.print(" (high-end-gfx)");
13225                    }
13226                    pw.println();
13227                } else {
13228                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13229                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13230                    pw.println(voltile);
13231                    pw.print("tuning,");
13232                    pw.print(ActivityManager.staticGetMemoryClass());
13233                    pw.print(',');
13234                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13235                    pw.print(',');
13236                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13237                    if (ActivityManager.isLowRamDeviceStatic()) {
13238                        pw.print(",low-ram");
13239                    }
13240                    if (ActivityManager.isHighEndGfx()) {
13241                        pw.print(",high-end-gfx");
13242                    }
13243                    pw.println();
13244                }
13245            }
13246        }
13247    }
13248
13249    /**
13250     * Searches array of arguments for the specified string
13251     * @param args array of argument strings
13252     * @param value value to search for
13253     * @return true if the value is contained in the array
13254     */
13255    private static boolean scanArgs(String[] args, String value) {
13256        if (args != null) {
13257            for (String arg : args) {
13258                if (value.equals(arg)) {
13259                    return true;
13260                }
13261            }
13262        }
13263        return false;
13264    }
13265
13266    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13267            ContentProviderRecord cpr, boolean always) {
13268        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13269
13270        if (!inLaunching || always) {
13271            synchronized (cpr) {
13272                cpr.launchingApp = null;
13273                cpr.notifyAll();
13274            }
13275            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13276            String names[] = cpr.info.authority.split(";");
13277            for (int j = 0; j < names.length; j++) {
13278                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13279            }
13280        }
13281
13282        for (int i=0; i<cpr.connections.size(); i++) {
13283            ContentProviderConnection conn = cpr.connections.get(i);
13284            if (conn.waiting) {
13285                // If this connection is waiting for the provider, then we don't
13286                // need to mess with its process unless we are always removing
13287                // or for some reason the provider is not currently launching.
13288                if (inLaunching && !always) {
13289                    continue;
13290                }
13291            }
13292            ProcessRecord capp = conn.client;
13293            conn.dead = true;
13294            if (conn.stableCount > 0) {
13295                if (!capp.persistent && capp.thread != null
13296                        && capp.pid != 0
13297                        && capp.pid != MY_PID) {
13298                    killUnneededProcessLocked(capp, "depends on provider "
13299                            + cpr.name.flattenToShortString()
13300                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13301                }
13302            } else if (capp.thread != null && conn.provider.provider != null) {
13303                try {
13304                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13305                } catch (RemoteException e) {
13306                }
13307                // In the protocol here, we don't expect the client to correctly
13308                // clean up this connection, we'll just remove it.
13309                cpr.connections.remove(i);
13310                conn.client.conProviders.remove(conn);
13311            }
13312        }
13313
13314        if (inLaunching && always) {
13315            mLaunchingProviders.remove(cpr);
13316        }
13317        return inLaunching;
13318    }
13319
13320    /**
13321     * Main code for cleaning up a process when it has gone away.  This is
13322     * called both as a result of the process dying, or directly when stopping
13323     * a process when running in single process mode.
13324     */
13325    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13326            boolean restarting, boolean allowRestart, int index) {
13327        if (index >= 0) {
13328            removeLruProcessLocked(app);
13329            ProcessList.remove(app.pid);
13330        }
13331
13332        mProcessesToGc.remove(app);
13333        mPendingPssProcesses.remove(app);
13334
13335        // Dismiss any open dialogs.
13336        if (app.crashDialog != null && !app.forceCrashReport) {
13337            app.crashDialog.dismiss();
13338            app.crashDialog = null;
13339        }
13340        if (app.anrDialog != null) {
13341            app.anrDialog.dismiss();
13342            app.anrDialog = null;
13343        }
13344        if (app.waitDialog != null) {
13345            app.waitDialog.dismiss();
13346            app.waitDialog = null;
13347        }
13348
13349        app.crashing = false;
13350        app.notResponding = false;
13351
13352        app.resetPackageList(mProcessStats);
13353        app.unlinkDeathRecipient();
13354        app.makeInactive(mProcessStats);
13355        app.waitingToKill = null;
13356        app.forcingToForeground = null;
13357        updateProcessForegroundLocked(app, false, false);
13358        app.foregroundActivities = false;
13359        app.hasShownUi = false;
13360        app.treatLikeActivity = false;
13361        app.hasAboveClient = false;
13362        app.hasClientActivities = false;
13363
13364        mServices.killServicesLocked(app, allowRestart);
13365
13366        boolean restart = false;
13367
13368        // Remove published content providers.
13369        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13370            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13371            final boolean always = app.bad || !allowRestart;
13372            if (removeDyingProviderLocked(app, cpr, always) || always) {
13373                // We left the provider in the launching list, need to
13374                // restart it.
13375                restart = true;
13376            }
13377
13378            cpr.provider = null;
13379            cpr.proc = null;
13380        }
13381        app.pubProviders.clear();
13382
13383        // Take care of any launching providers waiting for this process.
13384        if (checkAppInLaunchingProvidersLocked(app, false)) {
13385            restart = true;
13386        }
13387
13388        // Unregister from connected content providers.
13389        if (!app.conProviders.isEmpty()) {
13390            for (int i=0; i<app.conProviders.size(); i++) {
13391                ContentProviderConnection conn = app.conProviders.get(i);
13392                conn.provider.connections.remove(conn);
13393            }
13394            app.conProviders.clear();
13395        }
13396
13397        // At this point there may be remaining entries in mLaunchingProviders
13398        // where we were the only one waiting, so they are no longer of use.
13399        // Look for these and clean up if found.
13400        // XXX Commented out for now.  Trying to figure out a way to reproduce
13401        // the actual situation to identify what is actually going on.
13402        if (false) {
13403            for (int i=0; i<mLaunchingProviders.size(); i++) {
13404                ContentProviderRecord cpr = (ContentProviderRecord)
13405                        mLaunchingProviders.get(i);
13406                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13407                    synchronized (cpr) {
13408                        cpr.launchingApp = null;
13409                        cpr.notifyAll();
13410                    }
13411                }
13412            }
13413        }
13414
13415        skipCurrentReceiverLocked(app);
13416
13417        // Unregister any receivers.
13418        for (int i=app.receivers.size()-1; i>=0; i--) {
13419            removeReceiverLocked(app.receivers.valueAt(i));
13420        }
13421        app.receivers.clear();
13422
13423        // If the app is undergoing backup, tell the backup manager about it
13424        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13425            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13426                    + mBackupTarget.appInfo + " died during backup");
13427            try {
13428                IBackupManager bm = IBackupManager.Stub.asInterface(
13429                        ServiceManager.getService(Context.BACKUP_SERVICE));
13430                bm.agentDisconnected(app.info.packageName);
13431            } catch (RemoteException e) {
13432                // can't happen; backup manager is local
13433            }
13434        }
13435
13436        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13437            ProcessChangeItem item = mPendingProcessChanges.get(i);
13438            if (item.pid == app.pid) {
13439                mPendingProcessChanges.remove(i);
13440                mAvailProcessChanges.add(item);
13441            }
13442        }
13443        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13444
13445        // If the caller is restarting this app, then leave it in its
13446        // current lists and let the caller take care of it.
13447        if (restarting) {
13448            return;
13449        }
13450
13451        if (!app.persistent || app.isolated) {
13452            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13453                    "Removing non-persistent process during cleanup: " + app);
13454            mProcessNames.remove(app.processName, app.uid);
13455            mIsolatedProcesses.remove(app.uid);
13456            if (mHeavyWeightProcess == app) {
13457                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13458                        mHeavyWeightProcess.userId, 0));
13459                mHeavyWeightProcess = null;
13460            }
13461        } else if (!app.removed) {
13462            // This app is persistent, so we need to keep its record around.
13463            // If it is not already on the pending app list, add it there
13464            // and start a new process for it.
13465            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13466                mPersistentStartingProcesses.add(app);
13467                restart = true;
13468            }
13469        }
13470        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13471                "Clean-up removing on hold: " + app);
13472        mProcessesOnHold.remove(app);
13473
13474        if (app == mHomeProcess) {
13475            mHomeProcess = null;
13476        }
13477        if (app == mPreviousProcess) {
13478            mPreviousProcess = null;
13479        }
13480
13481        if (restart && !app.isolated) {
13482            // We have components that still need to be running in the
13483            // process, so re-launch it.
13484            mProcessNames.put(app.processName, app.uid, app);
13485            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13486        } else if (app.pid > 0 && app.pid != MY_PID) {
13487            // Goodbye!
13488            boolean removed;
13489            synchronized (mPidsSelfLocked) {
13490                mPidsSelfLocked.remove(app.pid);
13491                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13492            }
13493            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13494            if (app.isolated) {
13495                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13496            }
13497            app.setPid(0);
13498        }
13499    }
13500
13501    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13502        // Look through the content providers we are waiting to have launched,
13503        // and if any run in this process then either schedule a restart of
13504        // the process or kill the client waiting for it if this process has
13505        // gone bad.
13506        int NL = mLaunchingProviders.size();
13507        boolean restart = false;
13508        for (int i=0; i<NL; i++) {
13509            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13510            if (cpr.launchingApp == app) {
13511                if (!alwaysBad && !app.bad) {
13512                    restart = true;
13513                } else {
13514                    removeDyingProviderLocked(app, cpr, true);
13515                    // cpr should have been removed from mLaunchingProviders
13516                    NL = mLaunchingProviders.size();
13517                    i--;
13518                }
13519            }
13520        }
13521        return restart;
13522    }
13523
13524    // =========================================================
13525    // SERVICES
13526    // =========================================================
13527
13528    @Override
13529    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13530            int flags) {
13531        enforceNotIsolatedCaller("getServices");
13532        synchronized (this) {
13533            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13534        }
13535    }
13536
13537    @Override
13538    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13539        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13540        synchronized (this) {
13541            return mServices.getRunningServiceControlPanelLocked(name);
13542        }
13543    }
13544
13545    @Override
13546    public ComponentName startService(IApplicationThread caller, Intent service,
13547            String resolvedType, int userId) {
13548        enforceNotIsolatedCaller("startService");
13549        // Refuse possible leaked file descriptors
13550        if (service != null && service.hasFileDescriptors() == true) {
13551            throw new IllegalArgumentException("File descriptors passed in Intent");
13552        }
13553
13554        if (DEBUG_SERVICE)
13555            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13556        synchronized(this) {
13557            final int callingPid = Binder.getCallingPid();
13558            final int callingUid = Binder.getCallingUid();
13559            final long origId = Binder.clearCallingIdentity();
13560            ComponentName res = mServices.startServiceLocked(caller, service,
13561                    resolvedType, callingPid, callingUid, userId);
13562            Binder.restoreCallingIdentity(origId);
13563            return res;
13564        }
13565    }
13566
13567    ComponentName startServiceInPackage(int uid,
13568            Intent service, String resolvedType, int userId) {
13569        synchronized(this) {
13570            if (DEBUG_SERVICE)
13571                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13572            final long origId = Binder.clearCallingIdentity();
13573            ComponentName res = mServices.startServiceLocked(null, service,
13574                    resolvedType, -1, uid, userId);
13575            Binder.restoreCallingIdentity(origId);
13576            return res;
13577        }
13578    }
13579
13580    @Override
13581    public int stopService(IApplicationThread caller, Intent service,
13582            String resolvedType, int userId) {
13583        enforceNotIsolatedCaller("stopService");
13584        // Refuse possible leaked file descriptors
13585        if (service != null && service.hasFileDescriptors() == true) {
13586            throw new IllegalArgumentException("File descriptors passed in Intent");
13587        }
13588
13589        synchronized(this) {
13590            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13591        }
13592    }
13593
13594    @Override
13595    public IBinder peekService(Intent service, String resolvedType) {
13596        enforceNotIsolatedCaller("peekService");
13597        // Refuse possible leaked file descriptors
13598        if (service != null && service.hasFileDescriptors() == true) {
13599            throw new IllegalArgumentException("File descriptors passed in Intent");
13600        }
13601        synchronized(this) {
13602            return mServices.peekServiceLocked(service, resolvedType);
13603        }
13604    }
13605
13606    @Override
13607    public boolean stopServiceToken(ComponentName className, IBinder token,
13608            int startId) {
13609        synchronized(this) {
13610            return mServices.stopServiceTokenLocked(className, token, startId);
13611        }
13612    }
13613
13614    @Override
13615    public void setServiceForeground(ComponentName className, IBinder token,
13616            int id, Notification notification, boolean removeNotification) {
13617        synchronized(this) {
13618            mServices.setServiceForegroundLocked(className, token, id, notification,
13619                    removeNotification);
13620        }
13621    }
13622
13623    @Override
13624    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13625            boolean requireFull, String name, String callerPackage) {
13626        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13627                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13628    }
13629
13630    int unsafeConvertIncomingUser(int userId) {
13631        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13632                ? mCurrentUserId : userId;
13633    }
13634
13635    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13636            int allowMode, String name, String callerPackage) {
13637        final int callingUserId = UserHandle.getUserId(callingUid);
13638        if (callingUserId == userId) {
13639            return userId;
13640        }
13641
13642        // Note that we may be accessing mCurrentUserId outside of a lock...
13643        // shouldn't be a big deal, if this is being called outside
13644        // of a locked context there is intrinsically a race with
13645        // the value the caller will receive and someone else changing it.
13646        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13647        // we will switch to the calling user if access to the current user fails.
13648        int targetUserId = unsafeConvertIncomingUser(userId);
13649
13650        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13651            final boolean allow;
13652            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13653                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13654                // If the caller has this permission, they always pass go.  And collect $200.
13655                allow = true;
13656            } else if (allowMode == ALLOW_FULL_ONLY) {
13657                // We require full access, sucks to be you.
13658                allow = false;
13659            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13660                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13661                // If the caller does not have either permission, they are always doomed.
13662                allow = false;
13663            } else if (allowMode == ALLOW_NON_FULL) {
13664                // We are blanket allowing non-full access, you lucky caller!
13665                allow = true;
13666            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13667                // We may or may not allow this depending on whether the two users are
13668                // in the same profile.
13669                synchronized (mUserProfileGroupIdsSelfLocked) {
13670                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13671                            UserInfo.NO_PROFILE_GROUP_ID);
13672                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13673                            UserInfo.NO_PROFILE_GROUP_ID);
13674                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13675                            && callingProfile == targetProfile;
13676                }
13677            } else {
13678                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13679            }
13680            if (!allow) {
13681                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13682                    // In this case, they would like to just execute as their
13683                    // owner user instead of failing.
13684                    targetUserId = callingUserId;
13685                } else {
13686                    StringBuilder builder = new StringBuilder(128);
13687                    builder.append("Permission Denial: ");
13688                    builder.append(name);
13689                    if (callerPackage != null) {
13690                        builder.append(" from ");
13691                        builder.append(callerPackage);
13692                    }
13693                    builder.append(" asks to run as user ");
13694                    builder.append(userId);
13695                    builder.append(" but is calling from user ");
13696                    builder.append(UserHandle.getUserId(callingUid));
13697                    builder.append("; this requires ");
13698                    builder.append(INTERACT_ACROSS_USERS_FULL);
13699                    if (allowMode != ALLOW_FULL_ONLY) {
13700                        builder.append(" or ");
13701                        builder.append(INTERACT_ACROSS_USERS);
13702                    }
13703                    String msg = builder.toString();
13704                    Slog.w(TAG, msg);
13705                    throw new SecurityException(msg);
13706                }
13707            }
13708        }
13709        if (!allowAll && targetUserId < 0) {
13710            throw new IllegalArgumentException(
13711                    "Call does not support special user #" + targetUserId);
13712        }
13713        return targetUserId;
13714    }
13715
13716    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13717            String className, int flags) {
13718        boolean result = false;
13719        // For apps that don't have pre-defined UIDs, check for permission
13720        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13721            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13722                if (ActivityManager.checkUidPermission(
13723                        INTERACT_ACROSS_USERS,
13724                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13725                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13726                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13727                            + " requests FLAG_SINGLE_USER, but app does not hold "
13728                            + INTERACT_ACROSS_USERS;
13729                    Slog.w(TAG, msg);
13730                    throw new SecurityException(msg);
13731                }
13732                // Permission passed
13733                result = true;
13734            }
13735        } else if ("system".equals(componentProcessName)) {
13736            result = true;
13737        } else {
13738            // App with pre-defined UID, check if it's a persistent app
13739            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13740        }
13741        if (DEBUG_MU) {
13742            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13743                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13744        }
13745        return result;
13746    }
13747
13748    /**
13749     * Checks to see if the caller is in the same app as the singleton
13750     * component, or the component is in a special app. It allows special apps
13751     * to export singleton components but prevents exporting singleton
13752     * components for regular apps.
13753     */
13754    boolean isValidSingletonCall(int callingUid, int componentUid) {
13755        int componentAppId = UserHandle.getAppId(componentUid);
13756        return UserHandle.isSameApp(callingUid, componentUid)
13757                || componentAppId == Process.SYSTEM_UID
13758                || componentAppId == Process.PHONE_UID
13759                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13760                        == PackageManager.PERMISSION_GRANTED;
13761    }
13762
13763    public int bindService(IApplicationThread caller, IBinder token,
13764            Intent service, String resolvedType,
13765            IServiceConnection connection, int flags, int userId) {
13766        enforceNotIsolatedCaller("bindService");
13767        // Refuse possible leaked file descriptors
13768        if (service != null && service.hasFileDescriptors() == true) {
13769            throw new IllegalArgumentException("File descriptors passed in Intent");
13770        }
13771
13772        synchronized(this) {
13773            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13774                    connection, flags, userId);
13775        }
13776    }
13777
13778    public boolean unbindService(IServiceConnection connection) {
13779        synchronized (this) {
13780            return mServices.unbindServiceLocked(connection);
13781        }
13782    }
13783
13784    public void publishService(IBinder token, Intent intent, IBinder service) {
13785        // Refuse possible leaked file descriptors
13786        if (intent != null && intent.hasFileDescriptors() == true) {
13787            throw new IllegalArgumentException("File descriptors passed in Intent");
13788        }
13789
13790        synchronized(this) {
13791            if (!(token instanceof ServiceRecord)) {
13792                throw new IllegalArgumentException("Invalid service token");
13793            }
13794            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13795        }
13796    }
13797
13798    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13799        // Refuse possible leaked file descriptors
13800        if (intent != null && intent.hasFileDescriptors() == true) {
13801            throw new IllegalArgumentException("File descriptors passed in Intent");
13802        }
13803
13804        synchronized(this) {
13805            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13806        }
13807    }
13808
13809    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13810        synchronized(this) {
13811            if (!(token instanceof ServiceRecord)) {
13812                throw new IllegalArgumentException("Invalid service token");
13813            }
13814            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13815        }
13816    }
13817
13818    // =========================================================
13819    // BACKUP AND RESTORE
13820    // =========================================================
13821
13822    // Cause the target app to be launched if necessary and its backup agent
13823    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13824    // activity manager to announce its creation.
13825    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13826        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13827        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13828
13829        synchronized(this) {
13830            // !!! TODO: currently no check here that we're already bound
13831            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13832            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13833            synchronized (stats) {
13834                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13835            }
13836
13837            // Backup agent is now in use, its package can't be stopped.
13838            try {
13839                AppGlobals.getPackageManager().setPackageStoppedState(
13840                        app.packageName, false, UserHandle.getUserId(app.uid));
13841            } catch (RemoteException e) {
13842            } catch (IllegalArgumentException e) {
13843                Slog.w(TAG, "Failed trying to unstop package "
13844                        + app.packageName + ": " + e);
13845            }
13846
13847            BackupRecord r = new BackupRecord(ss, app, backupMode);
13848            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13849                    ? new ComponentName(app.packageName, app.backupAgentName)
13850                    : new ComponentName("android", "FullBackupAgent");
13851            // startProcessLocked() returns existing proc's record if it's already running
13852            ProcessRecord proc = startProcessLocked(app.processName, app,
13853                    false, 0, "backup", hostingName, false, false, false);
13854            if (proc == null) {
13855                Slog.e(TAG, "Unable to start backup agent process " + r);
13856                return false;
13857            }
13858
13859            r.app = proc;
13860            mBackupTarget = r;
13861            mBackupAppName = app.packageName;
13862
13863            // Try not to kill the process during backup
13864            updateOomAdjLocked(proc);
13865
13866            // If the process is already attached, schedule the creation of the backup agent now.
13867            // If it is not yet live, this will be done when it attaches to the framework.
13868            if (proc.thread != null) {
13869                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13870                try {
13871                    proc.thread.scheduleCreateBackupAgent(app,
13872                            compatibilityInfoForPackageLocked(app), backupMode);
13873                } catch (RemoteException e) {
13874                    // Will time out on the backup manager side
13875                }
13876            } else {
13877                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13878            }
13879            // Invariants: at this point, the target app process exists and the application
13880            // is either already running or in the process of coming up.  mBackupTarget and
13881            // mBackupAppName describe the app, so that when it binds back to the AM we
13882            // know that it's scheduled for a backup-agent operation.
13883        }
13884
13885        return true;
13886    }
13887
13888    @Override
13889    public void clearPendingBackup() {
13890        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13891        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13892
13893        synchronized (this) {
13894            mBackupTarget = null;
13895            mBackupAppName = null;
13896        }
13897    }
13898
13899    // A backup agent has just come up
13900    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13901        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13902                + " = " + agent);
13903
13904        synchronized(this) {
13905            if (!agentPackageName.equals(mBackupAppName)) {
13906                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13907                return;
13908            }
13909        }
13910
13911        long oldIdent = Binder.clearCallingIdentity();
13912        try {
13913            IBackupManager bm = IBackupManager.Stub.asInterface(
13914                    ServiceManager.getService(Context.BACKUP_SERVICE));
13915            bm.agentConnected(agentPackageName, agent);
13916        } catch (RemoteException e) {
13917            // can't happen; the backup manager service is local
13918        } catch (Exception e) {
13919            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13920            e.printStackTrace();
13921        } finally {
13922            Binder.restoreCallingIdentity(oldIdent);
13923        }
13924    }
13925
13926    // done with this agent
13927    public void unbindBackupAgent(ApplicationInfo appInfo) {
13928        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13929        if (appInfo == null) {
13930            Slog.w(TAG, "unbind backup agent for null app");
13931            return;
13932        }
13933
13934        synchronized(this) {
13935            try {
13936                if (mBackupAppName == null) {
13937                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13938                    return;
13939                }
13940
13941                if (!mBackupAppName.equals(appInfo.packageName)) {
13942                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13943                    return;
13944                }
13945
13946                // Not backing this app up any more; reset its OOM adjustment
13947                final ProcessRecord proc = mBackupTarget.app;
13948                updateOomAdjLocked(proc);
13949
13950                // If the app crashed during backup, 'thread' will be null here
13951                if (proc.thread != null) {
13952                    try {
13953                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13954                                compatibilityInfoForPackageLocked(appInfo));
13955                    } catch (Exception e) {
13956                        Slog.e(TAG, "Exception when unbinding backup agent:");
13957                        e.printStackTrace();
13958                    }
13959                }
13960            } finally {
13961                mBackupTarget = null;
13962                mBackupAppName = null;
13963            }
13964        }
13965    }
13966    // =========================================================
13967    // BROADCASTS
13968    // =========================================================
13969
13970    private final List getStickiesLocked(String action, IntentFilter filter,
13971            List cur, int userId) {
13972        final ContentResolver resolver = mContext.getContentResolver();
13973        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13974        if (stickies == null) {
13975            return cur;
13976        }
13977        final ArrayList<Intent> list = stickies.get(action);
13978        if (list == null) {
13979            return cur;
13980        }
13981        int N = list.size();
13982        for (int i=0; i<N; i++) {
13983            Intent intent = list.get(i);
13984            if (filter.match(resolver, intent, true, TAG) >= 0) {
13985                if (cur == null) {
13986                    cur = new ArrayList<Intent>();
13987                }
13988                cur.add(intent);
13989            }
13990        }
13991        return cur;
13992    }
13993
13994    boolean isPendingBroadcastProcessLocked(int pid) {
13995        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13996                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13997    }
13998
13999    void skipPendingBroadcastLocked(int pid) {
14000            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14001            for (BroadcastQueue queue : mBroadcastQueues) {
14002                queue.skipPendingBroadcastLocked(pid);
14003            }
14004    }
14005
14006    // The app just attached; send any pending broadcasts that it should receive
14007    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14008        boolean didSomething = false;
14009        for (BroadcastQueue queue : mBroadcastQueues) {
14010            didSomething |= queue.sendPendingBroadcastsLocked(app);
14011        }
14012        return didSomething;
14013    }
14014
14015    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14016            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14017        enforceNotIsolatedCaller("registerReceiver");
14018        int callingUid;
14019        int callingPid;
14020        synchronized(this) {
14021            ProcessRecord callerApp = null;
14022            if (caller != null) {
14023                callerApp = getRecordForAppLocked(caller);
14024                if (callerApp == null) {
14025                    throw new SecurityException(
14026                            "Unable to find app for caller " + caller
14027                            + " (pid=" + Binder.getCallingPid()
14028                            + ") when registering receiver " + receiver);
14029                }
14030                if (callerApp.info.uid != Process.SYSTEM_UID &&
14031                        !callerApp.pkgList.containsKey(callerPackage) &&
14032                        !"android".equals(callerPackage)) {
14033                    throw new SecurityException("Given caller package " + callerPackage
14034                            + " is not running in process " + callerApp);
14035                }
14036                callingUid = callerApp.info.uid;
14037                callingPid = callerApp.pid;
14038            } else {
14039                callerPackage = null;
14040                callingUid = Binder.getCallingUid();
14041                callingPid = Binder.getCallingPid();
14042            }
14043
14044            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14045                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14046
14047            List allSticky = null;
14048
14049            // Look for any matching sticky broadcasts...
14050            Iterator actions = filter.actionsIterator();
14051            if (actions != null) {
14052                while (actions.hasNext()) {
14053                    String action = (String)actions.next();
14054                    allSticky = getStickiesLocked(action, filter, allSticky,
14055                            UserHandle.USER_ALL);
14056                    allSticky = getStickiesLocked(action, filter, allSticky,
14057                            UserHandle.getUserId(callingUid));
14058                }
14059            } else {
14060                allSticky = getStickiesLocked(null, filter, allSticky,
14061                        UserHandle.USER_ALL);
14062                allSticky = getStickiesLocked(null, filter, allSticky,
14063                        UserHandle.getUserId(callingUid));
14064            }
14065
14066            // The first sticky in the list is returned directly back to
14067            // the client.
14068            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14069
14070            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14071                    + ": " + sticky);
14072
14073            if (receiver == null) {
14074                return sticky;
14075            }
14076
14077            ReceiverList rl
14078                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14079            if (rl == null) {
14080                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14081                        userId, receiver);
14082                if (rl.app != null) {
14083                    rl.app.receivers.add(rl);
14084                } else {
14085                    try {
14086                        receiver.asBinder().linkToDeath(rl, 0);
14087                    } catch (RemoteException e) {
14088                        return sticky;
14089                    }
14090                    rl.linkedToDeath = true;
14091                }
14092                mRegisteredReceivers.put(receiver.asBinder(), rl);
14093            } else if (rl.uid != callingUid) {
14094                throw new IllegalArgumentException(
14095                        "Receiver requested to register for uid " + callingUid
14096                        + " was previously registered for uid " + rl.uid);
14097            } else if (rl.pid != callingPid) {
14098                throw new IllegalArgumentException(
14099                        "Receiver requested to register for pid " + callingPid
14100                        + " was previously registered for pid " + rl.pid);
14101            } else if (rl.userId != userId) {
14102                throw new IllegalArgumentException(
14103                        "Receiver requested to register for user " + userId
14104                        + " was previously registered for user " + rl.userId);
14105            }
14106            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14107                    permission, callingUid, userId);
14108            rl.add(bf);
14109            if (!bf.debugCheck()) {
14110                Slog.w(TAG, "==> For Dynamic broadast");
14111            }
14112            mReceiverResolver.addFilter(bf);
14113
14114            // Enqueue broadcasts for all existing stickies that match
14115            // this filter.
14116            if (allSticky != null) {
14117                ArrayList receivers = new ArrayList();
14118                receivers.add(bf);
14119
14120                int N = allSticky.size();
14121                for (int i=0; i<N; i++) {
14122                    Intent intent = (Intent)allSticky.get(i);
14123                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14124                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14125                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14126                            null, null, false, true, true, -1);
14127                    queue.enqueueParallelBroadcastLocked(r);
14128                    queue.scheduleBroadcastsLocked();
14129                }
14130            }
14131
14132            return sticky;
14133        }
14134    }
14135
14136    public void unregisterReceiver(IIntentReceiver receiver) {
14137        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14138
14139        final long origId = Binder.clearCallingIdentity();
14140        try {
14141            boolean doTrim = false;
14142
14143            synchronized(this) {
14144                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14145                if (rl != null) {
14146                    if (rl.curBroadcast != null) {
14147                        BroadcastRecord r = rl.curBroadcast;
14148                        final boolean doNext = finishReceiverLocked(
14149                                receiver.asBinder(), r.resultCode, r.resultData,
14150                                r.resultExtras, r.resultAbort);
14151                        if (doNext) {
14152                            doTrim = true;
14153                            r.queue.processNextBroadcast(false);
14154                        }
14155                    }
14156
14157                    if (rl.app != null) {
14158                        rl.app.receivers.remove(rl);
14159                    }
14160                    removeReceiverLocked(rl);
14161                    if (rl.linkedToDeath) {
14162                        rl.linkedToDeath = false;
14163                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14164                    }
14165                }
14166            }
14167
14168            // If we actually concluded any broadcasts, we might now be able
14169            // to trim the recipients' apps from our working set
14170            if (doTrim) {
14171                trimApplications();
14172                return;
14173            }
14174
14175        } finally {
14176            Binder.restoreCallingIdentity(origId);
14177        }
14178    }
14179
14180    void removeReceiverLocked(ReceiverList rl) {
14181        mRegisteredReceivers.remove(rl.receiver.asBinder());
14182        int N = rl.size();
14183        for (int i=0; i<N; i++) {
14184            mReceiverResolver.removeFilter(rl.get(i));
14185        }
14186    }
14187
14188    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14189        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14190            ProcessRecord r = mLruProcesses.get(i);
14191            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14192                try {
14193                    r.thread.dispatchPackageBroadcast(cmd, packages);
14194                } catch (RemoteException ex) {
14195                }
14196            }
14197        }
14198    }
14199
14200    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14201            int[] users) {
14202        List<ResolveInfo> receivers = null;
14203        try {
14204            HashSet<ComponentName> singleUserReceivers = null;
14205            boolean scannedFirstReceivers = false;
14206            for (int user : users) {
14207                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14208                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14209                if (user != 0 && newReceivers != null) {
14210                    // If this is not the primary user, we need to check for
14211                    // any receivers that should be filtered out.
14212                    for (int i=0; i<newReceivers.size(); i++) {
14213                        ResolveInfo ri = newReceivers.get(i);
14214                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14215                            newReceivers.remove(i);
14216                            i--;
14217                        }
14218                    }
14219                }
14220                if (newReceivers != null && newReceivers.size() == 0) {
14221                    newReceivers = null;
14222                }
14223                if (receivers == null) {
14224                    receivers = newReceivers;
14225                } else if (newReceivers != null) {
14226                    // We need to concatenate the additional receivers
14227                    // found with what we have do far.  This would be easy,
14228                    // but we also need to de-dup any receivers that are
14229                    // singleUser.
14230                    if (!scannedFirstReceivers) {
14231                        // Collect any single user receivers we had already retrieved.
14232                        scannedFirstReceivers = true;
14233                        for (int i=0; i<receivers.size(); i++) {
14234                            ResolveInfo ri = receivers.get(i);
14235                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14236                                ComponentName cn = new ComponentName(
14237                                        ri.activityInfo.packageName, ri.activityInfo.name);
14238                                if (singleUserReceivers == null) {
14239                                    singleUserReceivers = new HashSet<ComponentName>();
14240                                }
14241                                singleUserReceivers.add(cn);
14242                            }
14243                        }
14244                    }
14245                    // Add the new results to the existing results, tracking
14246                    // and de-dupping single user receivers.
14247                    for (int i=0; i<newReceivers.size(); i++) {
14248                        ResolveInfo ri = newReceivers.get(i);
14249                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14250                            ComponentName cn = new ComponentName(
14251                                    ri.activityInfo.packageName, ri.activityInfo.name);
14252                            if (singleUserReceivers == null) {
14253                                singleUserReceivers = new HashSet<ComponentName>();
14254                            }
14255                            if (!singleUserReceivers.contains(cn)) {
14256                                singleUserReceivers.add(cn);
14257                                receivers.add(ri);
14258                            }
14259                        } else {
14260                            receivers.add(ri);
14261                        }
14262                    }
14263                }
14264            }
14265        } catch (RemoteException ex) {
14266            // pm is in same process, this will never happen.
14267        }
14268        return receivers;
14269    }
14270
14271    private final int broadcastIntentLocked(ProcessRecord callerApp,
14272            String callerPackage, Intent intent, String resolvedType,
14273            IIntentReceiver resultTo, int resultCode, String resultData,
14274            Bundle map, String requiredPermission, int appOp,
14275            boolean ordered, boolean sticky, int callingPid, int callingUid,
14276            int userId) {
14277        intent = new Intent(intent);
14278
14279        // By default broadcasts do not go to stopped apps.
14280        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14281
14282        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14283            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14284            + " ordered=" + ordered + " userid=" + userId);
14285        if ((resultTo != null) && !ordered) {
14286            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14287        }
14288
14289        userId = handleIncomingUser(callingPid, callingUid, userId,
14290                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14291
14292        // Make sure that the user who is receiving this broadcast is started.
14293        // If not, we will just skip it.
14294
14295
14296        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14297            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14298                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14299                Slog.w(TAG, "Skipping broadcast of " + intent
14300                        + ": user " + userId + " is stopped");
14301                return ActivityManager.BROADCAST_SUCCESS;
14302            }
14303        }
14304
14305        /*
14306         * Prevent non-system code (defined here to be non-persistent
14307         * processes) from sending protected broadcasts.
14308         */
14309        int callingAppId = UserHandle.getAppId(callingUid);
14310        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14311            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14312            || callingAppId == Process.NFC_UID || callingUid == 0) {
14313            // Always okay.
14314        } else if (callerApp == null || !callerApp.persistent) {
14315            try {
14316                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14317                        intent.getAction())) {
14318                    String msg = "Permission Denial: not allowed to send broadcast "
14319                            + intent.getAction() + " from pid="
14320                            + callingPid + ", uid=" + callingUid;
14321                    Slog.w(TAG, msg);
14322                    throw new SecurityException(msg);
14323                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14324                    // Special case for compatibility: we don't want apps to send this,
14325                    // but historically it has not been protected and apps may be using it
14326                    // to poke their own app widget.  So, instead of making it protected,
14327                    // just limit it to the caller.
14328                    if (callerApp == null) {
14329                        String msg = "Permission Denial: not allowed to send broadcast "
14330                                + intent.getAction() + " from unknown caller.";
14331                        Slog.w(TAG, msg);
14332                        throw new SecurityException(msg);
14333                    } else if (intent.getComponent() != null) {
14334                        // They are good enough to send to an explicit component...  verify
14335                        // it is being sent to the calling app.
14336                        if (!intent.getComponent().getPackageName().equals(
14337                                callerApp.info.packageName)) {
14338                            String msg = "Permission Denial: not allowed to send broadcast "
14339                                    + intent.getAction() + " to "
14340                                    + intent.getComponent().getPackageName() + " from "
14341                                    + callerApp.info.packageName;
14342                            Slog.w(TAG, msg);
14343                            throw new SecurityException(msg);
14344                        }
14345                    } else {
14346                        // Limit broadcast to their own package.
14347                        intent.setPackage(callerApp.info.packageName);
14348                    }
14349                }
14350            } catch (RemoteException e) {
14351                Slog.w(TAG, "Remote exception", e);
14352                return ActivityManager.BROADCAST_SUCCESS;
14353            }
14354        }
14355
14356        // Handle special intents: if this broadcast is from the package
14357        // manager about a package being removed, we need to remove all of
14358        // its activities from the history stack.
14359        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14360                intent.getAction());
14361        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14362                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14363                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14364                || uidRemoved) {
14365            if (checkComponentPermission(
14366                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14367                    callingPid, callingUid, -1, true)
14368                    == PackageManager.PERMISSION_GRANTED) {
14369                if (uidRemoved) {
14370                    final Bundle intentExtras = intent.getExtras();
14371                    final int uid = intentExtras != null
14372                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14373                    if (uid >= 0) {
14374                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14375                        synchronized (bs) {
14376                            bs.removeUidStatsLocked(uid);
14377                        }
14378                        mAppOpsService.uidRemoved(uid);
14379                    }
14380                } else {
14381                    // If resources are unavailable just force stop all
14382                    // those packages and flush the attribute cache as well.
14383                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14384                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14385                        if (list != null && (list.length > 0)) {
14386                            for (String pkg : list) {
14387                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14388                                        "storage unmount");
14389                            }
14390                            sendPackageBroadcastLocked(
14391                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14392                        }
14393                    } else {
14394                        Uri data = intent.getData();
14395                        String ssp;
14396                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14397                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14398                                    intent.getAction());
14399                            boolean fullUninstall = removed &&
14400                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14401                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14402                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14403                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14404                                        false, fullUninstall, userId,
14405                                        removed ? "pkg removed" : "pkg changed");
14406                            }
14407                            if (removed) {
14408                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14409                                        new String[] {ssp}, userId);
14410                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14411                                    mAppOpsService.packageRemoved(
14412                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14413
14414                                    // Remove all permissions granted from/to this package
14415                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14416                                }
14417                            }
14418                        }
14419                    }
14420                }
14421            } else {
14422                String msg = "Permission Denial: " + intent.getAction()
14423                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14424                        + ", uid=" + callingUid + ")"
14425                        + " requires "
14426                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14427                Slog.w(TAG, msg);
14428                throw new SecurityException(msg);
14429            }
14430
14431        // Special case for adding a package: by default turn on compatibility
14432        // mode.
14433        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14434            Uri data = intent.getData();
14435            String ssp;
14436            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14437                mCompatModePackages.handlePackageAddedLocked(ssp,
14438                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14439            }
14440        }
14441
14442        /*
14443         * If this is the time zone changed action, queue up a message that will reset the timezone
14444         * of all currently running processes. This message will get queued up before the broadcast
14445         * happens.
14446         */
14447        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14448            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14449        }
14450
14451        /*
14452         * If the user set the time, let all running processes know.
14453         */
14454        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14455            final int is24Hour = intent.getBooleanExtra(
14456                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14457            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14458        }
14459
14460        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14461            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14462        }
14463
14464        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14465            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14466            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14467        }
14468
14469        // Add to the sticky list if requested.
14470        if (sticky) {
14471            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14472                    callingPid, callingUid)
14473                    != PackageManager.PERMISSION_GRANTED) {
14474                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14475                        + callingPid + ", uid=" + callingUid
14476                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14477                Slog.w(TAG, msg);
14478                throw new SecurityException(msg);
14479            }
14480            if (requiredPermission != null) {
14481                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14482                        + " and enforce permission " + requiredPermission);
14483                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14484            }
14485            if (intent.getComponent() != null) {
14486                throw new SecurityException(
14487                        "Sticky broadcasts can't target a specific component");
14488            }
14489            // We use userId directly here, since the "all" target is maintained
14490            // as a separate set of sticky broadcasts.
14491            if (userId != UserHandle.USER_ALL) {
14492                // But first, if this is not a broadcast to all users, then
14493                // make sure it doesn't conflict with an existing broadcast to
14494                // all users.
14495                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14496                        UserHandle.USER_ALL);
14497                if (stickies != null) {
14498                    ArrayList<Intent> list = stickies.get(intent.getAction());
14499                    if (list != null) {
14500                        int N = list.size();
14501                        int i;
14502                        for (i=0; i<N; i++) {
14503                            if (intent.filterEquals(list.get(i))) {
14504                                throw new IllegalArgumentException(
14505                                        "Sticky broadcast " + intent + " for user "
14506                                        + userId + " conflicts with existing global broadcast");
14507                            }
14508                        }
14509                    }
14510                }
14511            }
14512            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14513            if (stickies == null) {
14514                stickies = new ArrayMap<String, ArrayList<Intent>>();
14515                mStickyBroadcasts.put(userId, stickies);
14516            }
14517            ArrayList<Intent> list = stickies.get(intent.getAction());
14518            if (list == null) {
14519                list = new ArrayList<Intent>();
14520                stickies.put(intent.getAction(), list);
14521            }
14522            int N = list.size();
14523            int i;
14524            for (i=0; i<N; i++) {
14525                if (intent.filterEquals(list.get(i))) {
14526                    // This sticky already exists, replace it.
14527                    list.set(i, new Intent(intent));
14528                    break;
14529                }
14530            }
14531            if (i >= N) {
14532                list.add(new Intent(intent));
14533            }
14534        }
14535
14536        int[] users;
14537        if (userId == UserHandle.USER_ALL) {
14538            // Caller wants broadcast to go to all started users.
14539            users = mStartedUserArray;
14540        } else {
14541            // Caller wants broadcast to go to one specific user.
14542            users = new int[] {userId};
14543        }
14544
14545        // Figure out who all will receive this broadcast.
14546        List receivers = null;
14547        List<BroadcastFilter> registeredReceivers = null;
14548        // Need to resolve the intent to interested receivers...
14549        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14550                 == 0) {
14551            receivers = collectReceiverComponents(intent, resolvedType, users);
14552        }
14553        if (intent.getComponent() == null) {
14554            registeredReceivers = mReceiverResolver.queryIntent(intent,
14555                    resolvedType, false, userId);
14556        }
14557
14558        final boolean replacePending =
14559                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14560
14561        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14562                + " replacePending=" + replacePending);
14563
14564        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14565        if (!ordered && NR > 0) {
14566            // If we are not serializing this broadcast, then send the
14567            // registered receivers separately so they don't wait for the
14568            // components to be launched.
14569            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14570            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14571                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14572                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14573                    ordered, sticky, false, userId);
14574            if (DEBUG_BROADCAST) Slog.v(
14575                    TAG, "Enqueueing parallel broadcast " + r);
14576            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14577            if (!replaced) {
14578                queue.enqueueParallelBroadcastLocked(r);
14579                queue.scheduleBroadcastsLocked();
14580            }
14581            registeredReceivers = null;
14582            NR = 0;
14583        }
14584
14585        // Merge into one list.
14586        int ir = 0;
14587        if (receivers != null) {
14588            // A special case for PACKAGE_ADDED: do not allow the package
14589            // being added to see this broadcast.  This prevents them from
14590            // using this as a back door to get run as soon as they are
14591            // installed.  Maybe in the future we want to have a special install
14592            // broadcast or such for apps, but we'd like to deliberately make
14593            // this decision.
14594            String skipPackages[] = null;
14595            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14596                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14597                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14598                Uri data = intent.getData();
14599                if (data != null) {
14600                    String pkgName = data.getSchemeSpecificPart();
14601                    if (pkgName != null) {
14602                        skipPackages = new String[] { pkgName };
14603                    }
14604                }
14605            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14606                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14607            }
14608            if (skipPackages != null && (skipPackages.length > 0)) {
14609                for (String skipPackage : skipPackages) {
14610                    if (skipPackage != null) {
14611                        int NT = receivers.size();
14612                        for (int it=0; it<NT; it++) {
14613                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14614                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14615                                receivers.remove(it);
14616                                it--;
14617                                NT--;
14618                            }
14619                        }
14620                    }
14621                }
14622            }
14623
14624            int NT = receivers != null ? receivers.size() : 0;
14625            int it = 0;
14626            ResolveInfo curt = null;
14627            BroadcastFilter curr = null;
14628            while (it < NT && ir < NR) {
14629                if (curt == null) {
14630                    curt = (ResolveInfo)receivers.get(it);
14631                }
14632                if (curr == null) {
14633                    curr = registeredReceivers.get(ir);
14634                }
14635                if (curr.getPriority() >= curt.priority) {
14636                    // Insert this broadcast record into the final list.
14637                    receivers.add(it, curr);
14638                    ir++;
14639                    curr = null;
14640                    it++;
14641                    NT++;
14642                } else {
14643                    // Skip to the next ResolveInfo in the final list.
14644                    it++;
14645                    curt = null;
14646                }
14647            }
14648        }
14649        while (ir < NR) {
14650            if (receivers == null) {
14651                receivers = new ArrayList();
14652            }
14653            receivers.add(registeredReceivers.get(ir));
14654            ir++;
14655        }
14656
14657        if ((receivers != null && receivers.size() > 0)
14658                || resultTo != null) {
14659            BroadcastQueue queue = broadcastQueueForIntent(intent);
14660            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14661                    callerPackage, callingPid, callingUid, resolvedType,
14662                    requiredPermission, appOp, receivers, resultTo, resultCode,
14663                    resultData, map, ordered, sticky, false, userId);
14664            if (DEBUG_BROADCAST) Slog.v(
14665                    TAG, "Enqueueing ordered broadcast " + r
14666                    + ": prev had " + queue.mOrderedBroadcasts.size());
14667            if (DEBUG_BROADCAST) {
14668                int seq = r.intent.getIntExtra("seq", -1);
14669                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14670            }
14671            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14672            if (!replaced) {
14673                queue.enqueueOrderedBroadcastLocked(r);
14674                queue.scheduleBroadcastsLocked();
14675            }
14676        }
14677
14678        return ActivityManager.BROADCAST_SUCCESS;
14679    }
14680
14681    final Intent verifyBroadcastLocked(Intent intent) {
14682        // Refuse possible leaked file descriptors
14683        if (intent != null && intent.hasFileDescriptors() == true) {
14684            throw new IllegalArgumentException("File descriptors passed in Intent");
14685        }
14686
14687        int flags = intent.getFlags();
14688
14689        if (!mProcessesReady) {
14690            // if the caller really truly claims to know what they're doing, go
14691            // ahead and allow the broadcast without launching any receivers
14692            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14693                intent = new Intent(intent);
14694                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14695            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14696                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14697                        + " before boot completion");
14698                throw new IllegalStateException("Cannot broadcast before boot completed");
14699            }
14700        }
14701
14702        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14703            throw new IllegalArgumentException(
14704                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14705        }
14706
14707        return intent;
14708    }
14709
14710    public final int broadcastIntent(IApplicationThread caller,
14711            Intent intent, String resolvedType, IIntentReceiver resultTo,
14712            int resultCode, String resultData, Bundle map,
14713            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14714        enforceNotIsolatedCaller("broadcastIntent");
14715        synchronized(this) {
14716            intent = verifyBroadcastLocked(intent);
14717
14718            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14719            final int callingPid = Binder.getCallingPid();
14720            final int callingUid = Binder.getCallingUid();
14721            final long origId = Binder.clearCallingIdentity();
14722            int res = broadcastIntentLocked(callerApp,
14723                    callerApp != null ? callerApp.info.packageName : null,
14724                    intent, resolvedType, resultTo,
14725                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14726                    callingPid, callingUid, userId);
14727            Binder.restoreCallingIdentity(origId);
14728            return res;
14729        }
14730    }
14731
14732    int broadcastIntentInPackage(String packageName, int uid,
14733            Intent intent, String resolvedType, IIntentReceiver resultTo,
14734            int resultCode, String resultData, Bundle map,
14735            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14736        synchronized(this) {
14737            intent = verifyBroadcastLocked(intent);
14738
14739            final long origId = Binder.clearCallingIdentity();
14740            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14741                    resultTo, resultCode, resultData, map, requiredPermission,
14742                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14743            Binder.restoreCallingIdentity(origId);
14744            return res;
14745        }
14746    }
14747
14748    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14749        // Refuse possible leaked file descriptors
14750        if (intent != null && intent.hasFileDescriptors() == true) {
14751            throw new IllegalArgumentException("File descriptors passed in Intent");
14752        }
14753
14754        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14755                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14756
14757        synchronized(this) {
14758            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14759                    != PackageManager.PERMISSION_GRANTED) {
14760                String msg = "Permission Denial: unbroadcastIntent() from pid="
14761                        + Binder.getCallingPid()
14762                        + ", uid=" + Binder.getCallingUid()
14763                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14764                Slog.w(TAG, msg);
14765                throw new SecurityException(msg);
14766            }
14767            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14768            if (stickies != null) {
14769                ArrayList<Intent> list = stickies.get(intent.getAction());
14770                if (list != null) {
14771                    int N = list.size();
14772                    int i;
14773                    for (i=0; i<N; i++) {
14774                        if (intent.filterEquals(list.get(i))) {
14775                            list.remove(i);
14776                            break;
14777                        }
14778                    }
14779                    if (list.size() <= 0) {
14780                        stickies.remove(intent.getAction());
14781                    }
14782                }
14783                if (stickies.size() <= 0) {
14784                    mStickyBroadcasts.remove(userId);
14785                }
14786            }
14787        }
14788    }
14789
14790    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14791            String resultData, Bundle resultExtras, boolean resultAbort) {
14792        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14793        if (r == null) {
14794            Slog.w(TAG, "finishReceiver called but not found on queue");
14795            return false;
14796        }
14797
14798        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14799    }
14800
14801    void backgroundServicesFinishedLocked(int userId) {
14802        for (BroadcastQueue queue : mBroadcastQueues) {
14803            queue.backgroundServicesFinishedLocked(userId);
14804        }
14805    }
14806
14807    public void finishReceiver(IBinder who, int resultCode, String resultData,
14808            Bundle resultExtras, boolean resultAbort) {
14809        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14810
14811        // Refuse possible leaked file descriptors
14812        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14813            throw new IllegalArgumentException("File descriptors passed in Bundle");
14814        }
14815
14816        final long origId = Binder.clearCallingIdentity();
14817        try {
14818            boolean doNext = false;
14819            BroadcastRecord r;
14820
14821            synchronized(this) {
14822                r = broadcastRecordForReceiverLocked(who);
14823                if (r != null) {
14824                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14825                        resultData, resultExtras, resultAbort, true);
14826                }
14827            }
14828
14829            if (doNext) {
14830                r.queue.processNextBroadcast(false);
14831            }
14832            trimApplications();
14833        } finally {
14834            Binder.restoreCallingIdentity(origId);
14835        }
14836    }
14837
14838    // =========================================================
14839    // INSTRUMENTATION
14840    // =========================================================
14841
14842    public boolean startInstrumentation(ComponentName className,
14843            String profileFile, int flags, Bundle arguments,
14844            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14845            int userId, String abiOverride) {
14846        enforceNotIsolatedCaller("startInstrumentation");
14847        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14848                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14849        // Refuse possible leaked file descriptors
14850        if (arguments != null && arguments.hasFileDescriptors()) {
14851            throw new IllegalArgumentException("File descriptors passed in Bundle");
14852        }
14853
14854        synchronized(this) {
14855            InstrumentationInfo ii = null;
14856            ApplicationInfo ai = null;
14857            try {
14858                ii = mContext.getPackageManager().getInstrumentationInfo(
14859                    className, STOCK_PM_FLAGS);
14860                ai = AppGlobals.getPackageManager().getApplicationInfo(
14861                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14862            } catch (PackageManager.NameNotFoundException e) {
14863            } catch (RemoteException e) {
14864            }
14865            if (ii == null) {
14866                reportStartInstrumentationFailure(watcher, className,
14867                        "Unable to find instrumentation info for: " + className);
14868                return false;
14869            }
14870            if (ai == null) {
14871                reportStartInstrumentationFailure(watcher, className,
14872                        "Unable to find instrumentation target package: " + ii.targetPackage);
14873                return false;
14874            }
14875
14876            int match = mContext.getPackageManager().checkSignatures(
14877                    ii.targetPackage, ii.packageName);
14878            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14879                String msg = "Permission Denial: starting instrumentation "
14880                        + className + " from pid="
14881                        + Binder.getCallingPid()
14882                        + ", uid=" + Binder.getCallingPid()
14883                        + " not allowed because package " + ii.packageName
14884                        + " does not have a signature matching the target "
14885                        + ii.targetPackage;
14886                reportStartInstrumentationFailure(watcher, className, msg);
14887                throw new SecurityException(msg);
14888            }
14889
14890            final long origId = Binder.clearCallingIdentity();
14891            // Instrumentation can kill and relaunch even persistent processes
14892            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14893                    "start instr");
14894            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14895            app.instrumentationClass = className;
14896            app.instrumentationInfo = ai;
14897            app.instrumentationProfileFile = profileFile;
14898            app.instrumentationArguments = arguments;
14899            app.instrumentationWatcher = watcher;
14900            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14901            app.instrumentationResultClass = className;
14902            Binder.restoreCallingIdentity(origId);
14903        }
14904
14905        return true;
14906    }
14907
14908    /**
14909     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14910     * error to the logs, but if somebody is watching, send the report there too.  This enables
14911     * the "am" command to report errors with more information.
14912     *
14913     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14914     * @param cn The component name of the instrumentation.
14915     * @param report The error report.
14916     */
14917    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14918            ComponentName cn, String report) {
14919        Slog.w(TAG, report);
14920        try {
14921            if (watcher != null) {
14922                Bundle results = new Bundle();
14923                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14924                results.putString("Error", report);
14925                watcher.instrumentationStatus(cn, -1, results);
14926            }
14927        } catch (RemoteException e) {
14928            Slog.w(TAG, e);
14929        }
14930    }
14931
14932    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14933        if (app.instrumentationWatcher != null) {
14934            try {
14935                // NOTE:  IInstrumentationWatcher *must* be oneway here
14936                app.instrumentationWatcher.instrumentationFinished(
14937                    app.instrumentationClass,
14938                    resultCode,
14939                    results);
14940            } catch (RemoteException e) {
14941            }
14942        }
14943        if (app.instrumentationUiAutomationConnection != null) {
14944            try {
14945                app.instrumentationUiAutomationConnection.shutdown();
14946            } catch (RemoteException re) {
14947                /* ignore */
14948            }
14949            // Only a UiAutomation can set this flag and now that
14950            // it is finished we make sure it is reset to its default.
14951            mUserIsMonkey = false;
14952        }
14953        app.instrumentationWatcher = null;
14954        app.instrumentationUiAutomationConnection = null;
14955        app.instrumentationClass = null;
14956        app.instrumentationInfo = null;
14957        app.instrumentationProfileFile = null;
14958        app.instrumentationArguments = null;
14959
14960        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14961                "finished inst");
14962    }
14963
14964    public void finishInstrumentation(IApplicationThread target,
14965            int resultCode, Bundle results) {
14966        int userId = UserHandle.getCallingUserId();
14967        // Refuse possible leaked file descriptors
14968        if (results != null && results.hasFileDescriptors()) {
14969            throw new IllegalArgumentException("File descriptors passed in Intent");
14970        }
14971
14972        synchronized(this) {
14973            ProcessRecord app = getRecordForAppLocked(target);
14974            if (app == null) {
14975                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14976                return;
14977            }
14978            final long origId = Binder.clearCallingIdentity();
14979            finishInstrumentationLocked(app, resultCode, results);
14980            Binder.restoreCallingIdentity(origId);
14981        }
14982    }
14983
14984    // =========================================================
14985    // CONFIGURATION
14986    // =========================================================
14987
14988    public ConfigurationInfo getDeviceConfigurationInfo() {
14989        ConfigurationInfo config = new ConfigurationInfo();
14990        synchronized (this) {
14991            config.reqTouchScreen = mConfiguration.touchscreen;
14992            config.reqKeyboardType = mConfiguration.keyboard;
14993            config.reqNavigation = mConfiguration.navigation;
14994            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14995                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14996                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14997            }
14998            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14999                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15000                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15001            }
15002            config.reqGlEsVersion = GL_ES_VERSION;
15003        }
15004        return config;
15005    }
15006
15007    ActivityStack getFocusedStack() {
15008        return mStackSupervisor.getFocusedStack();
15009    }
15010
15011    public Configuration getConfiguration() {
15012        Configuration ci;
15013        synchronized(this) {
15014            ci = new Configuration(mConfiguration);
15015        }
15016        return ci;
15017    }
15018
15019    public void updatePersistentConfiguration(Configuration values) {
15020        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15021                "updateConfiguration()");
15022        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15023                "updateConfiguration()");
15024        if (values == null) {
15025            throw new NullPointerException("Configuration must not be null");
15026        }
15027
15028        synchronized(this) {
15029            final long origId = Binder.clearCallingIdentity();
15030            updateConfigurationLocked(values, null, true, false);
15031            Binder.restoreCallingIdentity(origId);
15032        }
15033    }
15034
15035    public void updateConfiguration(Configuration values) {
15036        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15037                "updateConfiguration()");
15038
15039        synchronized(this) {
15040            if (values == null && mWindowManager != null) {
15041                // sentinel: fetch the current configuration from the window manager
15042                values = mWindowManager.computeNewConfiguration();
15043            }
15044
15045            if (mWindowManager != null) {
15046                mProcessList.applyDisplaySize(mWindowManager);
15047            }
15048
15049            final long origId = Binder.clearCallingIdentity();
15050            if (values != null) {
15051                Settings.System.clearConfiguration(values);
15052            }
15053            updateConfigurationLocked(values, null, false, false);
15054            Binder.restoreCallingIdentity(origId);
15055        }
15056    }
15057
15058    /**
15059     * Do either or both things: (1) change the current configuration, and (2)
15060     * make sure the given activity is running with the (now) current
15061     * configuration.  Returns true if the activity has been left running, or
15062     * false if <var>starting</var> is being destroyed to match the new
15063     * configuration.
15064     * @param persistent TODO
15065     */
15066    boolean updateConfigurationLocked(Configuration values,
15067            ActivityRecord starting, boolean persistent, boolean initLocale) {
15068        int changes = 0;
15069
15070        if (values != null) {
15071            Configuration newConfig = new Configuration(mConfiguration);
15072            changes = newConfig.updateFrom(values);
15073            if (changes != 0) {
15074                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15075                    Slog.i(TAG, "Updating configuration to: " + values);
15076                }
15077
15078                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15079
15080                if (values.locale != null && !initLocale) {
15081                    saveLocaleLocked(values.locale,
15082                                     !values.locale.equals(mConfiguration.locale),
15083                                     values.userSetLocale);
15084                }
15085
15086                mConfigurationSeq++;
15087                if (mConfigurationSeq <= 0) {
15088                    mConfigurationSeq = 1;
15089                }
15090                newConfig.seq = mConfigurationSeq;
15091                mConfiguration = newConfig;
15092                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15093                //mUsageStatsService.noteStartConfig(newConfig);
15094
15095                final Configuration configCopy = new Configuration(mConfiguration);
15096
15097                // TODO: If our config changes, should we auto dismiss any currently
15098                // showing dialogs?
15099                mShowDialogs = shouldShowDialogs(newConfig);
15100
15101                AttributeCache ac = AttributeCache.instance();
15102                if (ac != null) {
15103                    ac.updateConfiguration(configCopy);
15104                }
15105
15106                // Make sure all resources in our process are updated
15107                // right now, so that anyone who is going to retrieve
15108                // resource values after we return will be sure to get
15109                // the new ones.  This is especially important during
15110                // boot, where the first config change needs to guarantee
15111                // all resources have that config before following boot
15112                // code is executed.
15113                mSystemThread.applyConfigurationToResources(configCopy);
15114
15115                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15116                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15117                    msg.obj = new Configuration(configCopy);
15118                    mHandler.sendMessage(msg);
15119                }
15120
15121                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15122                    ProcessRecord app = mLruProcesses.get(i);
15123                    try {
15124                        if (app.thread != null) {
15125                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15126                                    + app.processName + " new config " + mConfiguration);
15127                            app.thread.scheduleConfigurationChanged(configCopy);
15128                        }
15129                    } catch (Exception e) {
15130                    }
15131                }
15132                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15133                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15134                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15135                        | Intent.FLAG_RECEIVER_FOREGROUND);
15136                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15137                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15138                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15139                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15140                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15141                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15142                    broadcastIntentLocked(null, null, intent,
15143                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15144                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15145                }
15146            }
15147        }
15148
15149        boolean kept = true;
15150        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15151        // mainStack is null during startup.
15152        if (mainStack != null) {
15153            if (changes != 0 && starting == null) {
15154                // If the configuration changed, and the caller is not already
15155                // in the process of starting an activity, then find the top
15156                // activity to check if its configuration needs to change.
15157                starting = mainStack.topRunningActivityLocked(null);
15158            }
15159
15160            if (starting != null) {
15161                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15162                // And we need to make sure at this point that all other activities
15163                // are made visible with the correct configuration.
15164                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15165            }
15166        }
15167
15168        if (values != null && mWindowManager != null) {
15169            mWindowManager.setNewConfiguration(mConfiguration);
15170        }
15171
15172        return kept;
15173    }
15174
15175    /**
15176     * Decide based on the configuration whether we should shouw the ANR,
15177     * crash, etc dialogs.  The idea is that if there is no affordnace to
15178     * press the on-screen buttons, we shouldn't show the dialog.
15179     *
15180     * A thought: SystemUI might also want to get told about this, the Power
15181     * dialog / global actions also might want different behaviors.
15182     */
15183    private static final boolean shouldShowDialogs(Configuration config) {
15184        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15185                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15186    }
15187
15188    /**
15189     * Save the locale.  You must be inside a synchronized (this) block.
15190     */
15191    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15192        if(isDiff) {
15193            SystemProperties.set("user.language", l.getLanguage());
15194            SystemProperties.set("user.region", l.getCountry());
15195        }
15196
15197        if(isPersist) {
15198            SystemProperties.set("persist.sys.language", l.getLanguage());
15199            SystemProperties.set("persist.sys.country", l.getCountry());
15200            SystemProperties.set("persist.sys.localevar", l.getVariant());
15201        }
15202    }
15203
15204    @Override
15205    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15206        ActivityRecord srec = ActivityRecord.forToken(token);
15207        return srec != null && srec.task.affinity != null &&
15208                srec.task.affinity.equals(destAffinity);
15209    }
15210
15211    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15212            Intent resultData) {
15213
15214        synchronized (this) {
15215            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15216            if (stack != null) {
15217                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15218            }
15219            return false;
15220        }
15221    }
15222
15223    public int getLaunchedFromUid(IBinder activityToken) {
15224        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15225        if (srec == null) {
15226            return -1;
15227        }
15228        return srec.launchedFromUid;
15229    }
15230
15231    public String getLaunchedFromPackage(IBinder activityToken) {
15232        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15233        if (srec == null) {
15234            return null;
15235        }
15236        return srec.launchedFromPackage;
15237    }
15238
15239    // =========================================================
15240    // LIFETIME MANAGEMENT
15241    // =========================================================
15242
15243    // Returns which broadcast queue the app is the current [or imminent] receiver
15244    // on, or 'null' if the app is not an active broadcast recipient.
15245    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15246        BroadcastRecord r = app.curReceiver;
15247        if (r != null) {
15248            return r.queue;
15249        }
15250
15251        // It's not the current receiver, but it might be starting up to become one
15252        synchronized (this) {
15253            for (BroadcastQueue queue : mBroadcastQueues) {
15254                r = queue.mPendingBroadcast;
15255                if (r != null && r.curApp == app) {
15256                    // found it; report which queue it's in
15257                    return queue;
15258                }
15259            }
15260        }
15261
15262        return null;
15263    }
15264
15265    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15266            boolean doingAll, long now) {
15267        if (mAdjSeq == app.adjSeq) {
15268            // This adjustment has already been computed.
15269            return app.curRawAdj;
15270        }
15271
15272        if (app.thread == null) {
15273            app.adjSeq = mAdjSeq;
15274            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15275            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15276            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15277        }
15278
15279        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15280        app.adjSource = null;
15281        app.adjTarget = null;
15282        app.empty = false;
15283        app.cached = false;
15284
15285        final int activitiesSize = app.activities.size();
15286
15287        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15288            // The max adjustment doesn't allow this app to be anything
15289            // below foreground, so it is not worth doing work for it.
15290            app.adjType = "fixed";
15291            app.adjSeq = mAdjSeq;
15292            app.curRawAdj = app.maxAdj;
15293            app.foregroundActivities = false;
15294            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15295            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15296            // System processes can do UI, and when they do we want to have
15297            // them trim their memory after the user leaves the UI.  To
15298            // facilitate this, here we need to determine whether or not it
15299            // is currently showing UI.
15300            app.systemNoUi = true;
15301            if (app == TOP_APP) {
15302                app.systemNoUi = false;
15303            } else if (activitiesSize > 0) {
15304                for (int j = 0; j < activitiesSize; j++) {
15305                    final ActivityRecord r = app.activities.get(j);
15306                    if (r.visible) {
15307                        app.systemNoUi = false;
15308                    }
15309                }
15310            }
15311            if (!app.systemNoUi) {
15312                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15313            }
15314            return (app.curAdj=app.maxAdj);
15315        }
15316
15317        app.systemNoUi = false;
15318
15319        // Determine the importance of the process, starting with most
15320        // important to least, and assign an appropriate OOM adjustment.
15321        int adj;
15322        int schedGroup;
15323        int procState;
15324        boolean foregroundActivities = false;
15325        BroadcastQueue queue;
15326        if (app == TOP_APP) {
15327            // The last app on the list is the foreground app.
15328            adj = ProcessList.FOREGROUND_APP_ADJ;
15329            schedGroup = Process.THREAD_GROUP_DEFAULT;
15330            app.adjType = "top-activity";
15331            foregroundActivities = true;
15332            procState = ActivityManager.PROCESS_STATE_TOP;
15333        } else if (app.instrumentationClass != null) {
15334            // Don't want to kill running instrumentation.
15335            adj = ProcessList.FOREGROUND_APP_ADJ;
15336            schedGroup = Process.THREAD_GROUP_DEFAULT;
15337            app.adjType = "instrumentation";
15338            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15339        } else if ((queue = isReceivingBroadcast(app)) != null) {
15340            // An app that is currently receiving a broadcast also
15341            // counts as being in the foreground for OOM killer purposes.
15342            // It's placed in a sched group based on the nature of the
15343            // broadcast as reflected by which queue it's active in.
15344            adj = ProcessList.FOREGROUND_APP_ADJ;
15345            schedGroup = (queue == mFgBroadcastQueue)
15346                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15347            app.adjType = "broadcast";
15348            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15349        } else if (app.executingServices.size() > 0) {
15350            // An app that is currently executing a service callback also
15351            // counts as being in the foreground.
15352            adj = ProcessList.FOREGROUND_APP_ADJ;
15353            schedGroup = app.execServicesFg ?
15354                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15355            app.adjType = "exec-service";
15356            procState = ActivityManager.PROCESS_STATE_SERVICE;
15357            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15358        } else {
15359            // As far as we know the process is empty.  We may change our mind later.
15360            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15361            // At this point we don't actually know the adjustment.  Use the cached adj
15362            // value that the caller wants us to.
15363            adj = cachedAdj;
15364            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15365            app.cached = true;
15366            app.empty = true;
15367            app.adjType = "cch-empty";
15368        }
15369
15370        // Examine all activities if not already foreground.
15371        if (!foregroundActivities && activitiesSize > 0) {
15372            for (int j = 0; j < activitiesSize; j++) {
15373                final ActivityRecord r = app.activities.get(j);
15374                if (r.app != app) {
15375                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15376                            + app + "?!?");
15377                    continue;
15378                }
15379                if (r.visible) {
15380                    // App has a visible activity; only upgrade adjustment.
15381                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15382                        adj = ProcessList.VISIBLE_APP_ADJ;
15383                        app.adjType = "visible";
15384                    }
15385                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15386                        procState = ActivityManager.PROCESS_STATE_TOP;
15387                    }
15388                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15389                    app.cached = false;
15390                    app.empty = false;
15391                    foregroundActivities = true;
15392                    break;
15393                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15394                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15395                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15396                        app.adjType = "pausing";
15397                    }
15398                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15399                        procState = ActivityManager.PROCESS_STATE_TOP;
15400                    }
15401                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15402                    app.cached = false;
15403                    app.empty = false;
15404                    foregroundActivities = true;
15405                } else if (r.state == ActivityState.STOPPING) {
15406                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15407                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15408                        app.adjType = "stopping";
15409                    }
15410                    // For the process state, we will at this point consider the
15411                    // process to be cached.  It will be cached either as an activity
15412                    // or empty depending on whether the activity is finishing.  We do
15413                    // this so that we can treat the process as cached for purposes of
15414                    // memory trimming (determing current memory level, trim command to
15415                    // send to process) since there can be an arbitrary number of stopping
15416                    // processes and they should soon all go into the cached state.
15417                    if (!r.finishing) {
15418                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15419                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15420                        }
15421                    }
15422                    app.cached = false;
15423                    app.empty = false;
15424                    foregroundActivities = true;
15425                } else {
15426                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15427                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15428                        app.adjType = "cch-act";
15429                    }
15430                }
15431            }
15432        }
15433
15434        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15435            if (app.foregroundServices) {
15436                // The user is aware of this app, so make it visible.
15437                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15438                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15439                app.cached = false;
15440                app.adjType = "fg-service";
15441                schedGroup = Process.THREAD_GROUP_DEFAULT;
15442            } else if (app.forcingToForeground != null) {
15443                // The user is aware of this app, so make it visible.
15444                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15445                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15446                app.cached = false;
15447                app.adjType = "force-fg";
15448                app.adjSource = app.forcingToForeground;
15449                schedGroup = Process.THREAD_GROUP_DEFAULT;
15450            }
15451        }
15452
15453        if (app == mHeavyWeightProcess) {
15454            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15455                // We don't want to kill the current heavy-weight process.
15456                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15457                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15458                app.cached = false;
15459                app.adjType = "heavy";
15460            }
15461            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15462                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15463            }
15464        }
15465
15466        if (app == mHomeProcess) {
15467            if (adj > ProcessList.HOME_APP_ADJ) {
15468                // This process is hosting what we currently consider to be the
15469                // home app, so we don't want to let it go into the background.
15470                adj = ProcessList.HOME_APP_ADJ;
15471                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15472                app.cached = false;
15473                app.adjType = "home";
15474            }
15475            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15476                procState = ActivityManager.PROCESS_STATE_HOME;
15477            }
15478        }
15479
15480        if (app == mPreviousProcess && app.activities.size() > 0) {
15481            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15482                // This was the previous process that showed UI to the user.
15483                // We want to try to keep it around more aggressively, to give
15484                // a good experience around switching between two apps.
15485                adj = ProcessList.PREVIOUS_APP_ADJ;
15486                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15487                app.cached = false;
15488                app.adjType = "previous";
15489            }
15490            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15491                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15492            }
15493        }
15494
15495        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15496                + " reason=" + app.adjType);
15497
15498        // By default, we use the computed adjustment.  It may be changed if
15499        // there are applications dependent on our services or providers, but
15500        // this gives us a baseline and makes sure we don't get into an
15501        // infinite recursion.
15502        app.adjSeq = mAdjSeq;
15503        app.curRawAdj = adj;
15504        app.hasStartedServices = false;
15505
15506        if (mBackupTarget != null && app == mBackupTarget.app) {
15507            // If possible we want to avoid killing apps while they're being backed up
15508            if (adj > ProcessList.BACKUP_APP_ADJ) {
15509                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15510                adj = ProcessList.BACKUP_APP_ADJ;
15511                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15512                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15513                }
15514                app.adjType = "backup";
15515                app.cached = false;
15516            }
15517            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15518                procState = ActivityManager.PROCESS_STATE_BACKUP;
15519            }
15520        }
15521
15522        boolean mayBeTop = false;
15523
15524        for (int is = app.services.size()-1;
15525                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15526                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15527                        || procState > ActivityManager.PROCESS_STATE_TOP);
15528                is--) {
15529            ServiceRecord s = app.services.valueAt(is);
15530            if (s.startRequested) {
15531                app.hasStartedServices = true;
15532                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15533                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15534                }
15535                if (app.hasShownUi && app != mHomeProcess) {
15536                    // If this process has shown some UI, let it immediately
15537                    // go to the LRU list because it may be pretty heavy with
15538                    // UI stuff.  We'll tag it with a label just to help
15539                    // debug and understand what is going on.
15540                    if (adj > ProcessList.SERVICE_ADJ) {
15541                        app.adjType = "cch-started-ui-services";
15542                    }
15543                } else {
15544                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15545                        // This service has seen some activity within
15546                        // recent memory, so we will keep its process ahead
15547                        // of the background processes.
15548                        if (adj > ProcessList.SERVICE_ADJ) {
15549                            adj = ProcessList.SERVICE_ADJ;
15550                            app.adjType = "started-services";
15551                            app.cached = false;
15552                        }
15553                    }
15554                    // If we have let the service slide into the background
15555                    // state, still have some text describing what it is doing
15556                    // even though the service no longer has an impact.
15557                    if (adj > ProcessList.SERVICE_ADJ) {
15558                        app.adjType = "cch-started-services";
15559                    }
15560                }
15561            }
15562            for (int conni = s.connections.size()-1;
15563                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15564                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15565                            || procState > ActivityManager.PROCESS_STATE_TOP);
15566                    conni--) {
15567                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15568                for (int i = 0;
15569                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15570                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15571                                || procState > ActivityManager.PROCESS_STATE_TOP);
15572                        i++) {
15573                    // XXX should compute this based on the max of
15574                    // all connected clients.
15575                    ConnectionRecord cr = clist.get(i);
15576                    if (cr.binding.client == app) {
15577                        // Binding to ourself is not interesting.
15578                        continue;
15579                    }
15580                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15581                        ProcessRecord client = cr.binding.client;
15582                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15583                                TOP_APP, doingAll, now);
15584                        int clientProcState = client.curProcState;
15585                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15586                            // If the other app is cached for any reason, for purposes here
15587                            // we are going to consider it empty.  The specific cached state
15588                            // doesn't propagate except under certain conditions.
15589                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15590                        }
15591                        String adjType = null;
15592                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15593                            // Not doing bind OOM management, so treat
15594                            // this guy more like a started service.
15595                            if (app.hasShownUi && app != mHomeProcess) {
15596                                // If this process has shown some UI, let it immediately
15597                                // go to the LRU list because it may be pretty heavy with
15598                                // UI stuff.  We'll tag it with a label just to help
15599                                // debug and understand what is going on.
15600                                if (adj > clientAdj) {
15601                                    adjType = "cch-bound-ui-services";
15602                                }
15603                                app.cached = false;
15604                                clientAdj = adj;
15605                                clientProcState = procState;
15606                            } else {
15607                                if (now >= (s.lastActivity
15608                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15609                                    // This service has not seen activity within
15610                                    // recent memory, so allow it to drop to the
15611                                    // LRU list if there is no other reason to keep
15612                                    // it around.  We'll also tag it with a label just
15613                                    // to help debug and undertand what is going on.
15614                                    if (adj > clientAdj) {
15615                                        adjType = "cch-bound-services";
15616                                    }
15617                                    clientAdj = adj;
15618                                }
15619                            }
15620                        }
15621                        if (adj > clientAdj) {
15622                            // If this process has recently shown UI, and
15623                            // the process that is binding to it is less
15624                            // important than being visible, then we don't
15625                            // care about the binding as much as we care
15626                            // about letting this process get into the LRU
15627                            // list to be killed and restarted if needed for
15628                            // memory.
15629                            if (app.hasShownUi && app != mHomeProcess
15630                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15631                                adjType = "cch-bound-ui-services";
15632                            } else {
15633                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15634                                        |Context.BIND_IMPORTANT)) != 0) {
15635                                    adj = clientAdj;
15636                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15637                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15638                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15639                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15640                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15641                                    adj = clientAdj;
15642                                } else {
15643                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15644                                        adj = ProcessList.VISIBLE_APP_ADJ;
15645                                    }
15646                                }
15647                                if (!client.cached) {
15648                                    app.cached = false;
15649                                }
15650                                adjType = "service";
15651                            }
15652                        }
15653                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15654                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15655                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15656                            }
15657                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15658                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15659                                    // Special handling of clients who are in the top state.
15660                                    // We *may* want to consider this process to be in the
15661                                    // top state as well, but only if there is not another
15662                                    // reason for it to be running.  Being on the top is a
15663                                    // special state, meaning you are specifically running
15664                                    // for the current top app.  If the process is already
15665                                    // running in the background for some other reason, it
15666                                    // is more important to continue considering it to be
15667                                    // in the background state.
15668                                    mayBeTop = true;
15669                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15670                                } else {
15671                                    // Special handling for above-top states (persistent
15672                                    // processes).  These should not bring the current process
15673                                    // into the top state, since they are not on top.  Instead
15674                                    // give them the best state after that.
15675                                    clientProcState =
15676                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15677                                }
15678                            }
15679                        } else {
15680                            if (clientProcState <
15681                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15682                                clientProcState =
15683                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15684                            }
15685                        }
15686                        if (procState > clientProcState) {
15687                            procState = clientProcState;
15688                        }
15689                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15690                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15691                            app.pendingUiClean = true;
15692                        }
15693                        if (adjType != null) {
15694                            app.adjType = adjType;
15695                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15696                                    .REASON_SERVICE_IN_USE;
15697                            app.adjSource = cr.binding.client;
15698                            app.adjSourceProcState = clientProcState;
15699                            app.adjTarget = s.name;
15700                        }
15701                    }
15702                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15703                        app.treatLikeActivity = true;
15704                    }
15705                    final ActivityRecord a = cr.activity;
15706                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15707                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15708                                (a.visible || a.state == ActivityState.RESUMED
15709                                 || a.state == ActivityState.PAUSING)) {
15710                            adj = ProcessList.FOREGROUND_APP_ADJ;
15711                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15712                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15713                            }
15714                            app.cached = false;
15715                            app.adjType = "service";
15716                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15717                                    .REASON_SERVICE_IN_USE;
15718                            app.adjSource = a;
15719                            app.adjSourceProcState = procState;
15720                            app.adjTarget = s.name;
15721                        }
15722                    }
15723                }
15724            }
15725        }
15726
15727        for (int provi = app.pubProviders.size()-1;
15728                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15729                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15730                        || procState > ActivityManager.PROCESS_STATE_TOP);
15731                provi--) {
15732            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15733            for (int i = cpr.connections.size()-1;
15734                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15735                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15736                            || procState > ActivityManager.PROCESS_STATE_TOP);
15737                    i--) {
15738                ContentProviderConnection conn = cpr.connections.get(i);
15739                ProcessRecord client = conn.client;
15740                if (client == app) {
15741                    // Being our own client is not interesting.
15742                    continue;
15743                }
15744                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15745                int clientProcState = client.curProcState;
15746                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15747                    // If the other app is cached for any reason, for purposes here
15748                    // we are going to consider it empty.
15749                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15750                }
15751                if (adj > clientAdj) {
15752                    if (app.hasShownUi && app != mHomeProcess
15753                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15754                        app.adjType = "cch-ui-provider";
15755                    } else {
15756                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15757                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15758                        app.adjType = "provider";
15759                    }
15760                    app.cached &= client.cached;
15761                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15762                            .REASON_PROVIDER_IN_USE;
15763                    app.adjSource = client;
15764                    app.adjSourceProcState = clientProcState;
15765                    app.adjTarget = cpr.name;
15766                }
15767                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15768                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15769                        // Special handling of clients who are in the top state.
15770                        // We *may* want to consider this process to be in the
15771                        // top state as well, but only if there is not another
15772                        // reason for it to be running.  Being on the top is a
15773                        // special state, meaning you are specifically running
15774                        // for the current top app.  If the process is already
15775                        // running in the background for some other reason, it
15776                        // is more important to continue considering it to be
15777                        // in the background state.
15778                        mayBeTop = true;
15779                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15780                    } else {
15781                        // Special handling for above-top states (persistent
15782                        // processes).  These should not bring the current process
15783                        // into the top state, since they are not on top.  Instead
15784                        // give them the best state after that.
15785                        clientProcState =
15786                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15787                    }
15788                }
15789                if (procState > clientProcState) {
15790                    procState = clientProcState;
15791                }
15792                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15793                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15794                }
15795            }
15796            // If the provider has external (non-framework) process
15797            // dependencies, ensure that its adjustment is at least
15798            // FOREGROUND_APP_ADJ.
15799            if (cpr.hasExternalProcessHandles()) {
15800                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15801                    adj = ProcessList.FOREGROUND_APP_ADJ;
15802                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15803                    app.cached = false;
15804                    app.adjType = "provider";
15805                    app.adjTarget = cpr.name;
15806                }
15807                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15808                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15809                }
15810            }
15811        }
15812
15813        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15814            // A client of one of our services or providers is in the top state.  We
15815            // *may* want to be in the top state, but not if we are already running in
15816            // the background for some other reason.  For the decision here, we are going
15817            // to pick out a few specific states that we want to remain in when a client
15818            // is top (states that tend to be longer-term) and otherwise allow it to go
15819            // to the top state.
15820            switch (procState) {
15821                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15822                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15823                case ActivityManager.PROCESS_STATE_SERVICE:
15824                    // These all are longer-term states, so pull them up to the top
15825                    // of the background states, but not all the way to the top state.
15826                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15827                    break;
15828                default:
15829                    // Otherwise, top is a better choice, so take it.
15830                    procState = ActivityManager.PROCESS_STATE_TOP;
15831                    break;
15832            }
15833        }
15834
15835        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15836            if (app.hasClientActivities) {
15837                // This is a cached process, but with client activities.  Mark it so.
15838                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15839                app.adjType = "cch-client-act";
15840            } else if (app.treatLikeActivity) {
15841                // This is a cached process, but somebody wants us to treat it like it has
15842                // an activity, okay!
15843                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15844                app.adjType = "cch-as-act";
15845            }
15846        }
15847
15848        if (adj == ProcessList.SERVICE_ADJ) {
15849            if (doingAll) {
15850                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15851                mNewNumServiceProcs++;
15852                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15853                if (!app.serviceb) {
15854                    // This service isn't far enough down on the LRU list to
15855                    // normally be a B service, but if we are low on RAM and it
15856                    // is large we want to force it down since we would prefer to
15857                    // keep launcher over it.
15858                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15859                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15860                        app.serviceHighRam = true;
15861                        app.serviceb = true;
15862                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15863                    } else {
15864                        mNewNumAServiceProcs++;
15865                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15866                    }
15867                } else {
15868                    app.serviceHighRam = false;
15869                }
15870            }
15871            if (app.serviceb) {
15872                adj = ProcessList.SERVICE_B_ADJ;
15873            }
15874        }
15875
15876        app.curRawAdj = adj;
15877
15878        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15879        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15880        if (adj > app.maxAdj) {
15881            adj = app.maxAdj;
15882            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15883                schedGroup = Process.THREAD_GROUP_DEFAULT;
15884            }
15885        }
15886
15887        // Do final modification to adj.  Everything we do between here and applying
15888        // the final setAdj must be done in this function, because we will also use
15889        // it when computing the final cached adj later.  Note that we don't need to
15890        // worry about this for max adj above, since max adj will always be used to
15891        // keep it out of the cached vaues.
15892        app.curAdj = app.modifyRawOomAdj(adj);
15893        app.curSchedGroup = schedGroup;
15894        app.curProcState = procState;
15895        app.foregroundActivities = foregroundActivities;
15896
15897        return app.curRawAdj;
15898    }
15899
15900    /**
15901     * Schedule PSS collection of a process.
15902     */
15903    void requestPssLocked(ProcessRecord proc, int procState) {
15904        if (mPendingPssProcesses.contains(proc)) {
15905            return;
15906        }
15907        if (mPendingPssProcesses.size() == 0) {
15908            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15909        }
15910        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15911        proc.pssProcState = procState;
15912        mPendingPssProcesses.add(proc);
15913    }
15914
15915    /**
15916     * Schedule PSS collection of all processes.
15917     */
15918    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15919        if (!always) {
15920            if (now < (mLastFullPssTime +
15921                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15922                return;
15923            }
15924        }
15925        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15926        mLastFullPssTime = now;
15927        mFullPssPending = true;
15928        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15929        mPendingPssProcesses.clear();
15930        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15931            ProcessRecord app = mLruProcesses.get(i);
15932            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15933                app.pssProcState = app.setProcState;
15934                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15935                        isSleeping(), now);
15936                mPendingPssProcesses.add(app);
15937            }
15938        }
15939        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15940    }
15941
15942    /**
15943     * Ask a given process to GC right now.
15944     */
15945    final void performAppGcLocked(ProcessRecord app) {
15946        try {
15947            app.lastRequestedGc = SystemClock.uptimeMillis();
15948            if (app.thread != null) {
15949                if (app.reportLowMemory) {
15950                    app.reportLowMemory = false;
15951                    app.thread.scheduleLowMemory();
15952                } else {
15953                    app.thread.processInBackground();
15954                }
15955            }
15956        } catch (Exception e) {
15957            // whatever.
15958        }
15959    }
15960
15961    /**
15962     * Returns true if things are idle enough to perform GCs.
15963     */
15964    private final boolean canGcNowLocked() {
15965        boolean processingBroadcasts = false;
15966        for (BroadcastQueue q : mBroadcastQueues) {
15967            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15968                processingBroadcasts = true;
15969            }
15970        }
15971        return !processingBroadcasts
15972                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15973    }
15974
15975    /**
15976     * Perform GCs on all processes that are waiting for it, but only
15977     * if things are idle.
15978     */
15979    final void performAppGcsLocked() {
15980        final int N = mProcessesToGc.size();
15981        if (N <= 0) {
15982            return;
15983        }
15984        if (canGcNowLocked()) {
15985            while (mProcessesToGc.size() > 0) {
15986                ProcessRecord proc = mProcessesToGc.remove(0);
15987                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15988                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15989                            <= SystemClock.uptimeMillis()) {
15990                        // To avoid spamming the system, we will GC processes one
15991                        // at a time, waiting a few seconds between each.
15992                        performAppGcLocked(proc);
15993                        scheduleAppGcsLocked();
15994                        return;
15995                    } else {
15996                        // It hasn't been long enough since we last GCed this
15997                        // process...  put it in the list to wait for its time.
15998                        addProcessToGcListLocked(proc);
15999                        break;
16000                    }
16001                }
16002            }
16003
16004            scheduleAppGcsLocked();
16005        }
16006    }
16007
16008    /**
16009     * If all looks good, perform GCs on all processes waiting for them.
16010     */
16011    final void performAppGcsIfAppropriateLocked() {
16012        if (canGcNowLocked()) {
16013            performAppGcsLocked();
16014            return;
16015        }
16016        // Still not idle, wait some more.
16017        scheduleAppGcsLocked();
16018    }
16019
16020    /**
16021     * Schedule the execution of all pending app GCs.
16022     */
16023    final void scheduleAppGcsLocked() {
16024        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16025
16026        if (mProcessesToGc.size() > 0) {
16027            // Schedule a GC for the time to the next process.
16028            ProcessRecord proc = mProcessesToGc.get(0);
16029            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16030
16031            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16032            long now = SystemClock.uptimeMillis();
16033            if (when < (now+GC_TIMEOUT)) {
16034                when = now + GC_TIMEOUT;
16035            }
16036            mHandler.sendMessageAtTime(msg, when);
16037        }
16038    }
16039
16040    /**
16041     * Add a process to the array of processes waiting to be GCed.  Keeps the
16042     * list in sorted order by the last GC time.  The process can't already be
16043     * on the list.
16044     */
16045    final void addProcessToGcListLocked(ProcessRecord proc) {
16046        boolean added = false;
16047        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16048            if (mProcessesToGc.get(i).lastRequestedGc <
16049                    proc.lastRequestedGc) {
16050                added = true;
16051                mProcessesToGc.add(i+1, proc);
16052                break;
16053            }
16054        }
16055        if (!added) {
16056            mProcessesToGc.add(0, proc);
16057        }
16058    }
16059
16060    /**
16061     * Set up to ask a process to GC itself.  This will either do it
16062     * immediately, or put it on the list of processes to gc the next
16063     * time things are idle.
16064     */
16065    final void scheduleAppGcLocked(ProcessRecord app) {
16066        long now = SystemClock.uptimeMillis();
16067        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16068            return;
16069        }
16070        if (!mProcessesToGc.contains(app)) {
16071            addProcessToGcListLocked(app);
16072            scheduleAppGcsLocked();
16073        }
16074    }
16075
16076    final void checkExcessivePowerUsageLocked(boolean doKills) {
16077        updateCpuStatsNow();
16078
16079        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16080        boolean doWakeKills = doKills;
16081        boolean doCpuKills = doKills;
16082        if (mLastPowerCheckRealtime == 0) {
16083            doWakeKills = false;
16084        }
16085        if (mLastPowerCheckUptime == 0) {
16086            doCpuKills = false;
16087        }
16088        if (stats.isScreenOn()) {
16089            doWakeKills = false;
16090        }
16091        final long curRealtime = SystemClock.elapsedRealtime();
16092        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16093        final long curUptime = SystemClock.uptimeMillis();
16094        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16095        mLastPowerCheckRealtime = curRealtime;
16096        mLastPowerCheckUptime = curUptime;
16097        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16098            doWakeKills = false;
16099        }
16100        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16101            doCpuKills = false;
16102        }
16103        int i = mLruProcesses.size();
16104        while (i > 0) {
16105            i--;
16106            ProcessRecord app = mLruProcesses.get(i);
16107            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16108                long wtime;
16109                synchronized (stats) {
16110                    wtime = stats.getProcessWakeTime(app.info.uid,
16111                            app.pid, curRealtime);
16112                }
16113                long wtimeUsed = wtime - app.lastWakeTime;
16114                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16115                if (DEBUG_POWER) {
16116                    StringBuilder sb = new StringBuilder(128);
16117                    sb.append("Wake for ");
16118                    app.toShortString(sb);
16119                    sb.append(": over ");
16120                    TimeUtils.formatDuration(realtimeSince, sb);
16121                    sb.append(" used ");
16122                    TimeUtils.formatDuration(wtimeUsed, sb);
16123                    sb.append(" (");
16124                    sb.append((wtimeUsed*100)/realtimeSince);
16125                    sb.append("%)");
16126                    Slog.i(TAG, sb.toString());
16127                    sb.setLength(0);
16128                    sb.append("CPU for ");
16129                    app.toShortString(sb);
16130                    sb.append(": over ");
16131                    TimeUtils.formatDuration(uptimeSince, sb);
16132                    sb.append(" used ");
16133                    TimeUtils.formatDuration(cputimeUsed, sb);
16134                    sb.append(" (");
16135                    sb.append((cputimeUsed*100)/uptimeSince);
16136                    sb.append("%)");
16137                    Slog.i(TAG, sb.toString());
16138                }
16139                // If a process has held a wake lock for more
16140                // than 50% of the time during this period,
16141                // that sounds bad.  Kill!
16142                if (doWakeKills && realtimeSince > 0
16143                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16144                    synchronized (stats) {
16145                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16146                                realtimeSince, wtimeUsed);
16147                    }
16148                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16149                            + " during " + realtimeSince);
16150                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16151                } else if (doCpuKills && uptimeSince > 0
16152                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16153                    synchronized (stats) {
16154                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16155                                uptimeSince, cputimeUsed);
16156                    }
16157                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16158                            + " during " + uptimeSince);
16159                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16160                } else {
16161                    app.lastWakeTime = wtime;
16162                    app.lastCpuTime = app.curCpuTime;
16163                }
16164            }
16165        }
16166    }
16167
16168    private final boolean applyOomAdjLocked(ProcessRecord app,
16169            ProcessRecord TOP_APP, boolean doingAll, long now) {
16170        boolean success = true;
16171
16172        if (app.curRawAdj != app.setRawAdj) {
16173            app.setRawAdj = app.curRawAdj;
16174        }
16175
16176        int changes = 0;
16177
16178        if (app.curAdj != app.setAdj) {
16179            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16180            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16181                TAG, "Set " + app.pid + " " + app.processName +
16182                " adj " + app.curAdj + ": " + app.adjType);
16183            app.setAdj = app.curAdj;
16184        }
16185
16186        if (app.setSchedGroup != app.curSchedGroup) {
16187            app.setSchedGroup = app.curSchedGroup;
16188            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16189                    "Setting process group of " + app.processName
16190                    + " to " + app.curSchedGroup);
16191            if (app.waitingToKill != null &&
16192                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16193                killUnneededProcessLocked(app, app.waitingToKill);
16194                success = false;
16195            } else {
16196                if (true) {
16197                    long oldId = Binder.clearCallingIdentity();
16198                    try {
16199                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16200                    } catch (Exception e) {
16201                        Slog.w(TAG, "Failed setting process group of " + app.pid
16202                                + " to " + app.curSchedGroup);
16203                        e.printStackTrace();
16204                    } finally {
16205                        Binder.restoreCallingIdentity(oldId);
16206                    }
16207                } else {
16208                    if (app.thread != null) {
16209                        try {
16210                            app.thread.setSchedulingGroup(app.curSchedGroup);
16211                        } catch (RemoteException e) {
16212                        }
16213                    }
16214                }
16215                Process.setSwappiness(app.pid,
16216                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16217            }
16218        }
16219        if (app.repForegroundActivities != app.foregroundActivities) {
16220            app.repForegroundActivities = app.foregroundActivities;
16221            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16222        }
16223        if (app.repProcState != app.curProcState) {
16224            app.repProcState = app.curProcState;
16225            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16226            if (app.thread != null) {
16227                try {
16228                    if (false) {
16229                        //RuntimeException h = new RuntimeException("here");
16230                        Slog.i(TAG, "Sending new process state " + app.repProcState
16231                                + " to " + app /*, h*/);
16232                    }
16233                    app.thread.setProcessState(app.repProcState);
16234                } catch (RemoteException e) {
16235                }
16236            }
16237        }
16238        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16239                app.setProcState)) {
16240            app.lastStateTime = now;
16241            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16242                    isSleeping(), now);
16243            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16244                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16245                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16246                    + (app.nextPssTime-now) + ": " + app);
16247        } else {
16248            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16249                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16250                requestPssLocked(app, app.setProcState);
16251                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16252                        isSleeping(), now);
16253            } else if (false && DEBUG_PSS) {
16254                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16255            }
16256        }
16257        if (app.setProcState != app.curProcState) {
16258            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16259                    "Proc state change of " + app.processName
16260                    + " to " + app.curProcState);
16261            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16262            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16263            if (setImportant && !curImportant) {
16264                // This app is no longer something we consider important enough to allow to
16265                // use arbitrary amounts of battery power.  Note
16266                // its current wake lock time to later know to kill it if
16267                // it is not behaving well.
16268                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16269                synchronized (stats) {
16270                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16271                            app.pid, SystemClock.elapsedRealtime());
16272                }
16273                app.lastCpuTime = app.curCpuTime;
16274
16275            }
16276            app.setProcState = app.curProcState;
16277            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16278                app.notCachedSinceIdle = false;
16279            }
16280            if (!doingAll) {
16281                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16282            } else {
16283                app.procStateChanged = true;
16284            }
16285        }
16286
16287        if (changes != 0) {
16288            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16289            int i = mPendingProcessChanges.size()-1;
16290            ProcessChangeItem item = null;
16291            while (i >= 0) {
16292                item = mPendingProcessChanges.get(i);
16293                if (item.pid == app.pid) {
16294                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16295                    break;
16296                }
16297                i--;
16298            }
16299            if (i < 0) {
16300                // No existing item in pending changes; need a new one.
16301                final int NA = mAvailProcessChanges.size();
16302                if (NA > 0) {
16303                    item = mAvailProcessChanges.remove(NA-1);
16304                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16305                } else {
16306                    item = new ProcessChangeItem();
16307                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16308                }
16309                item.changes = 0;
16310                item.pid = app.pid;
16311                item.uid = app.info.uid;
16312                if (mPendingProcessChanges.size() == 0) {
16313                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16314                            "*** Enqueueing dispatch processes changed!");
16315                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16316                }
16317                mPendingProcessChanges.add(item);
16318            }
16319            item.changes |= changes;
16320            item.processState = app.repProcState;
16321            item.foregroundActivities = app.repForegroundActivities;
16322            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16323                    + Integer.toHexString(System.identityHashCode(item))
16324                    + " " + app.toShortString() + ": changes=" + item.changes
16325                    + " procState=" + item.processState
16326                    + " foreground=" + item.foregroundActivities
16327                    + " type=" + app.adjType + " source=" + app.adjSource
16328                    + " target=" + app.adjTarget);
16329        }
16330
16331        return success;
16332    }
16333
16334    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16335        if (proc.thread != null) {
16336            if (proc.baseProcessTracker != null) {
16337                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16338            }
16339            if (proc.repProcState >= 0) {
16340                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16341                        proc.repProcState);
16342            }
16343        }
16344    }
16345
16346    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16347            ProcessRecord TOP_APP, boolean doingAll, long now) {
16348        if (app.thread == null) {
16349            return false;
16350        }
16351
16352        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16353
16354        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16355    }
16356
16357    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16358            boolean oomAdj) {
16359        if (isForeground != proc.foregroundServices) {
16360            proc.foregroundServices = isForeground;
16361            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16362                    proc.info.uid);
16363            if (isForeground) {
16364                if (curProcs == null) {
16365                    curProcs = new ArrayList<ProcessRecord>();
16366                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16367                }
16368                if (!curProcs.contains(proc)) {
16369                    curProcs.add(proc);
16370                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16371                            proc.info.packageName, proc.info.uid);
16372                }
16373            } else {
16374                if (curProcs != null) {
16375                    if (curProcs.remove(proc)) {
16376                        mBatteryStatsService.noteEvent(
16377                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16378                                proc.info.packageName, proc.info.uid);
16379                        if (curProcs.size() <= 0) {
16380                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16381                        }
16382                    }
16383                }
16384            }
16385            if (oomAdj) {
16386                updateOomAdjLocked();
16387            }
16388        }
16389    }
16390
16391    private final ActivityRecord resumedAppLocked() {
16392        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16393        String pkg;
16394        int uid;
16395        if (act != null) {
16396            pkg = act.packageName;
16397            uid = act.info.applicationInfo.uid;
16398        } else {
16399            pkg = null;
16400            uid = -1;
16401        }
16402        // Has the UID or resumed package name changed?
16403        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16404                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16405            if (mCurResumedPackage != null) {
16406                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16407                        mCurResumedPackage, mCurResumedUid);
16408            }
16409            mCurResumedPackage = pkg;
16410            mCurResumedUid = uid;
16411            if (mCurResumedPackage != null) {
16412                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16413                        mCurResumedPackage, mCurResumedUid);
16414            }
16415        }
16416        return act;
16417    }
16418
16419    final boolean updateOomAdjLocked(ProcessRecord app) {
16420        final ActivityRecord TOP_ACT = resumedAppLocked();
16421        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16422        final boolean wasCached = app.cached;
16423
16424        mAdjSeq++;
16425
16426        // This is the desired cached adjusment we want to tell it to use.
16427        // If our app is currently cached, we know it, and that is it.  Otherwise,
16428        // we don't know it yet, and it needs to now be cached we will then
16429        // need to do a complete oom adj.
16430        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16431                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16432        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16433                SystemClock.uptimeMillis());
16434        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16435            // Changed to/from cached state, so apps after it in the LRU
16436            // list may also be changed.
16437            updateOomAdjLocked();
16438        }
16439        return success;
16440    }
16441
16442    final void updateOomAdjLocked() {
16443        final ActivityRecord TOP_ACT = resumedAppLocked();
16444        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16445        final long now = SystemClock.uptimeMillis();
16446        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16447        final int N = mLruProcesses.size();
16448
16449        if (false) {
16450            RuntimeException e = new RuntimeException();
16451            e.fillInStackTrace();
16452            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16453        }
16454
16455        mAdjSeq++;
16456        mNewNumServiceProcs = 0;
16457        mNewNumAServiceProcs = 0;
16458
16459        final int emptyProcessLimit;
16460        final int cachedProcessLimit;
16461        if (mProcessLimit <= 0) {
16462            emptyProcessLimit = cachedProcessLimit = 0;
16463        } else if (mProcessLimit == 1) {
16464            emptyProcessLimit = 1;
16465            cachedProcessLimit = 0;
16466        } else {
16467            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16468            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16469        }
16470
16471        // Let's determine how many processes we have running vs.
16472        // how many slots we have for background processes; we may want
16473        // to put multiple processes in a slot of there are enough of
16474        // them.
16475        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16476                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16477        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16478        if (numEmptyProcs > cachedProcessLimit) {
16479            // If there are more empty processes than our limit on cached
16480            // processes, then use the cached process limit for the factor.
16481            // This ensures that the really old empty processes get pushed
16482            // down to the bottom, so if we are running low on memory we will
16483            // have a better chance at keeping around more cached processes
16484            // instead of a gazillion empty processes.
16485            numEmptyProcs = cachedProcessLimit;
16486        }
16487        int emptyFactor = numEmptyProcs/numSlots;
16488        if (emptyFactor < 1) emptyFactor = 1;
16489        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16490        if (cachedFactor < 1) cachedFactor = 1;
16491        int stepCached = 0;
16492        int stepEmpty = 0;
16493        int numCached = 0;
16494        int numEmpty = 0;
16495        int numTrimming = 0;
16496
16497        mNumNonCachedProcs = 0;
16498        mNumCachedHiddenProcs = 0;
16499
16500        // First update the OOM adjustment for each of the
16501        // application processes based on their current state.
16502        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16503        int nextCachedAdj = curCachedAdj+1;
16504        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16505        int nextEmptyAdj = curEmptyAdj+2;
16506        for (int i=N-1; i>=0; i--) {
16507            ProcessRecord app = mLruProcesses.get(i);
16508            if (!app.killedByAm && app.thread != null) {
16509                app.procStateChanged = false;
16510                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16511
16512                // If we haven't yet assigned the final cached adj
16513                // to the process, do that now.
16514                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16515                    switch (app.curProcState) {
16516                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16517                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16518                            // This process is a cached process holding activities...
16519                            // assign it the next cached value for that type, and then
16520                            // step that cached level.
16521                            app.curRawAdj = curCachedAdj;
16522                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16523                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16524                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16525                                    + ")");
16526                            if (curCachedAdj != nextCachedAdj) {
16527                                stepCached++;
16528                                if (stepCached >= cachedFactor) {
16529                                    stepCached = 0;
16530                                    curCachedAdj = nextCachedAdj;
16531                                    nextCachedAdj += 2;
16532                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16533                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16534                                    }
16535                                }
16536                            }
16537                            break;
16538                        default:
16539                            // For everything else, assign next empty cached process
16540                            // level and bump that up.  Note that this means that
16541                            // long-running services that have dropped down to the
16542                            // cached level will be treated as empty (since their process
16543                            // state is still as a service), which is what we want.
16544                            app.curRawAdj = curEmptyAdj;
16545                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16546                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16547                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16548                                    + ")");
16549                            if (curEmptyAdj != nextEmptyAdj) {
16550                                stepEmpty++;
16551                                if (stepEmpty >= emptyFactor) {
16552                                    stepEmpty = 0;
16553                                    curEmptyAdj = nextEmptyAdj;
16554                                    nextEmptyAdj += 2;
16555                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16556                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16557                                    }
16558                                }
16559                            }
16560                            break;
16561                    }
16562                }
16563
16564                applyOomAdjLocked(app, TOP_APP, true, now);
16565
16566                // Count the number of process types.
16567                switch (app.curProcState) {
16568                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16569                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16570                        mNumCachedHiddenProcs++;
16571                        numCached++;
16572                        if (numCached > cachedProcessLimit) {
16573                            killUnneededProcessLocked(app, "cached #" + numCached);
16574                        }
16575                        break;
16576                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16577                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16578                                && app.lastActivityTime < oldTime) {
16579                            killUnneededProcessLocked(app, "empty for "
16580                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16581                                    / 1000) + "s");
16582                        } else {
16583                            numEmpty++;
16584                            if (numEmpty > emptyProcessLimit) {
16585                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16586                            }
16587                        }
16588                        break;
16589                    default:
16590                        mNumNonCachedProcs++;
16591                        break;
16592                }
16593
16594                if (app.isolated && app.services.size() <= 0) {
16595                    // If this is an isolated process, and there are no
16596                    // services running in it, then the process is no longer
16597                    // needed.  We agressively kill these because we can by
16598                    // definition not re-use the same process again, and it is
16599                    // good to avoid having whatever code was running in them
16600                    // left sitting around after no longer needed.
16601                    killUnneededProcessLocked(app, "isolated not needed");
16602                }
16603
16604                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16605                        && !app.killedByAm) {
16606                    numTrimming++;
16607                }
16608            }
16609        }
16610
16611        mNumServiceProcs = mNewNumServiceProcs;
16612
16613        // Now determine the memory trimming level of background processes.
16614        // Unfortunately we need to start at the back of the list to do this
16615        // properly.  We only do this if the number of background apps we
16616        // are managing to keep around is less than half the maximum we desire;
16617        // if we are keeping a good number around, we'll let them use whatever
16618        // memory they want.
16619        final int numCachedAndEmpty = numCached + numEmpty;
16620        int memFactor;
16621        if (numCached <= ProcessList.TRIM_CACHED_APPS
16622                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16623            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16624                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16625            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16626                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16627            } else {
16628                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16629            }
16630        } else {
16631            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16632        }
16633        // We always allow the memory level to go up (better).  We only allow it to go
16634        // down if we are in a state where that is allowed, *and* the total number of processes
16635        // has gone down since last time.
16636        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16637                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16638                + " last=" + mLastNumProcesses);
16639        if (memFactor > mLastMemoryLevel) {
16640            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16641                memFactor = mLastMemoryLevel;
16642                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16643            }
16644        }
16645        mLastMemoryLevel = memFactor;
16646        mLastNumProcesses = mLruProcesses.size();
16647        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16648        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16649        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16650            if (mLowRamStartTime == 0) {
16651                mLowRamStartTime = now;
16652            }
16653            int step = 0;
16654            int fgTrimLevel;
16655            switch (memFactor) {
16656                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16657                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16658                    break;
16659                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16660                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16661                    break;
16662                default:
16663                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16664                    break;
16665            }
16666            int factor = numTrimming/3;
16667            int minFactor = 2;
16668            if (mHomeProcess != null) minFactor++;
16669            if (mPreviousProcess != null) minFactor++;
16670            if (factor < minFactor) factor = minFactor;
16671            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16672            for (int i=N-1; i>=0; i--) {
16673                ProcessRecord app = mLruProcesses.get(i);
16674                if (allChanged || app.procStateChanged) {
16675                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16676                    app.procStateChanged = false;
16677                }
16678                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16679                        && !app.killedByAm) {
16680                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16681                        try {
16682                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16683                                    "Trimming memory of " + app.processName
16684                                    + " to " + curLevel);
16685                            app.thread.scheduleTrimMemory(curLevel);
16686                        } catch (RemoteException e) {
16687                        }
16688                        if (false) {
16689                            // For now we won't do this; our memory trimming seems
16690                            // to be good enough at this point that destroying
16691                            // activities causes more harm than good.
16692                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16693                                    && app != mHomeProcess && app != mPreviousProcess) {
16694                                // Need to do this on its own message because the stack may not
16695                                // be in a consistent state at this point.
16696                                // For these apps we will also finish their activities
16697                                // to help them free memory.
16698                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16699                            }
16700                        }
16701                    }
16702                    app.trimMemoryLevel = curLevel;
16703                    step++;
16704                    if (step >= factor) {
16705                        step = 0;
16706                        switch (curLevel) {
16707                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16708                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16709                                break;
16710                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16711                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16712                                break;
16713                        }
16714                    }
16715                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16716                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16717                            && app.thread != null) {
16718                        try {
16719                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16720                                    "Trimming memory of heavy-weight " + app.processName
16721                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16722                            app.thread.scheduleTrimMemory(
16723                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16724                        } catch (RemoteException e) {
16725                        }
16726                    }
16727                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16728                } else {
16729                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16730                            || app.systemNoUi) && app.pendingUiClean) {
16731                        // If this application is now in the background and it
16732                        // had done UI, then give it the special trim level to
16733                        // have it free UI resources.
16734                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16735                        if (app.trimMemoryLevel < level && app.thread != null) {
16736                            try {
16737                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16738                                        "Trimming memory of bg-ui " + app.processName
16739                                        + " to " + level);
16740                                app.thread.scheduleTrimMemory(level);
16741                            } catch (RemoteException e) {
16742                            }
16743                        }
16744                        app.pendingUiClean = false;
16745                    }
16746                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16747                        try {
16748                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16749                                    "Trimming memory of fg " + app.processName
16750                                    + " to " + fgTrimLevel);
16751                            app.thread.scheduleTrimMemory(fgTrimLevel);
16752                        } catch (RemoteException e) {
16753                        }
16754                    }
16755                    app.trimMemoryLevel = fgTrimLevel;
16756                }
16757            }
16758        } else {
16759            if (mLowRamStartTime != 0) {
16760                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16761                mLowRamStartTime = 0;
16762            }
16763            for (int i=N-1; i>=0; i--) {
16764                ProcessRecord app = mLruProcesses.get(i);
16765                if (allChanged || app.procStateChanged) {
16766                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16767                    app.procStateChanged = false;
16768                }
16769                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16770                        || app.systemNoUi) && app.pendingUiClean) {
16771                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16772                            && app.thread != null) {
16773                        try {
16774                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16775                                    "Trimming memory of ui hidden " + app.processName
16776                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16777                            app.thread.scheduleTrimMemory(
16778                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16779                        } catch (RemoteException e) {
16780                        }
16781                    }
16782                    app.pendingUiClean = false;
16783                }
16784                app.trimMemoryLevel = 0;
16785            }
16786        }
16787
16788        if (mAlwaysFinishActivities) {
16789            // Need to do this on its own message because the stack may not
16790            // be in a consistent state at this point.
16791            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16792        }
16793
16794        if (allChanged) {
16795            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16796        }
16797
16798        if (mProcessStats.shouldWriteNowLocked(now)) {
16799            mHandler.post(new Runnable() {
16800                @Override public void run() {
16801                    synchronized (ActivityManagerService.this) {
16802                        mProcessStats.writeStateAsyncLocked();
16803                    }
16804                }
16805            });
16806        }
16807
16808        if (DEBUG_OOM_ADJ) {
16809            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16810        }
16811    }
16812
16813    final void trimApplications() {
16814        synchronized (this) {
16815            int i;
16816
16817            // First remove any unused application processes whose package
16818            // has been removed.
16819            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16820                final ProcessRecord app = mRemovedProcesses.get(i);
16821                if (app.activities.size() == 0
16822                        && app.curReceiver == null && app.services.size() == 0) {
16823                    Slog.i(
16824                        TAG, "Exiting empty application process "
16825                        + app.processName + " ("
16826                        + (app.thread != null ? app.thread.asBinder() : null)
16827                        + ")\n");
16828                    if (app.pid > 0 && app.pid != MY_PID) {
16829                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16830                                app.processName, app.setAdj, "empty");
16831                        app.killedByAm = true;
16832                        Process.killProcessQuiet(app.pid);
16833                        Process.killProcessGroup(app.info.uid, app.pid);
16834                    } else {
16835                        try {
16836                            app.thread.scheduleExit();
16837                        } catch (Exception e) {
16838                            // Ignore exceptions.
16839                        }
16840                    }
16841                    cleanUpApplicationRecordLocked(app, false, true, -1);
16842                    mRemovedProcesses.remove(i);
16843
16844                    if (app.persistent) {
16845                        addAppLocked(app.info, false, null /* ABI override */);
16846                    }
16847                }
16848            }
16849
16850            // Now update the oom adj for all processes.
16851            updateOomAdjLocked();
16852        }
16853    }
16854
16855    /** This method sends the specified signal to each of the persistent apps */
16856    public void signalPersistentProcesses(int sig) throws RemoteException {
16857        if (sig != Process.SIGNAL_USR1) {
16858            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16859        }
16860
16861        synchronized (this) {
16862            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16863                    != PackageManager.PERMISSION_GRANTED) {
16864                throw new SecurityException("Requires permission "
16865                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16866            }
16867
16868            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16869                ProcessRecord r = mLruProcesses.get(i);
16870                if (r.thread != null && r.persistent) {
16871                    Process.sendSignal(r.pid, sig);
16872                }
16873            }
16874        }
16875    }
16876
16877    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16878        if (proc == null || proc == mProfileProc) {
16879            proc = mProfileProc;
16880            path = mProfileFile;
16881            profileType = mProfileType;
16882            clearProfilerLocked();
16883        }
16884        if (proc == null) {
16885            return;
16886        }
16887        try {
16888            proc.thread.profilerControl(false, path, null, profileType);
16889        } catch (RemoteException e) {
16890            throw new IllegalStateException("Process disappeared");
16891        }
16892    }
16893
16894    private void clearProfilerLocked() {
16895        if (mProfileFd != null) {
16896            try {
16897                mProfileFd.close();
16898            } catch (IOException e) {
16899            }
16900        }
16901        mProfileApp = null;
16902        mProfileProc = null;
16903        mProfileFile = null;
16904        mProfileType = 0;
16905        mAutoStopProfiler = false;
16906    }
16907
16908    public boolean profileControl(String process, int userId, boolean start,
16909            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16910
16911        try {
16912            synchronized (this) {
16913                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16914                // its own permission.
16915                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16916                        != PackageManager.PERMISSION_GRANTED) {
16917                    throw new SecurityException("Requires permission "
16918                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16919                }
16920
16921                if (start && fd == null) {
16922                    throw new IllegalArgumentException("null fd");
16923                }
16924
16925                ProcessRecord proc = null;
16926                if (process != null) {
16927                    proc = findProcessLocked(process, userId, "profileControl");
16928                }
16929
16930                if (start && (proc == null || proc.thread == null)) {
16931                    throw new IllegalArgumentException("Unknown process: " + process);
16932                }
16933
16934                if (start) {
16935                    stopProfilerLocked(null, null, 0);
16936                    setProfileApp(proc.info, proc.processName, path, fd, false);
16937                    mProfileProc = proc;
16938                    mProfileType = profileType;
16939                    try {
16940                        fd = fd.dup();
16941                    } catch (IOException e) {
16942                        fd = null;
16943                    }
16944                    proc.thread.profilerControl(start, path, fd, profileType);
16945                    fd = null;
16946                    mProfileFd = null;
16947                } else {
16948                    stopProfilerLocked(proc, path, profileType);
16949                    if (fd != null) {
16950                        try {
16951                            fd.close();
16952                        } catch (IOException e) {
16953                        }
16954                    }
16955                }
16956
16957                return true;
16958            }
16959        } catch (RemoteException e) {
16960            throw new IllegalStateException("Process disappeared");
16961        } finally {
16962            if (fd != null) {
16963                try {
16964                    fd.close();
16965                } catch (IOException e) {
16966                }
16967            }
16968        }
16969    }
16970
16971    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16972        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16973                userId, true, ALLOW_FULL_ONLY, callName, null);
16974        ProcessRecord proc = null;
16975        try {
16976            int pid = Integer.parseInt(process);
16977            synchronized (mPidsSelfLocked) {
16978                proc = mPidsSelfLocked.get(pid);
16979            }
16980        } catch (NumberFormatException e) {
16981        }
16982
16983        if (proc == null) {
16984            ArrayMap<String, SparseArray<ProcessRecord>> all
16985                    = mProcessNames.getMap();
16986            SparseArray<ProcessRecord> procs = all.get(process);
16987            if (procs != null && procs.size() > 0) {
16988                proc = procs.valueAt(0);
16989                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16990                    for (int i=1; i<procs.size(); i++) {
16991                        ProcessRecord thisProc = procs.valueAt(i);
16992                        if (thisProc.userId == userId) {
16993                            proc = thisProc;
16994                            break;
16995                        }
16996                    }
16997                }
16998            }
16999        }
17000
17001        return proc;
17002    }
17003
17004    public boolean dumpHeap(String process, int userId, boolean managed,
17005            String path, ParcelFileDescriptor fd) throws RemoteException {
17006
17007        try {
17008            synchronized (this) {
17009                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17010                // its own permission (same as profileControl).
17011                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17012                        != PackageManager.PERMISSION_GRANTED) {
17013                    throw new SecurityException("Requires permission "
17014                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17015                }
17016
17017                if (fd == null) {
17018                    throw new IllegalArgumentException("null fd");
17019                }
17020
17021                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17022                if (proc == null || proc.thread == null) {
17023                    throw new IllegalArgumentException("Unknown process: " + process);
17024                }
17025
17026                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17027                if (!isDebuggable) {
17028                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17029                        throw new SecurityException("Process not debuggable: " + proc);
17030                    }
17031                }
17032
17033                proc.thread.dumpHeap(managed, path, fd);
17034                fd = null;
17035                return true;
17036            }
17037        } catch (RemoteException e) {
17038            throw new IllegalStateException("Process disappeared");
17039        } finally {
17040            if (fd != null) {
17041                try {
17042                    fd.close();
17043                } catch (IOException e) {
17044                }
17045            }
17046        }
17047    }
17048
17049    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17050    public void monitor() {
17051        synchronized (this) { }
17052    }
17053
17054    void onCoreSettingsChange(Bundle settings) {
17055        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17056            ProcessRecord processRecord = mLruProcesses.get(i);
17057            try {
17058                if (processRecord.thread != null) {
17059                    processRecord.thread.setCoreSettings(settings);
17060                }
17061            } catch (RemoteException re) {
17062                /* ignore */
17063            }
17064        }
17065    }
17066
17067    // Multi-user methods
17068
17069    /**
17070     * Start user, if its not already running, but don't bring it to foreground.
17071     */
17072    @Override
17073    public boolean startUserInBackground(final int userId) {
17074        return startUser(userId, /* foreground */ false);
17075    }
17076
17077    /**
17078     * Refreshes the list of users related to the current user when either a
17079     * user switch happens or when a new related user is started in the
17080     * background.
17081     */
17082    private void updateCurrentProfileIdsLocked() {
17083        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17084                mCurrentUserId, false /* enabledOnly */);
17085        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17086        for (int i = 0; i < currentProfileIds.length; i++) {
17087            currentProfileIds[i] = profiles.get(i).id;
17088        }
17089        mCurrentProfileIds = currentProfileIds;
17090
17091        synchronized (mUserProfileGroupIdsSelfLocked) {
17092            mUserProfileGroupIdsSelfLocked.clear();
17093            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17094            for (int i = 0; i < users.size(); i++) {
17095                UserInfo user = users.get(i);
17096                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17097                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17098                }
17099            }
17100        }
17101    }
17102
17103    private Set getProfileIdsLocked(int userId) {
17104        Set userIds = new HashSet<Integer>();
17105        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17106                userId, false /* enabledOnly */);
17107        for (UserInfo user : profiles) {
17108            userIds.add(Integer.valueOf(user.id));
17109        }
17110        return userIds;
17111    }
17112
17113    @Override
17114    public boolean switchUser(final int userId) {
17115        return startUser(userId, /* foregound */ true);
17116    }
17117
17118    private boolean startUser(final int userId, boolean foreground) {
17119        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17120                != PackageManager.PERMISSION_GRANTED) {
17121            String msg = "Permission Denial: switchUser() from pid="
17122                    + Binder.getCallingPid()
17123                    + ", uid=" + Binder.getCallingUid()
17124                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17125            Slog.w(TAG, msg);
17126            throw new SecurityException(msg);
17127        }
17128
17129        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17130
17131        final long ident = Binder.clearCallingIdentity();
17132        try {
17133            synchronized (this) {
17134                final int oldUserId = mCurrentUserId;
17135                if (oldUserId == userId) {
17136                    return true;
17137                }
17138
17139                mStackSupervisor.setLockTaskModeLocked(null, false);
17140
17141                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17142                if (userInfo == null) {
17143                    Slog.w(TAG, "No user info for user #" + userId);
17144                    return false;
17145                }
17146
17147                if (foreground) {
17148                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17149                            R.anim.screen_user_enter);
17150                }
17151
17152                boolean needStart = false;
17153
17154                // If the user we are switching to is not currently started, then
17155                // we need to start it now.
17156                if (mStartedUsers.get(userId) == null) {
17157                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17158                    updateStartedUserArrayLocked();
17159                    needStart = true;
17160                }
17161
17162                final Integer userIdInt = Integer.valueOf(userId);
17163                mUserLru.remove(userIdInt);
17164                mUserLru.add(userIdInt);
17165
17166                if (foreground) {
17167                    mCurrentUserId = userId;
17168                    updateCurrentProfileIdsLocked();
17169                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17170                    // Once the internal notion of the active user has switched, we lock the device
17171                    // with the option to show the user switcher on the keyguard.
17172                    mWindowManager.lockNow(null);
17173                } else {
17174                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17175                    updateCurrentProfileIdsLocked();
17176                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17177                    mUserLru.remove(currentUserIdInt);
17178                    mUserLru.add(currentUserIdInt);
17179                }
17180
17181                final UserStartedState uss = mStartedUsers.get(userId);
17182
17183                // Make sure user is in the started state.  If it is currently
17184                // stopping, we need to knock that off.
17185                if (uss.mState == UserStartedState.STATE_STOPPING) {
17186                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17187                    // so we can just fairly silently bring the user back from
17188                    // the almost-dead.
17189                    uss.mState = UserStartedState.STATE_RUNNING;
17190                    updateStartedUserArrayLocked();
17191                    needStart = true;
17192                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17193                    // This means ACTION_SHUTDOWN has been sent, so we will
17194                    // need to treat this as a new boot of the user.
17195                    uss.mState = UserStartedState.STATE_BOOTING;
17196                    updateStartedUserArrayLocked();
17197                    needStart = true;
17198                }
17199
17200                if (uss.mState == UserStartedState.STATE_BOOTING) {
17201                    // Booting up a new user, need to tell system services about it.
17202                    // Note that this is on the same handler as scheduling of broadcasts,
17203                    // which is important because it needs to go first.
17204                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17205                }
17206
17207                if (foreground) {
17208                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17209                            oldUserId));
17210                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17211                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17212                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17213                            oldUserId, userId, uss));
17214                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17215                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17216                }
17217
17218                if (needStart) {
17219                    // Send USER_STARTED broadcast
17220                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17221                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17222                            | Intent.FLAG_RECEIVER_FOREGROUND);
17223                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17224                    broadcastIntentLocked(null, null, intent,
17225                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17226                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17227                }
17228
17229                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17230                    if (userId != UserHandle.USER_OWNER) {
17231                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17232                        final ArrayList<ComponentName> doneReceivers
17233                                = new ArrayList<ComponentName>();
17234                        deliverPreBootCompleted(null, doneReceivers, userId);
17235
17236                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17237                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17238                        broadcastIntentLocked(null, null, intent, null,
17239                                new IIntentReceiver.Stub() {
17240                                    public void performReceive(Intent intent, int resultCode,
17241                                            String data, Bundle extras, boolean ordered,
17242                                            boolean sticky, int sendingUser) {
17243                                        userInitialized(uss, userId);
17244                                    }
17245                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17246                                true, false, MY_PID, Process.SYSTEM_UID,
17247                                userId);
17248                        uss.initializing = true;
17249                    } else {
17250                        getUserManagerLocked().makeInitialized(userInfo.id);
17251                    }
17252                }
17253
17254                if (foreground) {
17255                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17256                    if (homeInFront) {
17257                        startHomeActivityLocked(userId);
17258                    } else {
17259                        mStackSupervisor.resumeTopActivitiesLocked();
17260                    }
17261                    EventLogTags.writeAmSwitchUser(userId);
17262                    getUserManagerLocked().userForeground(userId);
17263                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17264                } else {
17265                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17266                }
17267
17268                if (needStart) {
17269                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17270                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17271                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17272                    broadcastIntentLocked(null, null, intent,
17273                            null, new IIntentReceiver.Stub() {
17274                                @Override
17275                                public void performReceive(Intent intent, int resultCode, String data,
17276                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17277                                        throws RemoteException {
17278                                }
17279                            }, 0, null, null,
17280                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17281                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17282                }
17283            }
17284        } finally {
17285            Binder.restoreCallingIdentity(ident);
17286        }
17287
17288        return true;
17289    }
17290
17291    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17292        long ident = Binder.clearCallingIdentity();
17293        try {
17294            Intent intent;
17295            if (oldUserId >= 0) {
17296                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17297                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17298                int count = profiles.size();
17299                for (int i = 0; i < count; i++) {
17300                    int profileUserId = profiles.get(i).id;
17301                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17302                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17303                            | Intent.FLAG_RECEIVER_FOREGROUND);
17304                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17305                    broadcastIntentLocked(null, null, intent,
17306                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17307                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17308                }
17309            }
17310            if (newUserId >= 0) {
17311                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17312                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17313                int count = profiles.size();
17314                for (int i = 0; i < count; i++) {
17315                    int profileUserId = profiles.get(i).id;
17316                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17317                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17318                            | Intent.FLAG_RECEIVER_FOREGROUND);
17319                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17320                    broadcastIntentLocked(null, null, intent,
17321                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17322                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17323                }
17324                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17325                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17326                        | Intent.FLAG_RECEIVER_FOREGROUND);
17327                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17328                broadcastIntentLocked(null, null, intent,
17329                        null, null, 0, null, null,
17330                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17331                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17332            }
17333        } finally {
17334            Binder.restoreCallingIdentity(ident);
17335        }
17336    }
17337
17338    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17339            final int newUserId) {
17340        final int N = mUserSwitchObservers.beginBroadcast();
17341        if (N > 0) {
17342            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17343                int mCount = 0;
17344                @Override
17345                public void sendResult(Bundle data) throws RemoteException {
17346                    synchronized (ActivityManagerService.this) {
17347                        if (mCurUserSwitchCallback == this) {
17348                            mCount++;
17349                            if (mCount == N) {
17350                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17351                            }
17352                        }
17353                    }
17354                }
17355            };
17356            synchronized (this) {
17357                uss.switching = true;
17358                mCurUserSwitchCallback = callback;
17359            }
17360            for (int i=0; i<N; i++) {
17361                try {
17362                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17363                            newUserId, callback);
17364                } catch (RemoteException e) {
17365                }
17366            }
17367        } else {
17368            synchronized (this) {
17369                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17370            }
17371        }
17372        mUserSwitchObservers.finishBroadcast();
17373    }
17374
17375    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17376        synchronized (this) {
17377            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17378            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17379        }
17380    }
17381
17382    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17383        mCurUserSwitchCallback = null;
17384        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17385        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17386                oldUserId, newUserId, uss));
17387    }
17388
17389    void userInitialized(UserStartedState uss, int newUserId) {
17390        completeSwitchAndInitalize(uss, newUserId, true, false);
17391    }
17392
17393    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17394        completeSwitchAndInitalize(uss, newUserId, false, true);
17395    }
17396
17397    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17398            boolean clearInitializing, boolean clearSwitching) {
17399        boolean unfrozen = false;
17400        synchronized (this) {
17401            if (clearInitializing) {
17402                uss.initializing = false;
17403                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17404            }
17405            if (clearSwitching) {
17406                uss.switching = false;
17407            }
17408            if (!uss.switching && !uss.initializing) {
17409                mWindowManager.stopFreezingScreen();
17410                unfrozen = true;
17411            }
17412        }
17413        if (unfrozen) {
17414            final int N = mUserSwitchObservers.beginBroadcast();
17415            for (int i=0; i<N; i++) {
17416                try {
17417                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17418                } catch (RemoteException e) {
17419                }
17420            }
17421            mUserSwitchObservers.finishBroadcast();
17422        }
17423    }
17424
17425    void scheduleStartProfilesLocked() {
17426        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17427            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17428                    DateUtils.SECOND_IN_MILLIS);
17429        }
17430    }
17431
17432    void startProfilesLocked() {
17433        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17434        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17435                mCurrentUserId, false /* enabledOnly */);
17436        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17437        for (UserInfo user : profiles) {
17438            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17439                    && user.id != mCurrentUserId) {
17440                toStart.add(user);
17441            }
17442        }
17443        final int n = toStart.size();
17444        int i = 0;
17445        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17446            startUserInBackground(toStart.get(i).id);
17447        }
17448        if (i < n) {
17449            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17450        }
17451    }
17452
17453    void finishUserBoot(UserStartedState uss) {
17454        synchronized (this) {
17455            if (uss.mState == UserStartedState.STATE_BOOTING
17456                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17457                uss.mState = UserStartedState.STATE_RUNNING;
17458                final int userId = uss.mHandle.getIdentifier();
17459                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17460                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17461                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17462                broadcastIntentLocked(null, null, intent,
17463                        null, null, 0, null, null,
17464                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17465                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17466            }
17467        }
17468    }
17469
17470    void finishUserSwitch(UserStartedState uss) {
17471        synchronized (this) {
17472            finishUserBoot(uss);
17473
17474            startProfilesLocked();
17475
17476            int num = mUserLru.size();
17477            int i = 0;
17478            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17479                Integer oldUserId = mUserLru.get(i);
17480                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17481                if (oldUss == null) {
17482                    // Shouldn't happen, but be sane if it does.
17483                    mUserLru.remove(i);
17484                    num--;
17485                    continue;
17486                }
17487                if (oldUss.mState == UserStartedState.STATE_STOPPING
17488                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17489                    // This user is already stopping, doesn't count.
17490                    num--;
17491                    i++;
17492                    continue;
17493                }
17494                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17495                    // Owner and current can't be stopped, but count as running.
17496                    i++;
17497                    continue;
17498                }
17499                // This is a user to be stopped.
17500                stopUserLocked(oldUserId, null);
17501                num--;
17502                i++;
17503            }
17504        }
17505    }
17506
17507    @Override
17508    public int stopUser(final int userId, final IStopUserCallback callback) {
17509        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17510                != PackageManager.PERMISSION_GRANTED) {
17511            String msg = "Permission Denial: switchUser() from pid="
17512                    + Binder.getCallingPid()
17513                    + ", uid=" + Binder.getCallingUid()
17514                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17515            Slog.w(TAG, msg);
17516            throw new SecurityException(msg);
17517        }
17518        if (userId <= 0) {
17519            throw new IllegalArgumentException("Can't stop primary user " + userId);
17520        }
17521        synchronized (this) {
17522            return stopUserLocked(userId, callback);
17523        }
17524    }
17525
17526    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17527        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17528        if (mCurrentUserId == userId) {
17529            return ActivityManager.USER_OP_IS_CURRENT;
17530        }
17531
17532        final UserStartedState uss = mStartedUsers.get(userId);
17533        if (uss == null) {
17534            // User is not started, nothing to do...  but we do need to
17535            // callback if requested.
17536            if (callback != null) {
17537                mHandler.post(new Runnable() {
17538                    @Override
17539                    public void run() {
17540                        try {
17541                            callback.userStopped(userId);
17542                        } catch (RemoteException e) {
17543                        }
17544                    }
17545                });
17546            }
17547            return ActivityManager.USER_OP_SUCCESS;
17548        }
17549
17550        if (callback != null) {
17551            uss.mStopCallbacks.add(callback);
17552        }
17553
17554        if (uss.mState != UserStartedState.STATE_STOPPING
17555                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17556            uss.mState = UserStartedState.STATE_STOPPING;
17557            updateStartedUserArrayLocked();
17558
17559            long ident = Binder.clearCallingIdentity();
17560            try {
17561                // We are going to broadcast ACTION_USER_STOPPING and then
17562                // once that is done send a final ACTION_SHUTDOWN and then
17563                // stop the user.
17564                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17565                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17566                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17567                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17568                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17569                // This is the result receiver for the final shutdown broadcast.
17570                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17571                    @Override
17572                    public void performReceive(Intent intent, int resultCode, String data,
17573                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17574                        finishUserStop(uss);
17575                    }
17576                };
17577                // This is the result receiver for the initial stopping broadcast.
17578                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17579                    @Override
17580                    public void performReceive(Intent intent, int resultCode, String data,
17581                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17582                        // On to the next.
17583                        synchronized (ActivityManagerService.this) {
17584                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17585                                // Whoops, we are being started back up.  Abort, abort!
17586                                return;
17587                            }
17588                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17589                        }
17590                        mBatteryStatsService.noteEvent(
17591                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17592                                Integer.toString(userId), userId);
17593                        mSystemServiceManager.stopUser(userId);
17594                        broadcastIntentLocked(null, null, shutdownIntent,
17595                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17596                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17597                    }
17598                };
17599                // Kick things off.
17600                broadcastIntentLocked(null, null, stoppingIntent,
17601                        null, stoppingReceiver, 0, null, null,
17602                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17603                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17604            } finally {
17605                Binder.restoreCallingIdentity(ident);
17606            }
17607        }
17608
17609        return ActivityManager.USER_OP_SUCCESS;
17610    }
17611
17612    void finishUserStop(UserStartedState uss) {
17613        final int userId = uss.mHandle.getIdentifier();
17614        boolean stopped;
17615        ArrayList<IStopUserCallback> callbacks;
17616        synchronized (this) {
17617            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17618            if (mStartedUsers.get(userId) != uss) {
17619                stopped = false;
17620            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17621                stopped = false;
17622            } else {
17623                stopped = true;
17624                // User can no longer run.
17625                mStartedUsers.remove(userId);
17626                mUserLru.remove(Integer.valueOf(userId));
17627                updateStartedUserArrayLocked();
17628
17629                // Clean up all state and processes associated with the user.
17630                // Kill all the processes for the user.
17631                forceStopUserLocked(userId, "finish user");
17632            }
17633        }
17634
17635        for (int i=0; i<callbacks.size(); i++) {
17636            try {
17637                if (stopped) callbacks.get(i).userStopped(userId);
17638                else callbacks.get(i).userStopAborted(userId);
17639            } catch (RemoteException e) {
17640            }
17641        }
17642
17643        if (stopped) {
17644            mSystemServiceManager.cleanupUser(userId);
17645            synchronized (this) {
17646                mStackSupervisor.removeUserLocked(userId);
17647            }
17648        }
17649    }
17650
17651    @Override
17652    public UserInfo getCurrentUser() {
17653        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17654                != PackageManager.PERMISSION_GRANTED) && (
17655                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17656                != PackageManager.PERMISSION_GRANTED)) {
17657            String msg = "Permission Denial: getCurrentUser() from pid="
17658                    + Binder.getCallingPid()
17659                    + ", uid=" + Binder.getCallingUid()
17660                    + " requires " + INTERACT_ACROSS_USERS;
17661            Slog.w(TAG, msg);
17662            throw new SecurityException(msg);
17663        }
17664        synchronized (this) {
17665            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17666        }
17667    }
17668
17669    int getCurrentUserIdLocked() {
17670        return mCurrentUserId;
17671    }
17672
17673    @Override
17674    public boolean isUserRunning(int userId, boolean orStopped) {
17675        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17676                != PackageManager.PERMISSION_GRANTED) {
17677            String msg = "Permission Denial: isUserRunning() from pid="
17678                    + Binder.getCallingPid()
17679                    + ", uid=" + Binder.getCallingUid()
17680                    + " requires " + INTERACT_ACROSS_USERS;
17681            Slog.w(TAG, msg);
17682            throw new SecurityException(msg);
17683        }
17684        synchronized (this) {
17685            return isUserRunningLocked(userId, orStopped);
17686        }
17687    }
17688
17689    boolean isUserRunningLocked(int userId, boolean orStopped) {
17690        UserStartedState state = mStartedUsers.get(userId);
17691        if (state == null) {
17692            return false;
17693        }
17694        if (orStopped) {
17695            return true;
17696        }
17697        return state.mState != UserStartedState.STATE_STOPPING
17698                && state.mState != UserStartedState.STATE_SHUTDOWN;
17699    }
17700
17701    @Override
17702    public int[] getRunningUserIds() {
17703        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17704                != PackageManager.PERMISSION_GRANTED) {
17705            String msg = "Permission Denial: isUserRunning() from pid="
17706                    + Binder.getCallingPid()
17707                    + ", uid=" + Binder.getCallingUid()
17708                    + " requires " + INTERACT_ACROSS_USERS;
17709            Slog.w(TAG, msg);
17710            throw new SecurityException(msg);
17711        }
17712        synchronized (this) {
17713            return mStartedUserArray;
17714        }
17715    }
17716
17717    private void updateStartedUserArrayLocked() {
17718        int num = 0;
17719        for (int i=0; i<mStartedUsers.size();  i++) {
17720            UserStartedState uss = mStartedUsers.valueAt(i);
17721            // This list does not include stopping users.
17722            if (uss.mState != UserStartedState.STATE_STOPPING
17723                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17724                num++;
17725            }
17726        }
17727        mStartedUserArray = new int[num];
17728        num = 0;
17729        for (int i=0; i<mStartedUsers.size();  i++) {
17730            UserStartedState uss = mStartedUsers.valueAt(i);
17731            if (uss.mState != UserStartedState.STATE_STOPPING
17732                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17733                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17734                num++;
17735            }
17736        }
17737    }
17738
17739    @Override
17740    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17741        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17742                != PackageManager.PERMISSION_GRANTED) {
17743            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17744                    + Binder.getCallingPid()
17745                    + ", uid=" + Binder.getCallingUid()
17746                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17747            Slog.w(TAG, msg);
17748            throw new SecurityException(msg);
17749        }
17750
17751        mUserSwitchObservers.register(observer);
17752    }
17753
17754    @Override
17755    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17756        mUserSwitchObservers.unregister(observer);
17757    }
17758
17759    private boolean userExists(int userId) {
17760        if (userId == 0) {
17761            return true;
17762        }
17763        UserManagerService ums = getUserManagerLocked();
17764        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17765    }
17766
17767    int[] getUsersLocked() {
17768        UserManagerService ums = getUserManagerLocked();
17769        return ums != null ? ums.getUserIds() : new int[] { 0 };
17770    }
17771
17772    UserManagerService getUserManagerLocked() {
17773        if (mUserManager == null) {
17774            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17775            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17776        }
17777        return mUserManager;
17778    }
17779
17780    private int applyUserId(int uid, int userId) {
17781        return UserHandle.getUid(userId, uid);
17782    }
17783
17784    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17785        if (info == null) return null;
17786        ApplicationInfo newInfo = new ApplicationInfo(info);
17787        newInfo.uid = applyUserId(info.uid, userId);
17788        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17789                + info.packageName;
17790        return newInfo;
17791    }
17792
17793    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17794        if (aInfo == null
17795                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17796            return aInfo;
17797        }
17798
17799        ActivityInfo info = new ActivityInfo(aInfo);
17800        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17801        return info;
17802    }
17803
17804    private final class LocalService extends ActivityManagerInternal {
17805        @Override
17806        public void goingToSleep() {
17807            ActivityManagerService.this.goingToSleep();
17808        }
17809
17810        @Override
17811        public void wakingUp() {
17812            ActivityManagerService.this.wakingUp();
17813        }
17814    }
17815
17816    /**
17817     * An implementation of IAppTask, that allows an app to manage its own tasks via
17818     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17819     * only the process that calls getAppTasks() can call the AppTask methods.
17820     */
17821    class AppTaskImpl extends IAppTask.Stub {
17822        private int mTaskId;
17823        private int mCallingUid;
17824
17825        public AppTaskImpl(int taskId, int callingUid) {
17826            mTaskId = taskId;
17827            mCallingUid = callingUid;
17828        }
17829
17830        @Override
17831        public void finishAndRemoveTask() {
17832            // Ensure that we are called from the same process that created this AppTask
17833            if (mCallingUid != Binder.getCallingUid()) {
17834                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17835                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17836                return;
17837            }
17838
17839            synchronized (ActivityManagerService.this) {
17840                long origId = Binder.clearCallingIdentity();
17841                try {
17842                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17843                    if (tr != null) {
17844                        // Only kill the process if we are not a new document
17845                        int flags = tr.getBaseIntent().getFlags();
17846                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17847                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17848                        removeTaskByIdLocked(mTaskId,
17849                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17850                    }
17851                } finally {
17852                    Binder.restoreCallingIdentity(origId);
17853                }
17854            }
17855        }
17856
17857        @Override
17858        public ActivityManager.RecentTaskInfo getTaskInfo() {
17859            // Ensure that we are called from the same process that created this AppTask
17860            if (mCallingUid != Binder.getCallingUid()) {
17861                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17862                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17863                return null;
17864            }
17865
17866            synchronized (ActivityManagerService.this) {
17867                long origId = Binder.clearCallingIdentity();
17868                try {
17869                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17870                    if (tr != null) {
17871                        return createRecentTaskInfoFromTaskRecord(tr);
17872                    }
17873                } finally {
17874                    Binder.restoreCallingIdentity(origId);
17875                }
17876                return null;
17877            }
17878        }
17879    }
17880}
17881