ActivityManagerService.java revision 8746a478abcfb3b0d73b156232051af1e8d21ce2
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162
1163    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1164    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1165    static final int FIRST_COMPAT_MODE_MSG = 300;
1166    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1167
1168    AlertDialog mUidAlert;
1169    CompatModeDialog mCompatModeDialog;
1170    long mLastMemUsageReportTime = 0;
1171
1172    private LockToAppRequestDialog mLockToAppRequest;
1173
1174    /**
1175     * Flag whether the current user is a "monkey", i.e. whether
1176     * the UI is driven by a UI automation tool.
1177     */
1178    private boolean mUserIsMonkey;
1179
1180    /** Flag whether the device has a recents UI */
1181    final boolean mHasRecents;
1182
1183    final ServiceThread mHandlerThread;
1184    final MainHandler mHandler;
1185
1186    final class MainHandler extends Handler {
1187        public MainHandler(Looper looper) {
1188            super(looper, null, true);
1189        }
1190
1191        @Override
1192        public void handleMessage(Message msg) {
1193            switch (msg.what) {
1194            case SHOW_ERROR_MSG: {
1195                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1196                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1197                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1198                synchronized (ActivityManagerService.this) {
1199                    ProcessRecord proc = (ProcessRecord)data.get("app");
1200                    AppErrorResult res = (AppErrorResult) data.get("result");
1201                    if (proc != null && proc.crashDialog != null) {
1202                        Slog.e(TAG, "App already has crash dialog: " + proc);
1203                        if (res != null) {
1204                            res.set(0);
1205                        }
1206                        return;
1207                    }
1208                    if (!showBackground && UserHandle.getAppId(proc.uid)
1209                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1210                            && proc.pid != MY_PID) {
1211                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1212                        if (res != null) {
1213                            res.set(0);
1214                        }
1215                        return;
1216                    }
1217                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1218                        Dialog d = new AppErrorDialog(mContext,
1219                                ActivityManagerService.this, res, proc);
1220                        d.show();
1221                        proc.crashDialog = d;
1222                    } else {
1223                        // The device is asleep, so just pretend that the user
1224                        // saw a crash dialog and hit "force quit".
1225                        if (res != null) {
1226                            res.set(0);
1227                        }
1228                    }
1229                }
1230
1231                ensureBootCompleted();
1232            } break;
1233            case SHOW_NOT_RESPONDING_MSG: {
1234                synchronized (ActivityManagerService.this) {
1235                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    if (proc != null && proc.anrDialog != null) {
1238                        Slog.e(TAG, "App already has anr dialog: " + proc);
1239                        return;
1240                    }
1241
1242                    Intent intent = new Intent("android.intent.action.ANR");
1243                    if (!mProcessesReady) {
1244                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1245                                | Intent.FLAG_RECEIVER_FOREGROUND);
1246                    }
1247                    broadcastIntentLocked(null, null, intent,
1248                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1249                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1250
1251                    if (mShowDialogs) {
1252                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1253                                mContext, proc, (ActivityRecord)data.get("activity"),
1254                                msg.arg1 != 0);
1255                        d.show();
1256                        proc.anrDialog = d;
1257                    } else {
1258                        // Just kill the app if there is no dialog to be shown.
1259                        killAppAtUsersRequest(proc, null);
1260                    }
1261                }
1262
1263                ensureBootCompleted();
1264            } break;
1265            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1266                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                synchronized (ActivityManagerService.this) {
1268                    ProcessRecord proc = (ProcessRecord) data.get("app");
1269                    if (proc == null) {
1270                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1271                        break;
1272                    }
1273                    if (proc.crashDialog != null) {
1274                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1275                        return;
1276                    }
1277                    AppErrorResult res = (AppErrorResult) data.get("result");
1278                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1279                        Dialog d = new StrictModeViolationDialog(mContext,
1280                                ActivityManagerService.this, res, proc);
1281                        d.show();
1282                        proc.crashDialog = d;
1283                    } else {
1284                        // The device is asleep, so just pretend that the user
1285                        // saw a crash dialog and hit "force quit".
1286                        res.set(0);
1287                    }
1288                }
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_FACTORY_ERROR_MSG: {
1292                Dialog d = new FactoryErrorDialog(
1293                    mContext, msg.getData().getCharSequence("msg"));
1294                d.show();
1295                ensureBootCompleted();
1296            } break;
1297            case UPDATE_CONFIGURATION_MSG: {
1298                final ContentResolver resolver = mContext.getContentResolver();
1299                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1300            } break;
1301            case GC_BACKGROUND_PROCESSES_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    performAppGcsIfAppropriateLocked();
1304                }
1305            } break;
1306            case WAIT_FOR_DEBUGGER_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    ProcessRecord app = (ProcessRecord)msg.obj;
1309                    if (msg.arg1 != 0) {
1310                        if (!app.waitedForDebugger) {
1311                            Dialog d = new AppWaitingForDebuggerDialog(
1312                                    ActivityManagerService.this,
1313                                    mContext, app);
1314                            app.waitDialog = d;
1315                            app.waitedForDebugger = true;
1316                            d.show();
1317                        }
1318                    } else {
1319                        if (app.waitDialog != null) {
1320                            app.waitDialog.dismiss();
1321                            app.waitDialog = null;
1322                        }
1323                    }
1324                }
1325            } break;
1326            case SERVICE_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1332                    return;
1333                }
1334                mServices.serviceTimeout((ProcessRecord)msg.obj);
1335            } break;
1336            case UPDATE_TIME_ZONE: {
1337                synchronized (ActivityManagerService.this) {
1338                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1339                        ProcessRecord r = mLruProcesses.get(i);
1340                        if (r.thread != null) {
1341                            try {
1342                                r.thread.updateTimeZone();
1343                            } catch (RemoteException ex) {
1344                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1345                            }
1346                        }
1347                    }
1348                }
1349            } break;
1350            case CLEAR_DNS_CACHE_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1353                        ProcessRecord r = mLruProcesses.get(i);
1354                        if (r.thread != null) {
1355                            try {
1356                                r.thread.clearDnsCache();
1357                            } catch (RemoteException ex) {
1358                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1359                            }
1360                        }
1361                    }
1362                }
1363            } break;
1364            case UPDATE_HTTP_PROXY_MSG: {
1365                ProxyInfo proxy = (ProxyInfo)msg.obj;
1366                String host = "";
1367                String port = "";
1368                String exclList = "";
1369                Uri pacFileUrl = Uri.EMPTY;
1370                if (proxy != null) {
1371                    host = proxy.getHost();
1372                    port = Integer.toString(proxy.getPort());
1373                    exclList = proxy.getExclusionListAsString();
1374                    pacFileUrl = proxy.getPacFileUrl();
1375                }
1376                synchronized (ActivityManagerService.this) {
1377                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1378                        ProcessRecord r = mLruProcesses.get(i);
1379                        if (r.thread != null) {
1380                            try {
1381                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1382                            } catch (RemoteException ex) {
1383                                Slog.w(TAG, "Failed to update http proxy for: " +
1384                                        r.info.processName);
1385                            }
1386                        }
1387                    }
1388                }
1389            } break;
1390            case SHOW_UID_ERROR_MSG: {
1391                String title = "System UIDs Inconsistent";
1392                String text = "UIDs on the system are inconsistent, you need to wipe your"
1393                        + " data partition or your device will be unstable.";
1394                Log.e(TAG, title + ": " + text);
1395                if (mShowDialogs) {
1396                    // XXX This is a temporary dialog, no need to localize.
1397                    AlertDialog d = new BaseErrorDialog(mContext);
1398                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1399                    d.setCancelable(false);
1400                    d.setTitle(title);
1401                    d.setMessage(text);
1402                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1403                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1404                    mUidAlert = d;
1405                    d.show();
1406                }
1407            } break;
1408            case IM_FEELING_LUCKY_MSG: {
1409                if (mUidAlert != null) {
1410                    mUidAlert.dismiss();
1411                    mUidAlert = null;
1412                }
1413            } break;
1414            case PROC_START_TIMEOUT_MSG: {
1415                if (mDidDexOpt) {
1416                    mDidDexOpt = false;
1417                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1418                    nmsg.obj = msg.obj;
1419                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1420                    return;
1421                }
1422                ProcessRecord app = (ProcessRecord)msg.obj;
1423                synchronized (ActivityManagerService.this) {
1424                    processStartTimedOutLocked(app);
1425                }
1426            } break;
1427            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1430                }
1431            } break;
1432            case KILL_APPLICATION_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    int appid = msg.arg1;
1435                    boolean restart = (msg.arg2 == 1);
1436                    Bundle bundle = (Bundle)msg.obj;
1437                    String pkg = bundle.getString("pkg");
1438                    String reason = bundle.getString("reason");
1439                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1440                            false, UserHandle.USER_ALL, reason);
1441                }
1442            } break;
1443            case FINALIZE_PENDING_INTENT_MSG: {
1444                ((PendingIntentRecord)msg.obj).completeFinalize();
1445            } break;
1446            case POST_HEAVY_NOTIFICATION_MSG: {
1447                INotificationManager inm = NotificationManager.getService();
1448                if (inm == null) {
1449                    return;
1450                }
1451
1452                ActivityRecord root = (ActivityRecord)msg.obj;
1453                ProcessRecord process = root.app;
1454                if (process == null) {
1455                    return;
1456                }
1457
1458                try {
1459                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1460                    String text = mContext.getString(R.string.heavy_weight_notification,
1461                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1462                    Notification notification = new Notification();
1463                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1464                    notification.when = 0;
1465                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1466                    notification.tickerText = text;
1467                    notification.defaults = 0; // please be quiet
1468                    notification.sound = null;
1469                    notification.vibrate = null;
1470                    notification.setLatestEventInfo(context, text,
1471                            mContext.getText(R.string.heavy_weight_notification_detail),
1472                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1473                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1474                                    new UserHandle(root.userId)));
1475
1476                    try {
1477                        int[] outId = new int[1];
1478                        inm.enqueueNotificationWithTag("android", "android", null,
1479                                R.string.heavy_weight_notification,
1480                                notification, outId, root.userId);
1481                    } catch (RuntimeException e) {
1482                        Slog.w(ActivityManagerService.TAG,
1483                                "Error showing notification for heavy-weight app", e);
1484                    } catch (RemoteException e) {
1485                    }
1486                } catch (NameNotFoundException e) {
1487                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1488                }
1489            } break;
1490            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1491                INotificationManager inm = NotificationManager.getService();
1492                if (inm == null) {
1493                    return;
1494                }
1495                try {
1496                    inm.cancelNotificationWithTag("android", null,
1497                            R.string.heavy_weight_notification,  msg.arg1);
1498                } catch (RuntimeException e) {
1499                    Slog.w(ActivityManagerService.TAG,
1500                            "Error canceling notification for service", e);
1501                } catch (RemoteException e) {
1502                }
1503            } break;
1504            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1505                synchronized (ActivityManagerService.this) {
1506                    checkExcessivePowerUsageLocked(true);
1507                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1508                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1510                }
1511            } break;
1512            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1513                synchronized (ActivityManagerService.this) {
1514                    ActivityRecord ar = (ActivityRecord)msg.obj;
1515                    if (mCompatModeDialog != null) {
1516                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1517                                ar.info.applicationInfo.packageName)) {
1518                            return;
1519                        }
1520                        mCompatModeDialog.dismiss();
1521                        mCompatModeDialog = null;
1522                    }
1523                    if (ar != null && false) {
1524                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1525                                ar.packageName)) {
1526                            int mode = mCompatModePackages.computeCompatModeLocked(
1527                                    ar.info.applicationInfo);
1528                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1529                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1530                                mCompatModeDialog = new CompatModeDialog(
1531                                        ActivityManagerService.this, mContext,
1532                                        ar.info.applicationInfo);
1533                                mCompatModeDialog.show();
1534                            }
1535                        }
1536                    }
1537                }
1538                break;
1539            }
1540            case DISPATCH_PROCESSES_CHANGED: {
1541                dispatchProcessesChanged();
1542                break;
1543            }
1544            case DISPATCH_PROCESS_DIED: {
1545                final int pid = msg.arg1;
1546                final int uid = msg.arg2;
1547                dispatchProcessDied(pid, uid);
1548                break;
1549            }
1550            case REPORT_MEM_USAGE_MSG: {
1551                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1552                Thread thread = new Thread() {
1553                    @Override public void run() {
1554                        final SparseArray<ProcessMemInfo> infoMap
1555                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1556                        for (int i=0, N=memInfos.size(); i<N; i++) {
1557                            ProcessMemInfo mi = memInfos.get(i);
1558                            infoMap.put(mi.pid, mi);
1559                        }
1560                        updateCpuStatsNow();
1561                        synchronized (mProcessCpuThread) {
1562                            final int N = mProcessCpuTracker.countStats();
1563                            for (int i=0; i<N; i++) {
1564                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1565                                if (st.vsize > 0) {
1566                                    long pss = Debug.getPss(st.pid, null);
1567                                    if (pss > 0) {
1568                                        if (infoMap.indexOfKey(st.pid) < 0) {
1569                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1570                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1571                                            mi.pss = pss;
1572                                            memInfos.add(mi);
1573                                        }
1574                                    }
1575                                }
1576                            }
1577                        }
1578
1579                        long totalPss = 0;
1580                        for (int i=0, N=memInfos.size(); i<N; i++) {
1581                            ProcessMemInfo mi = memInfos.get(i);
1582                            if (mi.pss == 0) {
1583                                mi.pss = Debug.getPss(mi.pid, null);
1584                            }
1585                            totalPss += mi.pss;
1586                        }
1587                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1588                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1589                                if (lhs.oomAdj != rhs.oomAdj) {
1590                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1591                                }
1592                                if (lhs.pss != rhs.pss) {
1593                                    return lhs.pss < rhs.pss ? 1 : -1;
1594                                }
1595                                return 0;
1596                            }
1597                        });
1598
1599                        StringBuilder tag = new StringBuilder(128);
1600                        StringBuilder stack = new StringBuilder(128);
1601                        tag.append("Low on memory -- ");
1602                        appendMemBucket(tag, totalPss, "total", false);
1603                        appendMemBucket(stack, totalPss, "total", true);
1604
1605                        StringBuilder logBuilder = new StringBuilder(1024);
1606                        logBuilder.append("Low on memory:\n");
1607
1608                        boolean firstLine = true;
1609                        int lastOomAdj = Integer.MIN_VALUE;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612
1613                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1614                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1615                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1616                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1617                                if (lastOomAdj != mi.oomAdj) {
1618                                    lastOomAdj = mi.oomAdj;
1619                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                        tag.append(" / ");
1621                                    }
1622                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1623                                        if (firstLine) {
1624                                            stack.append(":");
1625                                            firstLine = false;
1626                                        }
1627                                        stack.append("\n\t at ");
1628                                    } else {
1629                                        stack.append("$");
1630                                    }
1631                                } else {
1632                                    tag.append(" ");
1633                                    stack.append("$");
1634                                }
1635                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1636                                    appendMemBucket(tag, mi.pss, mi.name, false);
1637                                }
1638                                appendMemBucket(stack, mi.pss, mi.name, true);
1639                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1640                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1641                                    stack.append("(");
1642                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1643                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1644                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1645                                            stack.append(":");
1646                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1647                                        }
1648                                    }
1649                                    stack.append(")");
1650                                }
1651                            }
1652
1653                            logBuilder.append("  ");
1654                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1655                            logBuilder.append(' ');
1656                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1657                            logBuilder.append(' ');
1658                            ProcessList.appendRamKb(logBuilder, mi.pss);
1659                            logBuilder.append(" kB: ");
1660                            logBuilder.append(mi.name);
1661                            logBuilder.append(" (");
1662                            logBuilder.append(mi.pid);
1663                            logBuilder.append(") ");
1664                            logBuilder.append(mi.adjType);
1665                            logBuilder.append('\n');
1666                            if (mi.adjReason != null) {
1667                                logBuilder.append("                      ");
1668                                logBuilder.append(mi.adjReason);
1669                                logBuilder.append('\n');
1670                            }
1671                        }
1672
1673                        logBuilder.append("           ");
1674                        ProcessList.appendRamKb(logBuilder, totalPss);
1675                        logBuilder.append(" kB: TOTAL\n");
1676
1677                        long[] infos = new long[Debug.MEMINFO_COUNT];
1678                        Debug.getMemInfo(infos);
1679                        logBuilder.append("  MemInfo: ");
1680                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1685                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1686                            logBuilder.append("  ZRAM: ");
1687                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1688                            logBuilder.append(" kB RAM, ");
1689                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1690                            logBuilder.append(" kB swap total, ");
1691                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1692                            logBuilder.append(" kB swap free\n");
1693                        }
1694                        Slog.i(TAG, logBuilder.toString());
1695
1696                        StringBuilder dropBuilder = new StringBuilder(1024);
1697                        /*
1698                        StringWriter oomSw = new StringWriter();
1699                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1700                        StringWriter catSw = new StringWriter();
1701                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                        String[] emptyArgs = new String[] { };
1703                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1704                        oomPw.flush();
1705                        String oomString = oomSw.toString();
1706                        */
1707                        dropBuilder.append(stack);
1708                        dropBuilder.append('\n');
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append(logBuilder);
1711                        dropBuilder.append('\n');
1712                        /*
1713                        dropBuilder.append(oomString);
1714                        dropBuilder.append('\n');
1715                        */
1716                        StringWriter catSw = new StringWriter();
1717                        synchronized (ActivityManagerService.this) {
1718                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1719                            String[] emptyArgs = new String[] { };
1720                            catPw.println();
1721                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1722                            catPw.println();
1723                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1724                                    false, false, null);
1725                            catPw.println();
1726                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1727                            catPw.flush();
1728                        }
1729                        dropBuilder.append(catSw.toString());
1730                        addErrorToDropBox("lowmem", null, "system_server", null,
1731                                null, tag.toString(), dropBuilder.toString(), null, null);
1732                        //Slog.i(TAG, "Sent to dropbox:");
1733                        //Slog.i(TAG, dropBuilder.toString());
1734                        synchronized (ActivityManagerService.this) {
1735                            long now = SystemClock.uptimeMillis();
1736                            if (mLastMemUsageReportTime < now) {
1737                                mLastMemUsageReportTime = now;
1738                            }
1739                        }
1740                    }
1741                };
1742                thread.start();
1743                break;
1744            }
1745            case REPORT_USER_SWITCH_MSG: {
1746                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1747                break;
1748            }
1749            case CONTINUE_USER_SWITCH_MSG: {
1750                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1751                break;
1752            }
1753            case USER_SWITCH_TIMEOUT_MSG: {
1754                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1755                break;
1756            }
1757            case IMMERSIVE_MODE_LOCK_MSG: {
1758                final boolean nextState = (msg.arg1 != 0);
1759                if (mUpdateLock.isHeld() != nextState) {
1760                    if (DEBUG_IMMERSIVE) {
1761                        final ActivityRecord r = (ActivityRecord) msg.obj;
1762                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1763                    }
1764                    if (nextState) {
1765                        mUpdateLock.acquire();
1766                    } else {
1767                        mUpdateLock.release();
1768                    }
1769                }
1770                break;
1771            }
1772            case PERSIST_URI_GRANTS_MSG: {
1773                writeGrantedUriPermissions();
1774                break;
1775            }
1776            case REQUEST_ALL_PSS_MSG: {
1777                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1778                break;
1779            }
1780            case START_PROFILES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    startProfilesLocked();
1783                }
1784                break;
1785            }
1786            case UPDATE_TIME: {
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799                break;
1800            }
1801            case SYSTEM_USER_START_MSG: {
1802                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1803                        Integer.toString(msg.arg1), msg.arg1);
1804                mSystemServiceManager.startUser(msg.arg1);
1805                break;
1806            }
1807            case SYSTEM_USER_CURRENT_MSG: {
1808                mBatteryStatsService.noteEvent(
1809                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1810                        Integer.toString(msg.arg2), msg.arg2);
1811                mBatteryStatsService.noteEvent(
1812                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1813                        Integer.toString(msg.arg1), msg.arg1);
1814                mSystemServiceManager.switchUser(msg.arg1);
1815                break;
1816            }
1817            case ENTER_ANIMATION_COMPLETE_MSG: {
1818                synchronized (ActivityManagerService.this) {
1819                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1820                    if (r != null && r.app != null && r.app.thread != null) {
1821                        try {
1822                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1823                        } catch (RemoteException e) {
1824                        }
1825                    }
1826                }
1827                break;
1828            }
1829            }
1830        }
1831    };
1832
1833    static final int COLLECT_PSS_BG_MSG = 1;
1834
1835    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1836        @Override
1837        public void handleMessage(Message msg) {
1838            switch (msg.what) {
1839            case COLLECT_PSS_BG_MSG: {
1840                long start = SystemClock.uptimeMillis();
1841                MemInfoReader memInfo = null;
1842                synchronized (ActivityManagerService.this) {
1843                    if (mFullPssPending) {
1844                        mFullPssPending = false;
1845                        memInfo = new MemInfoReader();
1846                    }
1847                }
1848                if (memInfo != null) {
1849                    updateCpuStatsNow();
1850                    long nativeTotalPss = 0;
1851                    synchronized (mProcessCpuThread) {
1852                        final int N = mProcessCpuTracker.countStats();
1853                        for (int j=0; j<N; j++) {
1854                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1855                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1856                                // This is definitely an application process; skip it.
1857                                continue;
1858                            }
1859                            synchronized (mPidsSelfLocked) {
1860                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1861                                    // This is one of our own processes; skip it.
1862                                    continue;
1863                                }
1864                            }
1865                            nativeTotalPss += Debug.getPss(st.pid, null);
1866                        }
1867                    }
1868                    memInfo.readMemInfo();
1869                    synchronized (this) {
1870                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1871                                + (SystemClock.uptimeMillis()-start) + "ms");
1872                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1873                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1874                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1875                                        +memInfo.getSlabSizeKb(),
1876                                nativeTotalPss);
1877                    }
1878                }
1879
1880                int i=0, num=0;
1881                long[] tmp = new long[1];
1882                do {
1883                    ProcessRecord proc;
1884                    int procState;
1885                    int pid;
1886                    synchronized (ActivityManagerService.this) {
1887                        if (i >= mPendingPssProcesses.size()) {
1888                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1889                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1890                            mPendingPssProcesses.clear();
1891                            return;
1892                        }
1893                        proc = mPendingPssProcesses.get(i);
1894                        procState = proc.pssProcState;
1895                        if (proc.thread != null && procState == proc.setProcState) {
1896                            pid = proc.pid;
1897                        } else {
1898                            proc = null;
1899                            pid = 0;
1900                        }
1901                        i++;
1902                    }
1903                    if (proc != null) {
1904                        long pss = Debug.getPss(pid, tmp);
1905                        synchronized (ActivityManagerService.this) {
1906                            if (proc.thread != null && proc.setProcState == procState
1907                                    && proc.pid == pid) {
1908                                num++;
1909                                proc.lastPssTime = SystemClock.uptimeMillis();
1910                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1911                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1912                                        + ": " + pss + " lastPss=" + proc.lastPss
1913                                        + " state=" + ProcessList.makeProcStateString(procState));
1914                                if (proc.initialIdlePss == 0) {
1915                                    proc.initialIdlePss = pss;
1916                                }
1917                                proc.lastPss = pss;
1918                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1919                                    proc.lastCachedPss = pss;
1920                                }
1921                            }
1922                        }
1923                    }
1924                } while (true);
1925            }
1926            }
1927        }
1928    };
1929
1930    /**
1931     * Monitor for package changes and update our internal state.
1932     */
1933    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1934        @Override
1935        public void onPackageRemoved(String packageName, int uid) {
1936            // Remove all tasks with activities in the specified package from the list of recent tasks
1937            synchronized (ActivityManagerService.this) {
1938                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1939                    TaskRecord tr = mRecentTasks.get(i);
1940                    ComponentName cn = tr.intent.getComponent();
1941                    if (cn != null && cn.getPackageName().equals(packageName)) {
1942                        // If the package name matches, remove the task and kill the process
1943                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1944                    }
1945                }
1946            }
1947        }
1948
1949        @Override
1950        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1951            onPackageModified(packageName);
1952            return true;
1953        }
1954
1955        @Override
1956        public void onPackageModified(String packageName) {
1957            final PackageManager pm = mContext.getPackageManager();
1958            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1959                    new ArrayList<Pair<Intent, Integer>>();
1960            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1961            // Copy the list of recent tasks so that we don't hold onto the lock on
1962            // ActivityManagerService for long periods while checking if components exist.
1963            synchronized (ActivityManagerService.this) {
1964                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1965                    TaskRecord tr = mRecentTasks.get(i);
1966                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1967                }
1968            }
1969            // Check the recent tasks and filter out all tasks with components that no longer exist.
1970            Intent tmpI = new Intent();
1971            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1972                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1973                ComponentName cn = p.first.getComponent();
1974                if (cn != null && cn.getPackageName().equals(packageName)) {
1975                    try {
1976                        // Add the task to the list to remove if the component no longer exists
1977                        tmpI.setComponent(cn);
1978                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1979                            tasksToRemove.add(p.second);
1980                        }
1981                    } catch (Exception e) {}
1982                }
1983            }
1984            // Prune all the tasks with removed components from the list of recent tasks
1985            synchronized (ActivityManagerService.this) {
1986                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1987                    // Remove the task but don't kill the process (since other components in that
1988                    // package may still be running and in the background)
1989                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1990                }
1991            }
1992        }
1993
1994        @Override
1995        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1996            // Force stop the specified packages
1997            if (packages != null) {
1998                for (String pkg : packages) {
1999                    synchronized (ActivityManagerService.this) {
2000                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2001                                "finished booting")) {
2002                            return true;
2003                        }
2004                    }
2005                }
2006            }
2007            return false;
2008        }
2009    };
2010
2011    public void setSystemProcess() {
2012        try {
2013            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2014            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2015            ServiceManager.addService("meminfo", new MemBinder(this));
2016            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2017            ServiceManager.addService("dbinfo", new DbBinder(this));
2018            if (MONITOR_CPU_USAGE) {
2019                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2020            }
2021            ServiceManager.addService("permission", new PermissionController(this));
2022
2023            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2024                    "android", STOCK_PM_FLAGS);
2025            mSystemThread.installSystemApplicationInfo(info);
2026
2027            synchronized (this) {
2028                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2029                app.persistent = true;
2030                app.pid = MY_PID;
2031                app.maxAdj = ProcessList.SYSTEM_ADJ;
2032                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2033                mProcessNames.put(app.processName, app.uid, app);
2034                synchronized (mPidsSelfLocked) {
2035                    mPidsSelfLocked.put(app.pid, app);
2036                }
2037                updateLruProcessLocked(app, false, null);
2038                updateOomAdjLocked();
2039            }
2040        } catch (PackageManager.NameNotFoundException e) {
2041            throw new RuntimeException(
2042                    "Unable to find android system package", e);
2043        }
2044    }
2045
2046    public void setWindowManager(WindowManagerService wm) {
2047        mWindowManager = wm;
2048        mStackSupervisor.setWindowManager(wm);
2049    }
2050
2051    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2052        mUsageStatsService = usageStatsManager;
2053    }
2054
2055    public void startObservingNativeCrashes() {
2056        final NativeCrashListener ncl = new NativeCrashListener(this);
2057        ncl.start();
2058    }
2059
2060    public IAppOpsService getAppOpsService() {
2061        return mAppOpsService;
2062    }
2063
2064    static class MemBinder extends Binder {
2065        ActivityManagerService mActivityManagerService;
2066        MemBinder(ActivityManagerService activityManagerService) {
2067            mActivityManagerService = activityManagerService;
2068        }
2069
2070        @Override
2071        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2072            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2073                    != PackageManager.PERMISSION_GRANTED) {
2074                pw.println("Permission Denial: can't dump meminfo from from pid="
2075                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2076                        + " without permission " + android.Manifest.permission.DUMP);
2077                return;
2078            }
2079
2080            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2081        }
2082    }
2083
2084    static class GraphicsBinder extends Binder {
2085        ActivityManagerService mActivityManagerService;
2086        GraphicsBinder(ActivityManagerService activityManagerService) {
2087            mActivityManagerService = activityManagerService;
2088        }
2089
2090        @Override
2091        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2092            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2093                    != PackageManager.PERMISSION_GRANTED) {
2094                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2095                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2096                        + " without permission " + android.Manifest.permission.DUMP);
2097                return;
2098            }
2099
2100            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2101        }
2102    }
2103
2104    static class DbBinder extends Binder {
2105        ActivityManagerService mActivityManagerService;
2106        DbBinder(ActivityManagerService activityManagerService) {
2107            mActivityManagerService = activityManagerService;
2108        }
2109
2110        @Override
2111        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2112            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2113                    != PackageManager.PERMISSION_GRANTED) {
2114                pw.println("Permission Denial: can't dump dbinfo from from pid="
2115                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2116                        + " without permission " + android.Manifest.permission.DUMP);
2117                return;
2118            }
2119
2120            mActivityManagerService.dumpDbInfo(fd, pw, args);
2121        }
2122    }
2123
2124    static class CpuBinder extends Binder {
2125        ActivityManagerService mActivityManagerService;
2126        CpuBinder(ActivityManagerService activityManagerService) {
2127            mActivityManagerService = activityManagerService;
2128        }
2129
2130        @Override
2131        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2132            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2133                    != PackageManager.PERMISSION_GRANTED) {
2134                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2135                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2136                        + " without permission " + android.Manifest.permission.DUMP);
2137                return;
2138            }
2139
2140            synchronized (mActivityManagerService.mProcessCpuThread) {
2141                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2142                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2143                        SystemClock.uptimeMillis()));
2144            }
2145        }
2146    }
2147
2148    public static final class Lifecycle extends SystemService {
2149        private final ActivityManagerService mService;
2150
2151        public Lifecycle(Context context) {
2152            super(context);
2153            mService = new ActivityManagerService(context);
2154        }
2155
2156        @Override
2157        public void onStart() {
2158            mService.start();
2159        }
2160
2161        public ActivityManagerService getService() {
2162            return mService;
2163        }
2164    }
2165
2166    // Note: This method is invoked on the main thread but may need to attach various
2167    // handlers to other threads.  So take care to be explicit about the looper.
2168    public ActivityManagerService(Context systemContext) {
2169        mContext = systemContext;
2170        mFactoryTest = FactoryTest.getMode();
2171        mSystemThread = ActivityThread.currentActivityThread();
2172
2173        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2174
2175        mHandlerThread = new ServiceThread(TAG,
2176                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2177        mHandlerThread.start();
2178        mHandler = new MainHandler(mHandlerThread.getLooper());
2179
2180        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2181                "foreground", BROADCAST_FG_TIMEOUT, false);
2182        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2183                "background", BROADCAST_BG_TIMEOUT, true);
2184        mBroadcastQueues[0] = mFgBroadcastQueue;
2185        mBroadcastQueues[1] = mBgBroadcastQueue;
2186
2187        mServices = new ActiveServices(this);
2188        mProviderMap = new ProviderMap(this);
2189
2190        // TODO: Move creation of battery stats service outside of activity manager service.
2191        File dataDir = Environment.getDataDirectory();
2192        File systemDir = new File(dataDir, "system");
2193        systemDir.mkdirs();
2194        mBatteryStatsService = new BatteryStatsService(new File(
2195                systemDir, "batterystats.bin").toString(), mHandler);
2196        mBatteryStatsService.getActiveStatistics().readLocked();
2197        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2198        mOnBattery = DEBUG_POWER ? true
2199                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2200        mBatteryStatsService.getActiveStatistics().setCallback(this);
2201
2202        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2203
2204        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2205
2206        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2207
2208        // User 0 is the first and only user that runs at boot.
2209        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2210        mUserLru.add(Integer.valueOf(0));
2211        updateStartedUserArrayLocked();
2212
2213        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2214            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2215
2216        mConfiguration.setToDefaults();
2217        mConfiguration.setLocale(Locale.getDefault());
2218
2219        mConfigurationSeq = mConfiguration.seq = 1;
2220        mProcessCpuTracker.init();
2221
2222        mHasRecents = mContext.getResources().getBoolean(
2223                com.android.internal.R.bool.config_hasRecents);
2224
2225        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2226        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2227        mStackSupervisor = new ActivityStackSupervisor(this);
2228        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2229
2230        mProcessCpuThread = new Thread("CpuTracker") {
2231            @Override
2232            public void run() {
2233                while (true) {
2234                    try {
2235                        try {
2236                            synchronized(this) {
2237                                final long now = SystemClock.uptimeMillis();
2238                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2239                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2240                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2241                                //        + ", write delay=" + nextWriteDelay);
2242                                if (nextWriteDelay < nextCpuDelay) {
2243                                    nextCpuDelay = nextWriteDelay;
2244                                }
2245                                if (nextCpuDelay > 0) {
2246                                    mProcessCpuMutexFree.set(true);
2247                                    this.wait(nextCpuDelay);
2248                                }
2249                            }
2250                        } catch (InterruptedException e) {
2251                        }
2252                        updateCpuStatsNow();
2253                    } catch (Exception e) {
2254                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2255                    }
2256                }
2257            }
2258        };
2259
2260        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2261
2262        Watchdog.getInstance().addMonitor(this);
2263        Watchdog.getInstance().addThread(mHandler);
2264    }
2265
2266    public void setSystemServiceManager(SystemServiceManager mgr) {
2267        mSystemServiceManager = mgr;
2268    }
2269
2270    private void start() {
2271        Process.removeAllProcessGroups();
2272        mProcessCpuThread.start();
2273
2274        mBatteryStatsService.publish(mContext);
2275        mAppOpsService.publish(mContext);
2276        Slog.d("AppOps", "AppOpsService published");
2277        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2278    }
2279
2280    public void initPowerManagement() {
2281        mStackSupervisor.initPowerManagement();
2282        mBatteryStatsService.initPowerManagement();
2283    }
2284
2285    @Override
2286    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2287            throws RemoteException {
2288        if (code == SYSPROPS_TRANSACTION) {
2289            // We need to tell all apps about the system property change.
2290            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2291            synchronized(this) {
2292                final int NP = mProcessNames.getMap().size();
2293                for (int ip=0; ip<NP; ip++) {
2294                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2295                    final int NA = apps.size();
2296                    for (int ia=0; ia<NA; ia++) {
2297                        ProcessRecord app = apps.valueAt(ia);
2298                        if (app.thread != null) {
2299                            procs.add(app.thread.asBinder());
2300                        }
2301                    }
2302                }
2303            }
2304
2305            int N = procs.size();
2306            for (int i=0; i<N; i++) {
2307                Parcel data2 = Parcel.obtain();
2308                try {
2309                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2310                } catch (RemoteException e) {
2311                }
2312                data2.recycle();
2313            }
2314        }
2315        try {
2316            return super.onTransact(code, data, reply, flags);
2317        } catch (RuntimeException e) {
2318            // The activity manager only throws security exceptions, so let's
2319            // log all others.
2320            if (!(e instanceof SecurityException)) {
2321                Slog.wtf(TAG, "Activity Manager Crash", e);
2322            }
2323            throw e;
2324        }
2325    }
2326
2327    void updateCpuStats() {
2328        final long now = SystemClock.uptimeMillis();
2329        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2330            return;
2331        }
2332        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2333            synchronized (mProcessCpuThread) {
2334                mProcessCpuThread.notify();
2335            }
2336        }
2337    }
2338
2339    void updateCpuStatsNow() {
2340        synchronized (mProcessCpuThread) {
2341            mProcessCpuMutexFree.set(false);
2342            final long now = SystemClock.uptimeMillis();
2343            boolean haveNewCpuStats = false;
2344
2345            if (MONITOR_CPU_USAGE &&
2346                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2347                mLastCpuTime.set(now);
2348                haveNewCpuStats = true;
2349                mProcessCpuTracker.update();
2350                //Slog.i(TAG, mProcessCpu.printCurrentState());
2351                //Slog.i(TAG, "Total CPU usage: "
2352                //        + mProcessCpu.getTotalCpuPercent() + "%");
2353
2354                // Slog the cpu usage if the property is set.
2355                if ("true".equals(SystemProperties.get("events.cpu"))) {
2356                    int user = mProcessCpuTracker.getLastUserTime();
2357                    int system = mProcessCpuTracker.getLastSystemTime();
2358                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2359                    int irq = mProcessCpuTracker.getLastIrqTime();
2360                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2361                    int idle = mProcessCpuTracker.getLastIdleTime();
2362
2363                    int total = user + system + iowait + irq + softIrq + idle;
2364                    if (total == 0) total = 1;
2365
2366                    EventLog.writeEvent(EventLogTags.CPU,
2367                            ((user+system+iowait+irq+softIrq) * 100) / total,
2368                            (user * 100) / total,
2369                            (system * 100) / total,
2370                            (iowait * 100) / total,
2371                            (irq * 100) / total,
2372                            (softIrq * 100) / total);
2373                }
2374            }
2375
2376            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2377            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2378            synchronized(bstats) {
2379                synchronized(mPidsSelfLocked) {
2380                    if (haveNewCpuStats) {
2381                        if (mOnBattery) {
2382                            int perc = bstats.startAddingCpuLocked();
2383                            int totalUTime = 0;
2384                            int totalSTime = 0;
2385                            final int N = mProcessCpuTracker.countStats();
2386                            for (int i=0; i<N; i++) {
2387                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2388                                if (!st.working) {
2389                                    continue;
2390                                }
2391                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2392                                int otherUTime = (st.rel_utime*perc)/100;
2393                                int otherSTime = (st.rel_stime*perc)/100;
2394                                totalUTime += otherUTime;
2395                                totalSTime += otherSTime;
2396                                if (pr != null) {
2397                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2398                                    if (ps == null || !ps.isActive()) {
2399                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2400                                                pr.info.uid, pr.processName);
2401                                    }
2402                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2403                                            st.rel_stime-otherSTime);
2404                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2405                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2406                                } else {
2407                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2408                                    if (ps == null || !ps.isActive()) {
2409                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2410                                                bstats.mapUid(st.uid), st.name);
2411                                    }
2412                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2413                                            st.rel_stime-otherSTime);
2414                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2415                                }
2416                            }
2417                            bstats.finishAddingCpuLocked(perc, totalUTime,
2418                                    totalSTime, cpuSpeedTimes);
2419                        }
2420                    }
2421                }
2422
2423                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2424                    mLastWriteTime = now;
2425                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2426                }
2427            }
2428        }
2429    }
2430
2431    @Override
2432    public void batteryNeedsCpuUpdate() {
2433        updateCpuStatsNow();
2434    }
2435
2436    @Override
2437    public void batteryPowerChanged(boolean onBattery) {
2438        // When plugging in, update the CPU stats first before changing
2439        // the plug state.
2440        updateCpuStatsNow();
2441        synchronized (this) {
2442            synchronized(mPidsSelfLocked) {
2443                mOnBattery = DEBUG_POWER ? true : onBattery;
2444            }
2445        }
2446    }
2447
2448    /**
2449     * Initialize the application bind args. These are passed to each
2450     * process when the bindApplication() IPC is sent to the process. They're
2451     * lazily setup to make sure the services are running when they're asked for.
2452     */
2453    private HashMap<String, IBinder> getCommonServicesLocked() {
2454        if (mAppBindArgs == null) {
2455            mAppBindArgs = new HashMap<String, IBinder>();
2456
2457            // Setup the application init args
2458            mAppBindArgs.put("package", ServiceManager.getService("package"));
2459            mAppBindArgs.put("window", ServiceManager.getService("window"));
2460            mAppBindArgs.put(Context.ALARM_SERVICE,
2461                    ServiceManager.getService(Context.ALARM_SERVICE));
2462        }
2463        return mAppBindArgs;
2464    }
2465
2466    final void setFocusedActivityLocked(ActivityRecord r) {
2467        if (mFocusedActivity != r) {
2468            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2469            mFocusedActivity = r;
2470            if (r.task != null && r.task.voiceInteractor != null) {
2471                startRunningVoiceLocked();
2472            } else {
2473                finishRunningVoiceLocked();
2474            }
2475            mStackSupervisor.setFocusedStack(r);
2476            if (r != null) {
2477                mWindowManager.setFocusedApp(r.appToken, true);
2478            }
2479            applyUpdateLockStateLocked(r);
2480        }
2481    }
2482
2483    final void clearFocusedActivity(ActivityRecord r) {
2484        if (mFocusedActivity == r) {
2485            mFocusedActivity = null;
2486        }
2487    }
2488
2489    @Override
2490    public void setFocusedStack(int stackId) {
2491        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2492        synchronized (ActivityManagerService.this) {
2493            ActivityStack stack = mStackSupervisor.getStack(stackId);
2494            if (stack != null) {
2495                ActivityRecord r = stack.topRunningActivityLocked(null);
2496                if (r != null) {
2497                    setFocusedActivityLocked(r);
2498                }
2499            }
2500        }
2501    }
2502
2503    @Override
2504    public void notifyActivityDrawn(IBinder token) {
2505        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2506        synchronized (this) {
2507            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2508            if (r != null) {
2509                r.task.stack.notifyActivityDrawnLocked(r);
2510            }
2511        }
2512    }
2513
2514    final void applyUpdateLockStateLocked(ActivityRecord r) {
2515        // Modifications to the UpdateLock state are done on our handler, outside
2516        // the activity manager's locks.  The new state is determined based on the
2517        // state *now* of the relevant activity record.  The object is passed to
2518        // the handler solely for logging detail, not to be consulted/modified.
2519        final boolean nextState = r != null && r.immersive;
2520        mHandler.sendMessage(
2521                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2522    }
2523
2524    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2525        Message msg = Message.obtain();
2526        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2527        msg.obj = r.task.askedCompatMode ? null : r;
2528        mHandler.sendMessage(msg);
2529    }
2530
2531    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2532            String what, Object obj, ProcessRecord srcApp) {
2533        app.lastActivityTime = now;
2534
2535        if (app.activities.size() > 0) {
2536            // Don't want to touch dependent processes that are hosting activities.
2537            return index;
2538        }
2539
2540        int lrui = mLruProcesses.lastIndexOf(app);
2541        if (lrui < 0) {
2542            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2543                    + what + " " + obj + " from " + srcApp);
2544            return index;
2545        }
2546
2547        if (lrui >= index) {
2548            // Don't want to cause this to move dependent processes *back* in the
2549            // list as if they were less frequently used.
2550            return index;
2551        }
2552
2553        if (lrui >= mLruProcessActivityStart) {
2554            // Don't want to touch dependent processes that are hosting activities.
2555            return index;
2556        }
2557
2558        mLruProcesses.remove(lrui);
2559        if (index > 0) {
2560            index--;
2561        }
2562        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2563                + " in LRU list: " + app);
2564        mLruProcesses.add(index, app);
2565        return index;
2566    }
2567
2568    final void removeLruProcessLocked(ProcessRecord app) {
2569        int lrui = mLruProcesses.lastIndexOf(app);
2570        if (lrui >= 0) {
2571            if (lrui <= mLruProcessActivityStart) {
2572                mLruProcessActivityStart--;
2573            }
2574            if (lrui <= mLruProcessServiceStart) {
2575                mLruProcessServiceStart--;
2576            }
2577            mLruProcesses.remove(lrui);
2578        }
2579    }
2580
2581    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2582            ProcessRecord client) {
2583        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2584                || app.treatLikeActivity;
2585        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2586        if (!activityChange && hasActivity) {
2587            // The process has activities, so we are only allowing activity-based adjustments
2588            // to move it.  It should be kept in the front of the list with other
2589            // processes that have activities, and we don't want those to change their
2590            // order except due to activity operations.
2591            return;
2592        }
2593
2594        mLruSeq++;
2595        final long now = SystemClock.uptimeMillis();
2596        app.lastActivityTime = now;
2597
2598        // First a quick reject: if the app is already at the position we will
2599        // put it, then there is nothing to do.
2600        if (hasActivity) {
2601            final int N = mLruProcesses.size();
2602            if (N > 0 && mLruProcesses.get(N-1) == app) {
2603                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2604                return;
2605            }
2606        } else {
2607            if (mLruProcessServiceStart > 0
2608                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2609                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2610                return;
2611            }
2612        }
2613
2614        int lrui = mLruProcesses.lastIndexOf(app);
2615
2616        if (app.persistent && lrui >= 0) {
2617            // We don't care about the position of persistent processes, as long as
2618            // they are in the list.
2619            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2620            return;
2621        }
2622
2623        /* In progress: compute new position first, so we can avoid doing work
2624           if the process is not actually going to move.  Not yet working.
2625        int addIndex;
2626        int nextIndex;
2627        boolean inActivity = false, inService = false;
2628        if (hasActivity) {
2629            // Process has activities, put it at the very tipsy-top.
2630            addIndex = mLruProcesses.size();
2631            nextIndex = mLruProcessServiceStart;
2632            inActivity = true;
2633        } else if (hasService) {
2634            // Process has services, put it at the top of the service list.
2635            addIndex = mLruProcessActivityStart;
2636            nextIndex = mLruProcessServiceStart;
2637            inActivity = true;
2638            inService = true;
2639        } else  {
2640            // Process not otherwise of interest, it goes to the top of the non-service area.
2641            addIndex = mLruProcessServiceStart;
2642            if (client != null) {
2643                int clientIndex = mLruProcesses.lastIndexOf(client);
2644                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2645                        + app);
2646                if (clientIndex >= 0 && addIndex > clientIndex) {
2647                    addIndex = clientIndex;
2648                }
2649            }
2650            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2651        }
2652
2653        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2654                + mLruProcessActivityStart + "): " + app);
2655        */
2656
2657        if (lrui >= 0) {
2658            if (lrui < mLruProcessActivityStart) {
2659                mLruProcessActivityStart--;
2660            }
2661            if (lrui < mLruProcessServiceStart) {
2662                mLruProcessServiceStart--;
2663            }
2664            /*
2665            if (addIndex > lrui) {
2666                addIndex--;
2667            }
2668            if (nextIndex > lrui) {
2669                nextIndex--;
2670            }
2671            */
2672            mLruProcesses.remove(lrui);
2673        }
2674
2675        /*
2676        mLruProcesses.add(addIndex, app);
2677        if (inActivity) {
2678            mLruProcessActivityStart++;
2679        }
2680        if (inService) {
2681            mLruProcessActivityStart++;
2682        }
2683        */
2684
2685        int nextIndex;
2686        if (hasActivity) {
2687            final int N = mLruProcesses.size();
2688            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2689                // Process doesn't have activities, but has clients with
2690                // activities...  move it up, but one below the top (the top
2691                // should always have a real activity).
2692                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2693                mLruProcesses.add(N-1, app);
2694                // To keep it from spamming the LRU list (by making a bunch of clients),
2695                // we will push down any other entries owned by the app.
2696                final int uid = app.info.uid;
2697                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2698                    ProcessRecord subProc = mLruProcesses.get(i);
2699                    if (subProc.info.uid == uid) {
2700                        // We want to push this one down the list.  If the process after
2701                        // it is for the same uid, however, don't do so, because we don't
2702                        // want them internally to be re-ordered.
2703                        if (mLruProcesses.get(i-1).info.uid != uid) {
2704                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2705                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2706                            ProcessRecord tmp = mLruProcesses.get(i);
2707                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2708                            mLruProcesses.set(i-1, tmp);
2709                            i--;
2710                        }
2711                    } else {
2712                        // A gap, we can stop here.
2713                        break;
2714                    }
2715                }
2716            } else {
2717                // Process has activities, put it at the very tipsy-top.
2718                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2719                mLruProcesses.add(app);
2720            }
2721            nextIndex = mLruProcessServiceStart;
2722        } else if (hasService) {
2723            // Process has services, put it at the top of the service list.
2724            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2725            mLruProcesses.add(mLruProcessActivityStart, app);
2726            nextIndex = mLruProcessServiceStart;
2727            mLruProcessActivityStart++;
2728        } else  {
2729            // Process not otherwise of interest, it goes to the top of the non-service area.
2730            int index = mLruProcessServiceStart;
2731            if (client != null) {
2732                // If there is a client, don't allow the process to be moved up higher
2733                // in the list than that client.
2734                int clientIndex = mLruProcesses.lastIndexOf(client);
2735                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2736                        + " when updating " + app);
2737                if (clientIndex <= lrui) {
2738                    // Don't allow the client index restriction to push it down farther in the
2739                    // list than it already is.
2740                    clientIndex = lrui;
2741                }
2742                if (clientIndex >= 0 && index > clientIndex) {
2743                    index = clientIndex;
2744                }
2745            }
2746            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2747            mLruProcesses.add(index, app);
2748            nextIndex = index-1;
2749            mLruProcessActivityStart++;
2750            mLruProcessServiceStart++;
2751        }
2752
2753        // If the app is currently using a content provider or service,
2754        // bump those processes as well.
2755        for (int j=app.connections.size()-1; j>=0; j--) {
2756            ConnectionRecord cr = app.connections.valueAt(j);
2757            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2758                    && cr.binding.service.app != null
2759                    && cr.binding.service.app.lruSeq != mLruSeq
2760                    && !cr.binding.service.app.persistent) {
2761                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2762                        "service connection", cr, app);
2763            }
2764        }
2765        for (int j=app.conProviders.size()-1; j>=0; j--) {
2766            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2767            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2768                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2769                        "provider reference", cpr, app);
2770            }
2771        }
2772    }
2773
2774    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2775        if (uid == Process.SYSTEM_UID) {
2776            // The system gets to run in any process.  If there are multiple
2777            // processes with the same uid, just pick the first (this
2778            // should never happen).
2779            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2780            if (procs == null) return null;
2781            final int N = procs.size();
2782            for (int i = 0; i < N; i++) {
2783                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2784            }
2785        }
2786        ProcessRecord proc = mProcessNames.get(processName, uid);
2787        if (false && proc != null && !keepIfLarge
2788                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2789                && proc.lastCachedPss >= 4000) {
2790            // Turn this condition on to cause killing to happen regularly, for testing.
2791            if (proc.baseProcessTracker != null) {
2792                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2793            }
2794            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2795                    + "k from cached");
2796        } else if (proc != null && !keepIfLarge
2797                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2798                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2799            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2800            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2801                if (proc.baseProcessTracker != null) {
2802                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2803                }
2804                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2805                        + "k from cached");
2806            }
2807        }
2808        return proc;
2809    }
2810
2811    void ensurePackageDexOpt(String packageName) {
2812        IPackageManager pm = AppGlobals.getPackageManager();
2813        try {
2814            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2815                mDidDexOpt = true;
2816            }
2817        } catch (RemoteException e) {
2818        }
2819    }
2820
2821    boolean isNextTransitionForward() {
2822        int transit = mWindowManager.getPendingAppTransition();
2823        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2824                || transit == AppTransition.TRANSIT_TASK_OPEN
2825                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2826    }
2827
2828    final ProcessRecord startProcessLocked(String processName,
2829            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2830            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2831            boolean isolated, boolean keepIfLarge) {
2832        ProcessRecord app;
2833        if (!isolated) {
2834            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2835        } else {
2836            // If this is an isolated process, it can't re-use an existing process.
2837            app = null;
2838        }
2839        // We don't have to do anything more if:
2840        // (1) There is an existing application record; and
2841        // (2) The caller doesn't think it is dead, OR there is no thread
2842        //     object attached to it so we know it couldn't have crashed; and
2843        // (3) There is a pid assigned to it, so it is either starting or
2844        //     already running.
2845        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2846                + " app=" + app + " knownToBeDead=" + knownToBeDead
2847                + " thread=" + (app != null ? app.thread : null)
2848                + " pid=" + (app != null ? app.pid : -1));
2849        if (app != null && app.pid > 0) {
2850            if (!knownToBeDead || app.thread == null) {
2851                // We already have the app running, or are waiting for it to
2852                // come up (we have a pid but not yet its thread), so keep it.
2853                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2854                // If this is a new package in the process, add the package to the list
2855                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2856                return app;
2857            }
2858
2859            // An application record is attached to a previous process,
2860            // clean it up now.
2861            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2862            Process.killProcessGroup(app.info.uid, app.pid);
2863            handleAppDiedLocked(app, true, true);
2864        }
2865
2866        String hostingNameStr = hostingName != null
2867                ? hostingName.flattenToShortString() : null;
2868
2869        if (!isolated) {
2870            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2871                // If we are in the background, then check to see if this process
2872                // is bad.  If so, we will just silently fail.
2873                if (mBadProcesses.get(info.processName, info.uid) != null) {
2874                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2875                            + "/" + info.processName);
2876                    return null;
2877                }
2878            } else {
2879                // When the user is explicitly starting a process, then clear its
2880                // crash count so that we won't make it bad until they see at
2881                // least one crash dialog again, and make the process good again
2882                // if it had been bad.
2883                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2884                        + "/" + info.processName);
2885                mProcessCrashTimes.remove(info.processName, info.uid);
2886                if (mBadProcesses.get(info.processName, info.uid) != null) {
2887                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2888                            UserHandle.getUserId(info.uid), info.uid,
2889                            info.processName);
2890                    mBadProcesses.remove(info.processName, info.uid);
2891                    if (app != null) {
2892                        app.bad = false;
2893                    }
2894                }
2895            }
2896        }
2897
2898        if (app == null) {
2899            app = newProcessRecordLocked(info, processName, isolated);
2900            if (app == null) {
2901                Slog.w(TAG, "Failed making new process record for "
2902                        + processName + "/" + info.uid + " isolated=" + isolated);
2903                return null;
2904            }
2905            mProcessNames.put(processName, app.uid, app);
2906            if (isolated) {
2907                mIsolatedProcesses.put(app.uid, app);
2908            }
2909        } else {
2910            // If this is a new package in the process, add the package to the list
2911            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2912        }
2913
2914        // If the system is not ready yet, then hold off on starting this
2915        // process until it is.
2916        if (!mProcessesReady
2917                && !isAllowedWhileBooting(info)
2918                && !allowWhileBooting) {
2919            if (!mProcessesOnHold.contains(app)) {
2920                mProcessesOnHold.add(app);
2921            }
2922            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2923            return app;
2924        }
2925
2926        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2927        return (app.pid != 0) ? app : null;
2928    }
2929
2930    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2931        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2932    }
2933
2934    private final void startProcessLocked(ProcessRecord app,
2935            String hostingType, String hostingNameStr, String abiOverride) {
2936        if (app.pid > 0 && app.pid != MY_PID) {
2937            synchronized (mPidsSelfLocked) {
2938                mPidsSelfLocked.remove(app.pid);
2939                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2940            }
2941            app.setPid(0);
2942        }
2943
2944        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2945                "startProcessLocked removing on hold: " + app);
2946        mProcessesOnHold.remove(app);
2947
2948        updateCpuStats();
2949
2950        try {
2951            int uid = app.uid;
2952
2953            int[] gids = null;
2954            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2955            if (!app.isolated) {
2956                int[] permGids = null;
2957                try {
2958                    final PackageManager pm = mContext.getPackageManager();
2959                    permGids = pm.getPackageGids(app.info.packageName);
2960
2961                    if (Environment.isExternalStorageEmulated()) {
2962                        if (pm.checkPermission(
2963                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2964                                app.info.packageName) == PERMISSION_GRANTED) {
2965                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2966                        } else {
2967                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2968                        }
2969                    }
2970                } catch (PackageManager.NameNotFoundException e) {
2971                    Slog.w(TAG, "Unable to retrieve gids", e);
2972                }
2973
2974                /*
2975                 * Add shared application and profile GIDs so applications can share some
2976                 * resources like shared libraries and access user-wide resources
2977                 */
2978                if (permGids == null) {
2979                    gids = new int[2];
2980                } else {
2981                    gids = new int[permGids.length + 2];
2982                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2983                }
2984                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2985                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2986            }
2987            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2988                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2989                        && mTopComponent != null
2990                        && app.processName.equals(mTopComponent.getPackageName())) {
2991                    uid = 0;
2992                }
2993                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2994                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2995                    uid = 0;
2996                }
2997            }
2998            int debugFlags = 0;
2999            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3000                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3001                // Also turn on CheckJNI for debuggable apps. It's quite
3002                // awkward to turn on otherwise.
3003                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3004            }
3005            // Run the app in safe mode if its manifest requests so or the
3006            // system is booted in safe mode.
3007            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3008                mSafeMode == true) {
3009                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3010            }
3011            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3012                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3013            }
3014            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3015                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3016            }
3017            if ("1".equals(SystemProperties.get("debug.assert"))) {
3018                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3019            }
3020
3021            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3022            if (requiredAbi == null) {
3023                requiredAbi = Build.SUPPORTED_ABIS[0];
3024            }
3025
3026            // Start the process.  It will either succeed and return a result containing
3027            // the PID of the new process, or else throw a RuntimeException.
3028            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3029                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3030                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3031
3032            if (app.isolated) {
3033                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3034            }
3035            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3036
3037            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3038                    UserHandle.getUserId(uid), startResult.pid, uid,
3039                    app.processName, hostingType,
3040                    hostingNameStr != null ? hostingNameStr : "");
3041
3042            if (app.persistent) {
3043                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3044            }
3045
3046            StringBuilder buf = mStringBuilder;
3047            buf.setLength(0);
3048            buf.append("Start proc ");
3049            buf.append(app.processName);
3050            buf.append(" for ");
3051            buf.append(hostingType);
3052            if (hostingNameStr != null) {
3053                buf.append(" ");
3054                buf.append(hostingNameStr);
3055            }
3056            buf.append(": pid=");
3057            buf.append(startResult.pid);
3058            buf.append(" uid=");
3059            buf.append(uid);
3060            buf.append(" gids={");
3061            if (gids != null) {
3062                for (int gi=0; gi<gids.length; gi++) {
3063                    if (gi != 0) buf.append(", ");
3064                    buf.append(gids[gi]);
3065
3066                }
3067            }
3068            buf.append("}");
3069            if (requiredAbi != null) {
3070                buf.append(" abi=");
3071                buf.append(requiredAbi);
3072            }
3073            Slog.i(TAG, buf.toString());
3074            app.setPid(startResult.pid);
3075            app.usingWrapper = startResult.usingWrapper;
3076            app.removed = false;
3077            app.killedByAm = false;
3078            synchronized (mPidsSelfLocked) {
3079                this.mPidsSelfLocked.put(startResult.pid, app);
3080                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3081                msg.obj = app;
3082                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3083                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3084            }
3085        } catch (RuntimeException e) {
3086            // XXX do better error recovery.
3087            app.setPid(0);
3088            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3089            if (app.isolated) {
3090                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3091            }
3092            Slog.e(TAG, "Failure starting process " + app.processName, e);
3093        }
3094    }
3095
3096    void updateUsageStats(ActivityRecord component, boolean resumed) {
3097        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3098        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3099        if (resumed) {
3100            if (mUsageStatsService != null) {
3101                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3102                        UsageStats.Event.MOVE_TO_FOREGROUND);
3103            }
3104            synchronized (stats) {
3105                stats.noteActivityResumedLocked(component.app.uid);
3106            }
3107        } else {
3108            if (mUsageStatsService != null) {
3109                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3110                        UsageStats.Event.MOVE_TO_BACKGROUND);
3111            }
3112            synchronized (stats) {
3113                stats.noteActivityPausedLocked(component.app.uid);
3114            }
3115        }
3116    }
3117
3118    Intent getHomeIntent() {
3119        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3120        intent.setComponent(mTopComponent);
3121        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3122            intent.addCategory(Intent.CATEGORY_HOME);
3123        }
3124        return intent;
3125    }
3126
3127    boolean startHomeActivityLocked(int userId) {
3128        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3129                && mTopAction == null) {
3130            // We are running in factory test mode, but unable to find
3131            // the factory test app, so just sit around displaying the
3132            // error message and don't try to start anything.
3133            return false;
3134        }
3135        Intent intent = getHomeIntent();
3136        ActivityInfo aInfo =
3137            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3138        if (aInfo != null) {
3139            intent.setComponent(new ComponentName(
3140                    aInfo.applicationInfo.packageName, aInfo.name));
3141            // Don't do this if the home app is currently being
3142            // instrumented.
3143            aInfo = new ActivityInfo(aInfo);
3144            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3145            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3146                    aInfo.applicationInfo.uid, true);
3147            if (app == null || app.instrumentationClass == null) {
3148                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3149                mStackSupervisor.startHomeActivity(intent, aInfo);
3150            }
3151        }
3152
3153        return true;
3154    }
3155
3156    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3157        ActivityInfo ai = null;
3158        ComponentName comp = intent.getComponent();
3159        try {
3160            if (comp != null) {
3161                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3162            } else {
3163                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3164                        intent,
3165                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3166                            flags, userId);
3167
3168                if (info != null) {
3169                    ai = info.activityInfo;
3170                }
3171            }
3172        } catch (RemoteException e) {
3173            // ignore
3174        }
3175
3176        return ai;
3177    }
3178
3179    /**
3180     * Starts the "new version setup screen" if appropriate.
3181     */
3182    void startSetupActivityLocked() {
3183        // Only do this once per boot.
3184        if (mCheckedForSetup) {
3185            return;
3186        }
3187
3188        // We will show this screen if the current one is a different
3189        // version than the last one shown, and we are not running in
3190        // low-level factory test mode.
3191        final ContentResolver resolver = mContext.getContentResolver();
3192        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3193                Settings.Global.getInt(resolver,
3194                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3195            mCheckedForSetup = true;
3196
3197            // See if we should be showing the platform update setup UI.
3198            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3199            List<ResolveInfo> ris = mContext.getPackageManager()
3200                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3201
3202            // We don't allow third party apps to replace this.
3203            ResolveInfo ri = null;
3204            for (int i=0; ris != null && i<ris.size(); i++) {
3205                if ((ris.get(i).activityInfo.applicationInfo.flags
3206                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3207                    ri = ris.get(i);
3208                    break;
3209                }
3210            }
3211
3212            if (ri != null) {
3213                String vers = ri.activityInfo.metaData != null
3214                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3215                        : null;
3216                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3217                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3218                            Intent.METADATA_SETUP_VERSION);
3219                }
3220                String lastVers = Settings.Secure.getString(
3221                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3222                if (vers != null && !vers.equals(lastVers)) {
3223                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3224                    intent.setComponent(new ComponentName(
3225                            ri.activityInfo.packageName, ri.activityInfo.name));
3226                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3227                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3228                }
3229            }
3230        }
3231    }
3232
3233    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3234        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3235    }
3236
3237    void enforceNotIsolatedCaller(String caller) {
3238        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3239            throw new SecurityException("Isolated process not allowed to call " + caller);
3240        }
3241    }
3242
3243    @Override
3244    public int getFrontActivityScreenCompatMode() {
3245        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3246        synchronized (this) {
3247            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3248        }
3249    }
3250
3251    @Override
3252    public void setFrontActivityScreenCompatMode(int mode) {
3253        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3254                "setFrontActivityScreenCompatMode");
3255        synchronized (this) {
3256            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3257        }
3258    }
3259
3260    @Override
3261    public int getPackageScreenCompatMode(String packageName) {
3262        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3263        synchronized (this) {
3264            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3265        }
3266    }
3267
3268    @Override
3269    public void setPackageScreenCompatMode(String packageName, int mode) {
3270        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3271                "setPackageScreenCompatMode");
3272        synchronized (this) {
3273            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3274        }
3275    }
3276
3277    @Override
3278    public boolean getPackageAskScreenCompat(String packageName) {
3279        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3280        synchronized (this) {
3281            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3282        }
3283    }
3284
3285    @Override
3286    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3287        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3288                "setPackageAskScreenCompat");
3289        synchronized (this) {
3290            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3291        }
3292    }
3293
3294    private void dispatchProcessesChanged() {
3295        int N;
3296        synchronized (this) {
3297            N = mPendingProcessChanges.size();
3298            if (mActiveProcessChanges.length < N) {
3299                mActiveProcessChanges = new ProcessChangeItem[N];
3300            }
3301            mPendingProcessChanges.toArray(mActiveProcessChanges);
3302            mAvailProcessChanges.addAll(mPendingProcessChanges);
3303            mPendingProcessChanges.clear();
3304            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3305        }
3306
3307        int i = mProcessObservers.beginBroadcast();
3308        while (i > 0) {
3309            i--;
3310            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3311            if (observer != null) {
3312                try {
3313                    for (int j=0; j<N; j++) {
3314                        ProcessChangeItem item = mActiveProcessChanges[j];
3315                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3316                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3317                                    + item.pid + " uid=" + item.uid + ": "
3318                                    + item.foregroundActivities);
3319                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3320                                    item.foregroundActivities);
3321                        }
3322                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3325                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3326                        }
3327                    }
3328                } catch (RemoteException e) {
3329                }
3330            }
3331        }
3332        mProcessObservers.finishBroadcast();
3333    }
3334
3335    private void dispatchProcessDied(int pid, int uid) {
3336        int i = mProcessObservers.beginBroadcast();
3337        while (i > 0) {
3338            i--;
3339            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3340            if (observer != null) {
3341                try {
3342                    observer.onProcessDied(pid, uid);
3343                } catch (RemoteException e) {
3344                }
3345            }
3346        }
3347        mProcessObservers.finishBroadcast();
3348    }
3349
3350    @Override
3351    public final int startActivity(IApplicationThread caller, String callingPackage,
3352            Intent intent, String resolvedType, IBinder resultTo,
3353            String resultWho, int requestCode, int startFlags,
3354            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3355        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3356                resultWho, requestCode,
3357                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3358    }
3359
3360    @Override
3361    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3362            Intent intent, String resolvedType, IBinder resultTo,
3363            String resultWho, int requestCode, int startFlags,
3364            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3365        enforceNotIsolatedCaller("startActivity");
3366        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3367                false, ALLOW_FULL_ONLY, "startActivity", null);
3368        // TODO: Switch to user app stacks here.
3369        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3370                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3371                null, null, options, userId, null);
3372    }
3373
3374    @Override
3375    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3376            Intent intent, String resolvedType, IBinder resultTo,
3377            String resultWho, int requestCode, int startFlags, String profileFile,
3378            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3379        enforceNotIsolatedCaller("startActivityAndWait");
3380        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3381                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3382        WaitResult res = new WaitResult();
3383        // TODO: Switch to user app stacks here.
3384        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3385                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3386                res, null, options, userId, null);
3387        return res;
3388    }
3389
3390    @Override
3391    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3392            Intent intent, String resolvedType, IBinder resultTo,
3393            String resultWho, int requestCode, int startFlags, Configuration config,
3394            Bundle options, int userId) {
3395        enforceNotIsolatedCaller("startActivityWithConfig");
3396        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3397                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3398        // TODO: Switch to user app stacks here.
3399        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3400                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3401                null, null, null, config, options, userId, null);
3402        return ret;
3403    }
3404
3405    @Override
3406    public int startActivityIntentSender(IApplicationThread caller,
3407            IntentSender intent, Intent fillInIntent, String resolvedType,
3408            IBinder resultTo, String resultWho, int requestCode,
3409            int flagsMask, int flagsValues, Bundle options) {
3410        enforceNotIsolatedCaller("startActivityIntentSender");
3411        // Refuse possible leaked file descriptors
3412        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3413            throw new IllegalArgumentException("File descriptors passed in Intent");
3414        }
3415
3416        IIntentSender sender = intent.getTarget();
3417        if (!(sender instanceof PendingIntentRecord)) {
3418            throw new IllegalArgumentException("Bad PendingIntent object");
3419        }
3420
3421        PendingIntentRecord pir = (PendingIntentRecord)sender;
3422
3423        synchronized (this) {
3424            // If this is coming from the currently resumed activity, it is
3425            // effectively saying that app switches are allowed at this point.
3426            final ActivityStack stack = getFocusedStack();
3427            if (stack.mResumedActivity != null &&
3428                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3429                mAppSwitchesAllowedTime = 0;
3430            }
3431        }
3432        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3433                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3434        return ret;
3435    }
3436
3437    @Override
3438    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3439            Intent intent, String resolvedType, IVoiceInteractionSession session,
3440            IVoiceInteractor interactor, int startFlags, String profileFile,
3441            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3442        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3443                != PackageManager.PERMISSION_GRANTED) {
3444            String msg = "Permission Denial: startVoiceActivity() from pid="
3445                    + Binder.getCallingPid()
3446                    + ", uid=" + Binder.getCallingUid()
3447                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3448            Slog.w(TAG, msg);
3449            throw new SecurityException(msg);
3450        }
3451        if (session == null || interactor == null) {
3452            throw new NullPointerException("null session or interactor");
3453        }
3454        userId = handleIncomingUser(callingPid, callingUid, userId,
3455                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3456        // TODO: Switch to user app stacks here.
3457        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3458                resolvedType, session, interactor, null, null, 0, startFlags,
3459                profileFile, profileFd, null, null, options, userId, null);
3460    }
3461
3462    @Override
3463    public boolean startNextMatchingActivity(IBinder callingActivity,
3464            Intent intent, Bundle options) {
3465        // Refuse possible leaked file descriptors
3466        if (intent != null && intent.hasFileDescriptors() == true) {
3467            throw new IllegalArgumentException("File descriptors passed in Intent");
3468        }
3469
3470        synchronized (this) {
3471            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3472            if (r == null) {
3473                ActivityOptions.abort(options);
3474                return false;
3475            }
3476            if (r.app == null || r.app.thread == null) {
3477                // The caller is not running...  d'oh!
3478                ActivityOptions.abort(options);
3479                return false;
3480            }
3481            intent = new Intent(intent);
3482            // The caller is not allowed to change the data.
3483            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3484            // And we are resetting to find the next component...
3485            intent.setComponent(null);
3486
3487            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3488
3489            ActivityInfo aInfo = null;
3490            try {
3491                List<ResolveInfo> resolves =
3492                    AppGlobals.getPackageManager().queryIntentActivities(
3493                            intent, r.resolvedType,
3494                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3495                            UserHandle.getCallingUserId());
3496
3497                // Look for the original activity in the list...
3498                final int N = resolves != null ? resolves.size() : 0;
3499                for (int i=0; i<N; i++) {
3500                    ResolveInfo rInfo = resolves.get(i);
3501                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3502                            && rInfo.activityInfo.name.equals(r.info.name)) {
3503                        // We found the current one...  the next matching is
3504                        // after it.
3505                        i++;
3506                        if (i<N) {
3507                            aInfo = resolves.get(i).activityInfo;
3508                        }
3509                        if (debug) {
3510                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3511                                    + "/" + r.info.name);
3512                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3513                                    + "/" + aInfo.name);
3514                        }
3515                        break;
3516                    }
3517                }
3518            } catch (RemoteException e) {
3519            }
3520
3521            if (aInfo == null) {
3522                // Nobody who is next!
3523                ActivityOptions.abort(options);
3524                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3525                return false;
3526            }
3527
3528            intent.setComponent(new ComponentName(
3529                    aInfo.applicationInfo.packageName, aInfo.name));
3530            intent.setFlags(intent.getFlags()&~(
3531                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3532                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3533                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3534                    Intent.FLAG_ACTIVITY_NEW_TASK));
3535
3536            // Okay now we need to start the new activity, replacing the
3537            // currently running activity.  This is a little tricky because
3538            // we want to start the new one as if the current one is finished,
3539            // but not finish the current one first so that there is no flicker.
3540            // And thus...
3541            final boolean wasFinishing = r.finishing;
3542            r.finishing = true;
3543
3544            // Propagate reply information over to the new activity.
3545            final ActivityRecord resultTo = r.resultTo;
3546            final String resultWho = r.resultWho;
3547            final int requestCode = r.requestCode;
3548            r.resultTo = null;
3549            if (resultTo != null) {
3550                resultTo.removeResultsLocked(r, resultWho, requestCode);
3551            }
3552
3553            final long origId = Binder.clearCallingIdentity();
3554            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3555                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3556                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3557                    options, false, null, null);
3558            Binder.restoreCallingIdentity(origId);
3559
3560            r.finishing = wasFinishing;
3561            if (res != ActivityManager.START_SUCCESS) {
3562                return false;
3563            }
3564            return true;
3565        }
3566    }
3567
3568    @Override
3569    public final int startActivityFromRecents(int taskId, Bundle options) {
3570        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3571            String msg = "Permission Denial: startActivityFromRecents called without " +
3572                    START_TASKS_FROM_RECENTS;
3573            Slog.w(TAG, msg);
3574            throw new SecurityException(msg);
3575        }
3576        final int callingUid;
3577        final String callingPackage;
3578        final Intent intent;
3579        final int userId;
3580        synchronized (this) {
3581            final TaskRecord task = recentTaskForIdLocked(taskId);
3582            if (task == null) {
3583                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3584            }
3585            callingUid = task.mCallingUid;
3586            callingPackage = task.mCallingPackage;
3587            intent = task.intent;
3588            userId = task.userId;
3589        }
3590        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3591                options, userId, null);
3592    }
3593
3594    final int startActivityInPackage(int uid, String callingPackage,
3595            Intent intent, String resolvedType, IBinder resultTo,
3596            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3597                    IActivityContainer container) {
3598
3599        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3600                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3601
3602        // TODO: Switch to user app stacks here.
3603        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3604                null, null, resultTo, resultWho, requestCode, startFlags,
3605                null, null, null, null, options, userId, container);
3606        return ret;
3607    }
3608
3609    @Override
3610    public final int startActivities(IApplicationThread caller, String callingPackage,
3611            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3612            int userId) {
3613        enforceNotIsolatedCaller("startActivities");
3614        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3615                false, ALLOW_FULL_ONLY, "startActivity", null);
3616        // TODO: Switch to user app stacks here.
3617        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3618                resolvedTypes, resultTo, options, userId);
3619        return ret;
3620    }
3621
3622    final int startActivitiesInPackage(int uid, String callingPackage,
3623            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3624            Bundle options, int userId) {
3625
3626        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3627                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3628        // TODO: Switch to user app stacks here.
3629        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3630                resultTo, options, userId);
3631        return ret;
3632    }
3633
3634    final void addRecentTaskLocked(TaskRecord task) {
3635        int N = mRecentTasks.size();
3636        // Quick case: check if the top-most recent task is the same.
3637        if (N > 0 && mRecentTasks.get(0) == task) {
3638            return;
3639        }
3640        // Another quick case: never add voice sessions.
3641        if (task.voiceSession != null) {
3642            return;
3643        }
3644        // Remove any existing entries that are the same kind of task.
3645        final Intent intent = task.intent;
3646        final boolean document = intent != null && intent.isDocument();
3647        final ComponentName comp = intent.getComponent();
3648
3649        int maxRecents = task.maxRecents - 1;
3650        for (int i=0; i<N; i++) {
3651            final TaskRecord tr = mRecentTasks.get(i);
3652            if (task != tr) {
3653                if (task.userId != tr.userId) {
3654                    continue;
3655                }
3656                if (i > MAX_RECENT_BITMAPS) {
3657                    tr.freeLastThumbnail();
3658                }
3659                final Intent trIntent = tr.intent;
3660                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3661                    (intent == null || !intent.filterEquals(trIntent))) {
3662                    continue;
3663                }
3664                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3665                if (document && trIsDocument) {
3666                    // These are the same document activity (not necessarily the same doc).
3667                    if (maxRecents > 0) {
3668                        --maxRecents;
3669                        continue;
3670                    }
3671                    // Hit the maximum number of documents for this task. Fall through
3672                    // and remove this document from recents.
3673                } else if (document || trIsDocument) {
3674                    // Only one of these is a document. Not the droid we're looking for.
3675                    continue;
3676                }
3677            }
3678
3679            // Either task and tr are the same or, their affinities match or their intents match
3680            // and neither of them is a document, or they are documents using the same activity
3681            // and their maxRecents has been reached.
3682            tr.disposeThumbnail();
3683            mRecentTasks.remove(i);
3684            if (task != tr) {
3685                tr.closeRecentsChain();
3686            }
3687            i--;
3688            N--;
3689            if (task.intent == null) {
3690                // If the new recent task we are adding is not fully
3691                // specified, then replace it with the existing recent task.
3692                task = tr;
3693            }
3694            mTaskPersister.notify(tr, false);
3695        }
3696        if (N >= MAX_RECENT_TASKS) {
3697            final TaskRecord tr = mRecentTasks.remove(N - 1);
3698            tr.disposeThumbnail();
3699            tr.closeRecentsChain();
3700        }
3701        mRecentTasks.add(0, task);
3702    }
3703
3704    @Override
3705    public void reportActivityFullyDrawn(IBinder token) {
3706        synchronized (this) {
3707            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3708            if (r == null) {
3709                return;
3710            }
3711            r.reportFullyDrawnLocked();
3712        }
3713    }
3714
3715    @Override
3716    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3717        synchronized (this) {
3718            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3719            if (r == null) {
3720                return;
3721            }
3722            final long origId = Binder.clearCallingIdentity();
3723            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3724            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3725                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3726            if (config != null) {
3727                r.frozenBeforeDestroy = true;
3728                if (!updateConfigurationLocked(config, r, false, false)) {
3729                    mStackSupervisor.resumeTopActivitiesLocked();
3730                }
3731            }
3732            Binder.restoreCallingIdentity(origId);
3733        }
3734    }
3735
3736    @Override
3737    public int getRequestedOrientation(IBinder token) {
3738        synchronized (this) {
3739            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3740            if (r == null) {
3741                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3742            }
3743            return mWindowManager.getAppOrientation(r.appToken);
3744        }
3745    }
3746
3747    /**
3748     * This is the internal entry point for handling Activity.finish().
3749     *
3750     * @param token The Binder token referencing the Activity we want to finish.
3751     * @param resultCode Result code, if any, from this Activity.
3752     * @param resultData Result data (Intent), if any, from this Activity.
3753     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3754     *            the root Activity in the task.
3755     *
3756     * @return Returns true if the activity successfully finished, or false if it is still running.
3757     */
3758    @Override
3759    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3760            boolean finishTask) {
3761        // Refuse possible leaked file descriptors
3762        if (resultData != null && resultData.hasFileDescriptors() == true) {
3763            throw new IllegalArgumentException("File descriptors passed in Intent");
3764        }
3765
3766        synchronized(this) {
3767            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3768            if (r == null) {
3769                return true;
3770            }
3771            // Keep track of the root activity of the task before we finish it
3772            TaskRecord tr = r.task;
3773            ActivityRecord rootR = tr.getRootActivity();
3774            // Do not allow task to finish in Lock Task mode.
3775            if (tr == mStackSupervisor.mLockTaskModeTask) {
3776                if (rootR == r) {
3777                    mStackSupervisor.showLockTaskToast();
3778                    return false;
3779                }
3780            }
3781            if (mController != null) {
3782                // Find the first activity that is not finishing.
3783                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3784                if (next != null) {
3785                    // ask watcher if this is allowed
3786                    boolean resumeOK = true;
3787                    try {
3788                        resumeOK = mController.activityResuming(next.packageName);
3789                    } catch (RemoteException e) {
3790                        mController = null;
3791                        Watchdog.getInstance().setActivityController(null);
3792                    }
3793
3794                    if (!resumeOK) {
3795                        return false;
3796                    }
3797                }
3798            }
3799            final long origId = Binder.clearCallingIdentity();
3800            try {
3801                boolean res;
3802                if (finishTask && r == rootR) {
3803                    // If requested, remove the task that is associated to this activity only if it
3804                    // was the root activity in the task.  The result code and data is ignored because
3805                    // we don't support returning them across task boundaries.
3806                    res = removeTaskByIdLocked(tr.taskId, 0);
3807                } else {
3808                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3809                            resultData, "app-request", true);
3810                }
3811                return res;
3812            } finally {
3813                Binder.restoreCallingIdentity(origId);
3814            }
3815        }
3816    }
3817
3818    @Override
3819    public final void finishHeavyWeightApp() {
3820        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3821                != PackageManager.PERMISSION_GRANTED) {
3822            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3823                    + Binder.getCallingPid()
3824                    + ", uid=" + Binder.getCallingUid()
3825                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3826            Slog.w(TAG, msg);
3827            throw new SecurityException(msg);
3828        }
3829
3830        synchronized(this) {
3831            if (mHeavyWeightProcess == null) {
3832                return;
3833            }
3834
3835            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3836                    mHeavyWeightProcess.activities);
3837            for (int i=0; i<activities.size(); i++) {
3838                ActivityRecord r = activities.get(i);
3839                if (!r.finishing) {
3840                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3841                            null, "finish-heavy", true);
3842                }
3843            }
3844
3845            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3846                    mHeavyWeightProcess.userId, 0));
3847            mHeavyWeightProcess = null;
3848        }
3849    }
3850
3851    @Override
3852    public void crashApplication(int uid, int initialPid, String packageName,
3853            String message) {
3854        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3855                != PackageManager.PERMISSION_GRANTED) {
3856            String msg = "Permission Denial: crashApplication() from pid="
3857                    + Binder.getCallingPid()
3858                    + ", uid=" + Binder.getCallingUid()
3859                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3860            Slog.w(TAG, msg);
3861            throw new SecurityException(msg);
3862        }
3863
3864        synchronized(this) {
3865            ProcessRecord proc = null;
3866
3867            // Figure out which process to kill.  We don't trust that initialPid
3868            // still has any relation to current pids, so must scan through the
3869            // list.
3870            synchronized (mPidsSelfLocked) {
3871                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3872                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3873                    if (p.uid != uid) {
3874                        continue;
3875                    }
3876                    if (p.pid == initialPid) {
3877                        proc = p;
3878                        break;
3879                    }
3880                    if (p.pkgList.containsKey(packageName)) {
3881                        proc = p;
3882                    }
3883                }
3884            }
3885
3886            if (proc == null) {
3887                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3888                        + " initialPid=" + initialPid
3889                        + " packageName=" + packageName);
3890                return;
3891            }
3892
3893            if (proc.thread != null) {
3894                if (proc.pid == Process.myPid()) {
3895                    Log.w(TAG, "crashApplication: trying to crash self!");
3896                    return;
3897                }
3898                long ident = Binder.clearCallingIdentity();
3899                try {
3900                    proc.thread.scheduleCrash(message);
3901                } catch (RemoteException e) {
3902                }
3903                Binder.restoreCallingIdentity(ident);
3904            }
3905        }
3906    }
3907
3908    @Override
3909    public final void finishSubActivity(IBinder token, String resultWho,
3910            int requestCode) {
3911        synchronized(this) {
3912            final long origId = Binder.clearCallingIdentity();
3913            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3914            if (r != null) {
3915                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3916            }
3917            Binder.restoreCallingIdentity(origId);
3918        }
3919    }
3920
3921    @Override
3922    public boolean finishActivityAffinity(IBinder token) {
3923        synchronized(this) {
3924            final long origId = Binder.clearCallingIdentity();
3925            try {
3926                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3927
3928                ActivityRecord rootR = r.task.getRootActivity();
3929                // Do not allow task to finish in Lock Task mode.
3930                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3931                    if (rootR == r) {
3932                        mStackSupervisor.showLockTaskToast();
3933                        return false;
3934                    }
3935                }
3936                boolean res = false;
3937                if (r != null) {
3938                    res = r.task.stack.finishActivityAffinityLocked(r);
3939                }
3940                return res;
3941            } finally {
3942                Binder.restoreCallingIdentity(origId);
3943            }
3944        }
3945    }
3946
3947    @Override
3948    public void finishVoiceTask(IVoiceInteractionSession session) {
3949        synchronized(this) {
3950            final long origId = Binder.clearCallingIdentity();
3951            try {
3952                mStackSupervisor.finishVoiceTask(session);
3953            } finally {
3954                Binder.restoreCallingIdentity(origId);
3955            }
3956        }
3957
3958    }
3959
3960    @Override
3961    public boolean willActivityBeVisible(IBinder token) {
3962        synchronized(this) {
3963            ActivityStack stack = ActivityRecord.getStackLocked(token);
3964            if (stack != null) {
3965                return stack.willActivityBeVisibleLocked(token);
3966            }
3967            return false;
3968        }
3969    }
3970
3971    @Override
3972    public void overridePendingTransition(IBinder token, String packageName,
3973            int enterAnim, int exitAnim) {
3974        synchronized(this) {
3975            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3976            if (self == null) {
3977                return;
3978            }
3979
3980            final long origId = Binder.clearCallingIdentity();
3981
3982            if (self.state == ActivityState.RESUMED
3983                    || self.state == ActivityState.PAUSING) {
3984                mWindowManager.overridePendingAppTransition(packageName,
3985                        enterAnim, exitAnim, null);
3986            }
3987
3988            Binder.restoreCallingIdentity(origId);
3989        }
3990    }
3991
3992    /**
3993     * Main function for removing an existing process from the activity manager
3994     * as a result of that process going away.  Clears out all connections
3995     * to the process.
3996     */
3997    private final void handleAppDiedLocked(ProcessRecord app,
3998            boolean restarting, boolean allowRestart) {
3999        int pid = app.pid;
4000        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4001        if (!restarting) {
4002            removeLruProcessLocked(app);
4003            if (pid > 0) {
4004                ProcessList.remove(pid);
4005            }
4006        }
4007
4008        if (mProfileProc == app) {
4009            clearProfilerLocked();
4010        }
4011
4012        // Remove this application's activities from active lists.
4013        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4014
4015        app.activities.clear();
4016
4017        if (app.instrumentationClass != null) {
4018            Slog.w(TAG, "Crash of app " + app.processName
4019                  + " running instrumentation " + app.instrumentationClass);
4020            Bundle info = new Bundle();
4021            info.putString("shortMsg", "Process crashed.");
4022            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4023        }
4024
4025        if (!restarting) {
4026            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4027                // If there was nothing to resume, and we are not already
4028                // restarting this process, but there is a visible activity that
4029                // is hosted by the process...  then make sure all visible
4030                // activities are running, taking care of restarting this
4031                // process.
4032                if (hasVisibleActivities) {
4033                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4034                }
4035            }
4036        }
4037    }
4038
4039    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4040        IBinder threadBinder = thread.asBinder();
4041        // Find the application record.
4042        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4043            ProcessRecord rec = mLruProcesses.get(i);
4044            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4045                return i;
4046            }
4047        }
4048        return -1;
4049    }
4050
4051    final ProcessRecord getRecordForAppLocked(
4052            IApplicationThread thread) {
4053        if (thread == null) {
4054            return null;
4055        }
4056
4057        int appIndex = getLRURecordIndexForAppLocked(thread);
4058        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4059    }
4060
4061    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4062        // If there are no longer any background processes running,
4063        // and the app that died was not running instrumentation,
4064        // then tell everyone we are now low on memory.
4065        boolean haveBg = false;
4066        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4067            ProcessRecord rec = mLruProcesses.get(i);
4068            if (rec.thread != null
4069                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4070                haveBg = true;
4071                break;
4072            }
4073        }
4074
4075        if (!haveBg) {
4076            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4077            if (doReport) {
4078                long now = SystemClock.uptimeMillis();
4079                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4080                    doReport = false;
4081                } else {
4082                    mLastMemUsageReportTime = now;
4083                }
4084            }
4085            final ArrayList<ProcessMemInfo> memInfos
4086                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4087            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4088            long now = SystemClock.uptimeMillis();
4089            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4090                ProcessRecord rec = mLruProcesses.get(i);
4091                if (rec == dyingProc || rec.thread == null) {
4092                    continue;
4093                }
4094                if (doReport) {
4095                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4096                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4097                }
4098                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4099                    // The low memory report is overriding any current
4100                    // state for a GC request.  Make sure to do
4101                    // heavy/important/visible/foreground processes first.
4102                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4103                        rec.lastRequestedGc = 0;
4104                    } else {
4105                        rec.lastRequestedGc = rec.lastLowMemory;
4106                    }
4107                    rec.reportLowMemory = true;
4108                    rec.lastLowMemory = now;
4109                    mProcessesToGc.remove(rec);
4110                    addProcessToGcListLocked(rec);
4111                }
4112            }
4113            if (doReport) {
4114                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4115                mHandler.sendMessage(msg);
4116            }
4117            scheduleAppGcsLocked();
4118        }
4119    }
4120
4121    final void appDiedLocked(ProcessRecord app, int pid,
4122            IApplicationThread thread) {
4123
4124        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4125        synchronized (stats) {
4126            stats.noteProcessDiedLocked(app.info.uid, pid);
4127        }
4128
4129        Process.killProcessGroup(app.info.uid, pid);
4130
4131        // Clean up already done if the process has been re-started.
4132        if (app.pid == pid && app.thread != null &&
4133                app.thread.asBinder() == thread.asBinder()) {
4134            boolean doLowMem = app.instrumentationClass == null;
4135            boolean doOomAdj = doLowMem;
4136            if (!app.killedByAm) {
4137                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4138                        + ") has died.");
4139                mAllowLowerMemLevel = true;
4140            } else {
4141                // Note that we always want to do oom adj to update our state with the
4142                // new number of procs.
4143                mAllowLowerMemLevel = false;
4144                doLowMem = false;
4145            }
4146            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4147            if (DEBUG_CLEANUP) Slog.v(
4148                TAG, "Dying app: " + app + ", pid: " + pid
4149                + ", thread: " + thread.asBinder());
4150            handleAppDiedLocked(app, false, true);
4151
4152            if (doOomAdj) {
4153                updateOomAdjLocked();
4154            }
4155            if (doLowMem) {
4156                doLowMemReportIfNeededLocked(app);
4157            }
4158        } else if (app.pid != pid) {
4159            // A new process has already been started.
4160            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4161                    + ") has died and restarted (pid " + app.pid + ").");
4162            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4163        } else if (DEBUG_PROCESSES) {
4164            Slog.d(TAG, "Received spurious death notification for thread "
4165                    + thread.asBinder());
4166        }
4167    }
4168
4169    /**
4170     * If a stack trace dump file is configured, dump process stack traces.
4171     * @param clearTraces causes the dump file to be erased prior to the new
4172     *    traces being written, if true; when false, the new traces will be
4173     *    appended to any existing file content.
4174     * @param firstPids of dalvik VM processes to dump stack traces for first
4175     * @param lastPids of dalvik VM processes to dump stack traces for last
4176     * @param nativeProcs optional list of native process names to dump stack crawls
4177     * @return file containing stack traces, or null if no dump file is configured
4178     */
4179    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4180            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4181        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4182        if (tracesPath == null || tracesPath.length() == 0) {
4183            return null;
4184        }
4185
4186        File tracesFile = new File(tracesPath);
4187        try {
4188            File tracesDir = tracesFile.getParentFile();
4189            if (!tracesDir.exists()) {
4190                tracesFile.mkdirs();
4191                if (!SELinux.restorecon(tracesDir)) {
4192                    return null;
4193                }
4194            }
4195            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4196
4197            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4198            tracesFile.createNewFile();
4199            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4200        } catch (IOException e) {
4201            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4202            return null;
4203        }
4204
4205        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4206        return tracesFile;
4207    }
4208
4209    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4210            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4211        // Use a FileObserver to detect when traces finish writing.
4212        // The order of traces is considered important to maintain for legibility.
4213        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4214            @Override
4215            public synchronized void onEvent(int event, String path) { notify(); }
4216        };
4217
4218        try {
4219            observer.startWatching();
4220
4221            // First collect all of the stacks of the most important pids.
4222            if (firstPids != null) {
4223                try {
4224                    int num = firstPids.size();
4225                    for (int i = 0; i < num; i++) {
4226                        synchronized (observer) {
4227                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4228                            observer.wait(200);  // Wait for write-close, give up after 200msec
4229                        }
4230                    }
4231                } catch (InterruptedException e) {
4232                    Log.wtf(TAG, e);
4233                }
4234            }
4235
4236            // Next collect the stacks of the native pids
4237            if (nativeProcs != null) {
4238                int[] pids = Process.getPidsForCommands(nativeProcs);
4239                if (pids != null) {
4240                    for (int pid : pids) {
4241                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4242                    }
4243                }
4244            }
4245
4246            // Lastly, measure CPU usage.
4247            if (processCpuTracker != null) {
4248                processCpuTracker.init();
4249                System.gc();
4250                processCpuTracker.update();
4251                try {
4252                    synchronized (processCpuTracker) {
4253                        processCpuTracker.wait(500); // measure over 1/2 second.
4254                    }
4255                } catch (InterruptedException e) {
4256                }
4257                processCpuTracker.update();
4258
4259                // We'll take the stack crawls of just the top apps using CPU.
4260                final int N = processCpuTracker.countWorkingStats();
4261                int numProcs = 0;
4262                for (int i=0; i<N && numProcs<5; i++) {
4263                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4264                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4265                        numProcs++;
4266                        try {
4267                            synchronized (observer) {
4268                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4269                                observer.wait(200);  // Wait for write-close, give up after 200msec
4270                            }
4271                        } catch (InterruptedException e) {
4272                            Log.wtf(TAG, e);
4273                        }
4274
4275                    }
4276                }
4277            }
4278        } finally {
4279            observer.stopWatching();
4280        }
4281    }
4282
4283    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4284        if (true || IS_USER_BUILD) {
4285            return;
4286        }
4287        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4288        if (tracesPath == null || tracesPath.length() == 0) {
4289            return;
4290        }
4291
4292        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4293        StrictMode.allowThreadDiskWrites();
4294        try {
4295            final File tracesFile = new File(tracesPath);
4296            final File tracesDir = tracesFile.getParentFile();
4297            final File tracesTmp = new File(tracesDir, "__tmp__");
4298            try {
4299                if (!tracesDir.exists()) {
4300                    tracesFile.mkdirs();
4301                    if (!SELinux.restorecon(tracesDir.getPath())) {
4302                        return;
4303                    }
4304                }
4305                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4306
4307                if (tracesFile.exists()) {
4308                    tracesTmp.delete();
4309                    tracesFile.renameTo(tracesTmp);
4310                }
4311                StringBuilder sb = new StringBuilder();
4312                Time tobj = new Time();
4313                tobj.set(System.currentTimeMillis());
4314                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4315                sb.append(": ");
4316                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4317                sb.append(" since ");
4318                sb.append(msg);
4319                FileOutputStream fos = new FileOutputStream(tracesFile);
4320                fos.write(sb.toString().getBytes());
4321                if (app == null) {
4322                    fos.write("\n*** No application process!".getBytes());
4323                }
4324                fos.close();
4325                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4326            } catch (IOException e) {
4327                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4328                return;
4329            }
4330
4331            if (app != null) {
4332                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4333                firstPids.add(app.pid);
4334                dumpStackTraces(tracesPath, firstPids, null, null, null);
4335            }
4336
4337            File lastTracesFile = null;
4338            File curTracesFile = null;
4339            for (int i=9; i>=0; i--) {
4340                String name = String.format(Locale.US, "slow%02d.txt", i);
4341                curTracesFile = new File(tracesDir, name);
4342                if (curTracesFile.exists()) {
4343                    if (lastTracesFile != null) {
4344                        curTracesFile.renameTo(lastTracesFile);
4345                    } else {
4346                        curTracesFile.delete();
4347                    }
4348                }
4349                lastTracesFile = curTracesFile;
4350            }
4351            tracesFile.renameTo(curTracesFile);
4352            if (tracesTmp.exists()) {
4353                tracesTmp.renameTo(tracesFile);
4354            }
4355        } finally {
4356            StrictMode.setThreadPolicy(oldPolicy);
4357        }
4358    }
4359
4360    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4361            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4362        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4363        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4364
4365        if (mController != null) {
4366            try {
4367                // 0 == continue, -1 = kill process immediately
4368                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4369                if (res < 0 && app.pid != MY_PID) {
4370                    Process.killProcess(app.pid);
4371                    Process.killProcessGroup(app.info.uid, app.pid);
4372                }
4373            } catch (RemoteException e) {
4374                mController = null;
4375                Watchdog.getInstance().setActivityController(null);
4376            }
4377        }
4378
4379        long anrTime = SystemClock.uptimeMillis();
4380        if (MONITOR_CPU_USAGE) {
4381            updateCpuStatsNow();
4382        }
4383
4384        synchronized (this) {
4385            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4386            if (mShuttingDown) {
4387                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4388                return;
4389            } else if (app.notResponding) {
4390                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4391                return;
4392            } else if (app.crashing) {
4393                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4394                return;
4395            }
4396
4397            // In case we come through here for the same app before completing
4398            // this one, mark as anring now so we will bail out.
4399            app.notResponding = true;
4400
4401            // Log the ANR to the event log.
4402            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4403                    app.processName, app.info.flags, annotation);
4404
4405            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4406            firstPids.add(app.pid);
4407
4408            int parentPid = app.pid;
4409            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4410            if (parentPid != app.pid) firstPids.add(parentPid);
4411
4412            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4413
4414            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4415                ProcessRecord r = mLruProcesses.get(i);
4416                if (r != null && r.thread != null) {
4417                    int pid = r.pid;
4418                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4419                        if (r.persistent) {
4420                            firstPids.add(pid);
4421                        } else {
4422                            lastPids.put(pid, Boolean.TRUE);
4423                        }
4424                    }
4425                }
4426            }
4427        }
4428
4429        // Log the ANR to the main log.
4430        StringBuilder info = new StringBuilder();
4431        info.setLength(0);
4432        info.append("ANR in ").append(app.processName);
4433        if (activity != null && activity.shortComponentName != null) {
4434            info.append(" (").append(activity.shortComponentName).append(")");
4435        }
4436        info.append("\n");
4437        info.append("PID: ").append(app.pid).append("\n");
4438        if (annotation != null) {
4439            info.append("Reason: ").append(annotation).append("\n");
4440        }
4441        if (parent != null && parent != activity) {
4442            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4443        }
4444
4445        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4446
4447        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4448                NATIVE_STACKS_OF_INTEREST);
4449
4450        String cpuInfo = null;
4451        if (MONITOR_CPU_USAGE) {
4452            updateCpuStatsNow();
4453            synchronized (mProcessCpuThread) {
4454                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4455            }
4456            info.append(processCpuTracker.printCurrentLoad());
4457            info.append(cpuInfo);
4458        }
4459
4460        info.append(processCpuTracker.printCurrentState(anrTime));
4461
4462        Slog.e(TAG, info.toString());
4463        if (tracesFile == null) {
4464            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4465            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4466        }
4467
4468        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4469                cpuInfo, tracesFile, null);
4470
4471        if (mController != null) {
4472            try {
4473                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4474                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4475                if (res != 0) {
4476                    if (res < 0 && app.pid != MY_PID) {
4477                        Process.killProcess(app.pid);
4478                        Process.killProcessGroup(app.info.uid, app.pid);
4479                    } else {
4480                        synchronized (this) {
4481                            mServices.scheduleServiceTimeoutLocked(app);
4482                        }
4483                    }
4484                    return;
4485                }
4486            } catch (RemoteException e) {
4487                mController = null;
4488                Watchdog.getInstance().setActivityController(null);
4489            }
4490        }
4491
4492        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4493        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4494                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4495
4496        synchronized (this) {
4497            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4498                killUnneededProcessLocked(app, "background ANR");
4499                return;
4500            }
4501
4502            // Set the app's notResponding state, and look up the errorReportReceiver
4503            makeAppNotRespondingLocked(app,
4504                    activity != null ? activity.shortComponentName : null,
4505                    annotation != null ? "ANR " + annotation : "ANR",
4506                    info.toString());
4507
4508            // Bring up the infamous App Not Responding dialog
4509            Message msg = Message.obtain();
4510            HashMap<String, Object> map = new HashMap<String, Object>();
4511            msg.what = SHOW_NOT_RESPONDING_MSG;
4512            msg.obj = map;
4513            msg.arg1 = aboveSystem ? 1 : 0;
4514            map.put("app", app);
4515            if (activity != null) {
4516                map.put("activity", activity);
4517            }
4518
4519            mHandler.sendMessage(msg);
4520        }
4521    }
4522
4523    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4524        if (!mLaunchWarningShown) {
4525            mLaunchWarningShown = true;
4526            mHandler.post(new Runnable() {
4527                @Override
4528                public void run() {
4529                    synchronized (ActivityManagerService.this) {
4530                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4531                        d.show();
4532                        mHandler.postDelayed(new Runnable() {
4533                            @Override
4534                            public void run() {
4535                                synchronized (ActivityManagerService.this) {
4536                                    d.dismiss();
4537                                    mLaunchWarningShown = false;
4538                                }
4539                            }
4540                        }, 4000);
4541                    }
4542                }
4543            });
4544        }
4545    }
4546
4547    @Override
4548    public boolean clearApplicationUserData(final String packageName,
4549            final IPackageDataObserver observer, int userId) {
4550        enforceNotIsolatedCaller("clearApplicationUserData");
4551        int uid = Binder.getCallingUid();
4552        int pid = Binder.getCallingPid();
4553        userId = handleIncomingUser(pid, uid,
4554                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4555        long callingId = Binder.clearCallingIdentity();
4556        try {
4557            IPackageManager pm = AppGlobals.getPackageManager();
4558            int pkgUid = -1;
4559            synchronized(this) {
4560                try {
4561                    pkgUid = pm.getPackageUid(packageName, userId);
4562                } catch (RemoteException e) {
4563                }
4564                if (pkgUid == -1) {
4565                    Slog.w(TAG, "Invalid packageName: " + packageName);
4566                    if (observer != null) {
4567                        try {
4568                            observer.onRemoveCompleted(packageName, false);
4569                        } catch (RemoteException e) {
4570                            Slog.i(TAG, "Observer no longer exists.");
4571                        }
4572                    }
4573                    return false;
4574                }
4575                if (uid == pkgUid || checkComponentPermission(
4576                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4577                        pid, uid, -1, true)
4578                        == PackageManager.PERMISSION_GRANTED) {
4579                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4580                } else {
4581                    throw new SecurityException("PID " + pid + " does not have permission "
4582                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4583                                    + " of package " + packageName);
4584                }
4585            }
4586
4587            try {
4588                // Clear application user data
4589                pm.clearApplicationUserData(packageName, observer, userId);
4590
4591                // Remove all permissions granted from/to this package
4592                removeUriPermissionsForPackageLocked(packageName, userId, true);
4593
4594                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4595                        Uri.fromParts("package", packageName, null));
4596                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4597                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4598                        null, null, 0, null, null, null, false, false, userId);
4599            } catch (RemoteException e) {
4600            }
4601        } finally {
4602            Binder.restoreCallingIdentity(callingId);
4603        }
4604        return true;
4605    }
4606
4607    @Override
4608    public void killBackgroundProcesses(final String packageName, int userId) {
4609        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4610                != PackageManager.PERMISSION_GRANTED &&
4611                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4612                        != PackageManager.PERMISSION_GRANTED) {
4613            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4614                    + Binder.getCallingPid()
4615                    + ", uid=" + Binder.getCallingUid()
4616                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4617            Slog.w(TAG, msg);
4618            throw new SecurityException(msg);
4619        }
4620
4621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4622                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4623        long callingId = Binder.clearCallingIdentity();
4624        try {
4625            IPackageManager pm = AppGlobals.getPackageManager();
4626            synchronized(this) {
4627                int appId = -1;
4628                try {
4629                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4630                } catch (RemoteException e) {
4631                }
4632                if (appId == -1) {
4633                    Slog.w(TAG, "Invalid packageName: " + packageName);
4634                    return;
4635                }
4636                killPackageProcessesLocked(packageName, appId, userId,
4637                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4638            }
4639        } finally {
4640            Binder.restoreCallingIdentity(callingId);
4641        }
4642    }
4643
4644    @Override
4645    public void killAllBackgroundProcesses() {
4646        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4647                != PackageManager.PERMISSION_GRANTED) {
4648            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4649                    + Binder.getCallingPid()
4650                    + ", uid=" + Binder.getCallingUid()
4651                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4652            Slog.w(TAG, msg);
4653            throw new SecurityException(msg);
4654        }
4655
4656        long callingId = Binder.clearCallingIdentity();
4657        try {
4658            synchronized(this) {
4659                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4660                final int NP = mProcessNames.getMap().size();
4661                for (int ip=0; ip<NP; ip++) {
4662                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4663                    final int NA = apps.size();
4664                    for (int ia=0; ia<NA; ia++) {
4665                        ProcessRecord app = apps.valueAt(ia);
4666                        if (app.persistent) {
4667                            // we don't kill persistent processes
4668                            continue;
4669                        }
4670                        if (app.removed) {
4671                            procs.add(app);
4672                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4673                            app.removed = true;
4674                            procs.add(app);
4675                        }
4676                    }
4677                }
4678
4679                int N = procs.size();
4680                for (int i=0; i<N; i++) {
4681                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4682                }
4683                mAllowLowerMemLevel = true;
4684                updateOomAdjLocked();
4685                doLowMemReportIfNeededLocked(null);
4686            }
4687        } finally {
4688            Binder.restoreCallingIdentity(callingId);
4689        }
4690    }
4691
4692    @Override
4693    public void forceStopPackage(final String packageName, int userId) {
4694        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4695                != PackageManager.PERMISSION_GRANTED) {
4696            String msg = "Permission Denial: forceStopPackage() from pid="
4697                    + Binder.getCallingPid()
4698                    + ", uid=" + Binder.getCallingUid()
4699                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4700            Slog.w(TAG, msg);
4701            throw new SecurityException(msg);
4702        }
4703        final int callingPid = Binder.getCallingPid();
4704        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4705                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4706        long callingId = Binder.clearCallingIdentity();
4707        try {
4708            IPackageManager pm = AppGlobals.getPackageManager();
4709            synchronized(this) {
4710                int[] users = userId == UserHandle.USER_ALL
4711                        ? getUsersLocked() : new int[] { userId };
4712                for (int user : users) {
4713                    int pkgUid = -1;
4714                    try {
4715                        pkgUid = pm.getPackageUid(packageName, user);
4716                    } catch (RemoteException e) {
4717                    }
4718                    if (pkgUid == -1) {
4719                        Slog.w(TAG, "Invalid packageName: " + packageName);
4720                        continue;
4721                    }
4722                    try {
4723                        pm.setPackageStoppedState(packageName, true, user);
4724                    } catch (RemoteException e) {
4725                    } catch (IllegalArgumentException e) {
4726                        Slog.w(TAG, "Failed trying to unstop package "
4727                                + packageName + ": " + e);
4728                    }
4729                    if (isUserRunningLocked(user, false)) {
4730                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4731                    }
4732                }
4733            }
4734        } finally {
4735            Binder.restoreCallingIdentity(callingId);
4736        }
4737    }
4738
4739    @Override
4740    public void addPackageDependency(String packageName) {
4741        synchronized (this) {
4742            int callingPid = Binder.getCallingPid();
4743            if (callingPid == Process.myPid()) {
4744                //  Yeah, um, no.
4745                Slog.w(TAG, "Can't addPackageDependency on system process");
4746                return;
4747            }
4748            ProcessRecord proc;
4749            synchronized (mPidsSelfLocked) {
4750                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4751            }
4752            if (proc != null) {
4753                if (proc.pkgDeps == null) {
4754                    proc.pkgDeps = new ArraySet<String>(1);
4755                }
4756                proc.pkgDeps.add(packageName);
4757            }
4758        }
4759    }
4760
4761    /*
4762     * The pkg name and app id have to be specified.
4763     */
4764    @Override
4765    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4766        if (pkg == null) {
4767            return;
4768        }
4769        // Make sure the uid is valid.
4770        if (appid < 0) {
4771            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4772            return;
4773        }
4774        int callerUid = Binder.getCallingUid();
4775        // Only the system server can kill an application
4776        if (callerUid == Process.SYSTEM_UID) {
4777            // Post an aysnc message to kill the application
4778            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4779            msg.arg1 = appid;
4780            msg.arg2 = 0;
4781            Bundle bundle = new Bundle();
4782            bundle.putString("pkg", pkg);
4783            bundle.putString("reason", reason);
4784            msg.obj = bundle;
4785            mHandler.sendMessage(msg);
4786        } else {
4787            throw new SecurityException(callerUid + " cannot kill pkg: " +
4788                    pkg);
4789        }
4790    }
4791
4792    @Override
4793    public void closeSystemDialogs(String reason) {
4794        enforceNotIsolatedCaller("closeSystemDialogs");
4795
4796        final int pid = Binder.getCallingPid();
4797        final int uid = Binder.getCallingUid();
4798        final long origId = Binder.clearCallingIdentity();
4799        try {
4800            synchronized (this) {
4801                // Only allow this from foreground processes, so that background
4802                // applications can't abuse it to prevent system UI from being shown.
4803                if (uid >= Process.FIRST_APPLICATION_UID) {
4804                    ProcessRecord proc;
4805                    synchronized (mPidsSelfLocked) {
4806                        proc = mPidsSelfLocked.get(pid);
4807                    }
4808                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4809                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4810                                + " from background process " + proc);
4811                        return;
4812                    }
4813                }
4814                closeSystemDialogsLocked(reason);
4815            }
4816        } finally {
4817            Binder.restoreCallingIdentity(origId);
4818        }
4819    }
4820
4821    void closeSystemDialogsLocked(String reason) {
4822        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4823        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4824                | Intent.FLAG_RECEIVER_FOREGROUND);
4825        if (reason != null) {
4826            intent.putExtra("reason", reason);
4827        }
4828        mWindowManager.closeSystemDialogs(reason);
4829
4830        mStackSupervisor.closeSystemDialogsLocked();
4831
4832        broadcastIntentLocked(null, null, intent, null,
4833                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4834                Process.SYSTEM_UID, UserHandle.USER_ALL);
4835    }
4836
4837    @Override
4838    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4839        enforceNotIsolatedCaller("getProcessMemoryInfo");
4840        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4841        for (int i=pids.length-1; i>=0; i--) {
4842            ProcessRecord proc;
4843            int oomAdj;
4844            synchronized (this) {
4845                synchronized (mPidsSelfLocked) {
4846                    proc = mPidsSelfLocked.get(pids[i]);
4847                    oomAdj = proc != null ? proc.setAdj : 0;
4848                }
4849            }
4850            infos[i] = new Debug.MemoryInfo();
4851            Debug.getMemoryInfo(pids[i], infos[i]);
4852            if (proc != null) {
4853                synchronized (this) {
4854                    if (proc.thread != null && proc.setAdj == oomAdj) {
4855                        // Record this for posterity if the process has been stable.
4856                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4857                                infos[i].getTotalUss(), false, proc.pkgList);
4858                    }
4859                }
4860            }
4861        }
4862        return infos;
4863    }
4864
4865    @Override
4866    public long[] getProcessPss(int[] pids) {
4867        enforceNotIsolatedCaller("getProcessPss");
4868        long[] pss = new long[pids.length];
4869        for (int i=pids.length-1; i>=0; i--) {
4870            ProcessRecord proc;
4871            int oomAdj;
4872            synchronized (this) {
4873                synchronized (mPidsSelfLocked) {
4874                    proc = mPidsSelfLocked.get(pids[i]);
4875                    oomAdj = proc != null ? proc.setAdj : 0;
4876                }
4877            }
4878            long[] tmpUss = new long[1];
4879            pss[i] = Debug.getPss(pids[i], tmpUss);
4880            if (proc != null) {
4881                synchronized (this) {
4882                    if (proc.thread != null && proc.setAdj == oomAdj) {
4883                        // Record this for posterity if the process has been stable.
4884                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4885                    }
4886                }
4887            }
4888        }
4889        return pss;
4890    }
4891
4892    @Override
4893    public void killApplicationProcess(String processName, int uid) {
4894        if (processName == null) {
4895            return;
4896        }
4897
4898        int callerUid = Binder.getCallingUid();
4899        // Only the system server can kill an application
4900        if (callerUid == Process.SYSTEM_UID) {
4901            synchronized (this) {
4902                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4903                if (app != null && app.thread != null) {
4904                    try {
4905                        app.thread.scheduleSuicide();
4906                    } catch (RemoteException e) {
4907                        // If the other end already died, then our work here is done.
4908                    }
4909                } else {
4910                    Slog.w(TAG, "Process/uid not found attempting kill of "
4911                            + processName + " / " + uid);
4912                }
4913            }
4914        } else {
4915            throw new SecurityException(callerUid + " cannot kill app process: " +
4916                    processName);
4917        }
4918    }
4919
4920    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4921        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4922                false, true, false, false, UserHandle.getUserId(uid), reason);
4923        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4924                Uri.fromParts("package", packageName, null));
4925        if (!mProcessesReady) {
4926            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4927                    | Intent.FLAG_RECEIVER_FOREGROUND);
4928        }
4929        intent.putExtra(Intent.EXTRA_UID, uid);
4930        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4931        broadcastIntentLocked(null, null, intent,
4932                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4933                false, false,
4934                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4935    }
4936
4937    private void forceStopUserLocked(int userId, String reason) {
4938        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4939        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4940        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4941                | Intent.FLAG_RECEIVER_FOREGROUND);
4942        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4943        broadcastIntentLocked(null, null, intent,
4944                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4945                false, false,
4946                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4947    }
4948
4949    private final boolean killPackageProcessesLocked(String packageName, int appId,
4950            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4951            boolean doit, boolean evenPersistent, String reason) {
4952        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4953
4954        // Remove all processes this package may have touched: all with the
4955        // same UID (except for the system or root user), and all whose name
4956        // matches the package name.
4957        final int NP = mProcessNames.getMap().size();
4958        for (int ip=0; ip<NP; ip++) {
4959            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4960            final int NA = apps.size();
4961            for (int ia=0; ia<NA; ia++) {
4962                ProcessRecord app = apps.valueAt(ia);
4963                if (app.persistent && !evenPersistent) {
4964                    // we don't kill persistent processes
4965                    continue;
4966                }
4967                if (app.removed) {
4968                    if (doit) {
4969                        procs.add(app);
4970                    }
4971                    continue;
4972                }
4973
4974                // Skip process if it doesn't meet our oom adj requirement.
4975                if (app.setAdj < minOomAdj) {
4976                    continue;
4977                }
4978
4979                // If no package is specified, we call all processes under the
4980                // give user id.
4981                if (packageName == null) {
4982                    if (app.userId != userId) {
4983                        continue;
4984                    }
4985                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4986                        continue;
4987                    }
4988                // Package has been specified, we want to hit all processes
4989                // that match it.  We need to qualify this by the processes
4990                // that are running under the specified app and user ID.
4991                } else {
4992                    final boolean isDep = app.pkgDeps != null
4993                            && app.pkgDeps.contains(packageName);
4994                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
4995                        continue;
4996                    }
4997                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4998                        continue;
4999                    }
5000                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5001                        continue;
5002                    }
5003                }
5004
5005                // Process has passed all conditions, kill it!
5006                if (!doit) {
5007                    return true;
5008                }
5009                app.removed = true;
5010                procs.add(app);
5011            }
5012        }
5013
5014        int N = procs.size();
5015        for (int i=0; i<N; i++) {
5016            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5017        }
5018        updateOomAdjLocked();
5019        return N > 0;
5020    }
5021
5022    private final boolean forceStopPackageLocked(String name, int appId,
5023            boolean callerWillRestart, boolean purgeCache, boolean doit,
5024            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5025        int i;
5026        int N;
5027
5028        if (userId == UserHandle.USER_ALL && name == null) {
5029            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5030        }
5031
5032        if (appId < 0 && name != null) {
5033            try {
5034                appId = UserHandle.getAppId(
5035                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5036            } catch (RemoteException e) {
5037            }
5038        }
5039
5040        if (doit) {
5041            if (name != null) {
5042                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5043                        + " user=" + userId + ": " + reason);
5044            } else {
5045                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5046            }
5047
5048            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5049            for (int ip=pmap.size()-1; ip>=0; ip--) {
5050                SparseArray<Long> ba = pmap.valueAt(ip);
5051                for (i=ba.size()-1; i>=0; i--) {
5052                    boolean remove = false;
5053                    final int entUid = ba.keyAt(i);
5054                    if (name != null) {
5055                        if (userId == UserHandle.USER_ALL) {
5056                            if (UserHandle.getAppId(entUid) == appId) {
5057                                remove = true;
5058                            }
5059                        } else {
5060                            if (entUid == UserHandle.getUid(userId, appId)) {
5061                                remove = true;
5062                            }
5063                        }
5064                    } else if (UserHandle.getUserId(entUid) == userId) {
5065                        remove = true;
5066                    }
5067                    if (remove) {
5068                        ba.removeAt(i);
5069                    }
5070                }
5071                if (ba.size() == 0) {
5072                    pmap.removeAt(ip);
5073                }
5074            }
5075        }
5076
5077        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5078                -100, callerWillRestart, true, doit, evenPersistent,
5079                name == null ? ("stop user " + userId) : ("stop " + name));
5080
5081        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5082            if (!doit) {
5083                return true;
5084            }
5085            didSomething = true;
5086        }
5087
5088        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5089            if (!doit) {
5090                return true;
5091            }
5092            didSomething = true;
5093        }
5094
5095        if (name == null) {
5096            // Remove all sticky broadcasts from this user.
5097            mStickyBroadcasts.remove(userId);
5098        }
5099
5100        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5101        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5102                userId, providers)) {
5103            if (!doit) {
5104                return true;
5105            }
5106            didSomething = true;
5107        }
5108        N = providers.size();
5109        for (i=0; i<N; i++) {
5110            removeDyingProviderLocked(null, providers.get(i), true);
5111        }
5112
5113        // Remove transient permissions granted from/to this package/user
5114        removeUriPermissionsForPackageLocked(name, userId, false);
5115
5116        if (name == null || uninstalling) {
5117            // Remove pending intents.  For now we only do this when force
5118            // stopping users, because we have some problems when doing this
5119            // for packages -- app widgets are not currently cleaned up for
5120            // such packages, so they can be left with bad pending intents.
5121            if (mIntentSenderRecords.size() > 0) {
5122                Iterator<WeakReference<PendingIntentRecord>> it
5123                        = mIntentSenderRecords.values().iterator();
5124                while (it.hasNext()) {
5125                    WeakReference<PendingIntentRecord> wpir = it.next();
5126                    if (wpir == null) {
5127                        it.remove();
5128                        continue;
5129                    }
5130                    PendingIntentRecord pir = wpir.get();
5131                    if (pir == null) {
5132                        it.remove();
5133                        continue;
5134                    }
5135                    if (name == null) {
5136                        // Stopping user, remove all objects for the user.
5137                        if (pir.key.userId != userId) {
5138                            // Not the same user, skip it.
5139                            continue;
5140                        }
5141                    } else {
5142                        if (UserHandle.getAppId(pir.uid) != appId) {
5143                            // Different app id, skip it.
5144                            continue;
5145                        }
5146                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5147                            // Different user, skip it.
5148                            continue;
5149                        }
5150                        if (!pir.key.packageName.equals(name)) {
5151                            // Different package, skip it.
5152                            continue;
5153                        }
5154                    }
5155                    if (!doit) {
5156                        return true;
5157                    }
5158                    didSomething = true;
5159                    it.remove();
5160                    pir.canceled = true;
5161                    if (pir.key.activity != null) {
5162                        pir.key.activity.pendingResults.remove(pir.ref);
5163                    }
5164                }
5165            }
5166        }
5167
5168        if (doit) {
5169            if (purgeCache && name != null) {
5170                AttributeCache ac = AttributeCache.instance();
5171                if (ac != null) {
5172                    ac.removePackage(name);
5173                }
5174            }
5175            if (mBooted) {
5176                mStackSupervisor.resumeTopActivitiesLocked();
5177                mStackSupervisor.scheduleIdleLocked();
5178            }
5179        }
5180
5181        return didSomething;
5182    }
5183
5184    private final boolean removeProcessLocked(ProcessRecord app,
5185            boolean callerWillRestart, boolean allowRestart, String reason) {
5186        final String name = app.processName;
5187        final int uid = app.uid;
5188        if (DEBUG_PROCESSES) Slog.d(
5189            TAG, "Force removing proc " + app.toShortString() + " (" + name
5190            + "/" + uid + ")");
5191
5192        mProcessNames.remove(name, uid);
5193        mIsolatedProcesses.remove(app.uid);
5194        if (mHeavyWeightProcess == app) {
5195            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5196                    mHeavyWeightProcess.userId, 0));
5197            mHeavyWeightProcess = null;
5198        }
5199        boolean needRestart = false;
5200        if (app.pid > 0 && app.pid != MY_PID) {
5201            int pid = app.pid;
5202            synchronized (mPidsSelfLocked) {
5203                mPidsSelfLocked.remove(pid);
5204                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5205            }
5206            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5207            if (app.isolated) {
5208                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5209            }
5210            killUnneededProcessLocked(app, reason);
5211            Process.killProcessGroup(app.info.uid, app.pid);
5212            handleAppDiedLocked(app, true, allowRestart);
5213            removeLruProcessLocked(app);
5214
5215            if (app.persistent && !app.isolated) {
5216                if (!callerWillRestart) {
5217                    addAppLocked(app.info, false, null /* ABI override */);
5218                } else {
5219                    needRestart = true;
5220                }
5221            }
5222        } else {
5223            mRemovedProcesses.add(app);
5224        }
5225
5226        return needRestart;
5227    }
5228
5229    private final void processStartTimedOutLocked(ProcessRecord app) {
5230        final int pid = app.pid;
5231        boolean gone = false;
5232        synchronized (mPidsSelfLocked) {
5233            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5234            if (knownApp != null && knownApp.thread == null) {
5235                mPidsSelfLocked.remove(pid);
5236                gone = true;
5237            }
5238        }
5239
5240        if (gone) {
5241            Slog.w(TAG, "Process " + app + " failed to attach");
5242            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5243                    pid, app.uid, app.processName);
5244            mProcessNames.remove(app.processName, app.uid);
5245            mIsolatedProcesses.remove(app.uid);
5246            if (mHeavyWeightProcess == app) {
5247                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5248                        mHeavyWeightProcess.userId, 0));
5249                mHeavyWeightProcess = null;
5250            }
5251            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5252            if (app.isolated) {
5253                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5254            }
5255            // Take care of any launching providers waiting for this process.
5256            checkAppInLaunchingProvidersLocked(app, true);
5257            // Take care of any services that are waiting for the process.
5258            mServices.processStartTimedOutLocked(app);
5259            killUnneededProcessLocked(app, "start timeout");
5260            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5261                Slog.w(TAG, "Unattached app died before backup, skipping");
5262                try {
5263                    IBackupManager bm = IBackupManager.Stub.asInterface(
5264                            ServiceManager.getService(Context.BACKUP_SERVICE));
5265                    bm.agentDisconnected(app.info.packageName);
5266                } catch (RemoteException e) {
5267                    // Can't happen; the backup manager is local
5268                }
5269            }
5270            if (isPendingBroadcastProcessLocked(pid)) {
5271                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5272                skipPendingBroadcastLocked(pid);
5273            }
5274        } else {
5275            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5276        }
5277    }
5278
5279    private final boolean attachApplicationLocked(IApplicationThread thread,
5280            int pid) {
5281
5282        // Find the application record that is being attached...  either via
5283        // the pid if we are running in multiple processes, or just pull the
5284        // next app record if we are emulating process with anonymous threads.
5285        ProcessRecord app;
5286        if (pid != MY_PID && pid >= 0) {
5287            synchronized (mPidsSelfLocked) {
5288                app = mPidsSelfLocked.get(pid);
5289            }
5290        } else {
5291            app = null;
5292        }
5293
5294        if (app == null) {
5295            Slog.w(TAG, "No pending application record for pid " + pid
5296                    + " (IApplicationThread " + thread + "); dropping process");
5297            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5298            if (pid > 0 && pid != MY_PID) {
5299                Process.killProcessQuiet(pid);
5300                //TODO: Process.killProcessGroup(app.info.uid, pid);
5301            } else {
5302                try {
5303                    thread.scheduleExit();
5304                } catch (Exception e) {
5305                    // Ignore exceptions.
5306                }
5307            }
5308            return false;
5309        }
5310
5311        // If this application record is still attached to a previous
5312        // process, clean it up now.
5313        if (app.thread != null) {
5314            handleAppDiedLocked(app, true, true);
5315        }
5316
5317        // Tell the process all about itself.
5318
5319        if (localLOGV) Slog.v(
5320                TAG, "Binding process pid " + pid + " to record " + app);
5321
5322        final String processName = app.processName;
5323        try {
5324            AppDeathRecipient adr = new AppDeathRecipient(
5325                    app, pid, thread);
5326            thread.asBinder().linkToDeath(adr, 0);
5327            app.deathRecipient = adr;
5328        } catch (RemoteException e) {
5329            app.resetPackageList(mProcessStats);
5330            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5331            return false;
5332        }
5333
5334        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5335
5336        app.makeActive(thread, mProcessStats);
5337        app.curAdj = app.setAdj = -100;
5338        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5339        app.forcingToForeground = null;
5340        updateProcessForegroundLocked(app, false, false);
5341        app.hasShownUi = false;
5342        app.debugging = false;
5343        app.cached = false;
5344
5345        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5346
5347        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5348        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5349
5350        if (!normalMode) {
5351            Slog.i(TAG, "Launching preboot mode app: " + app);
5352        }
5353
5354        if (localLOGV) Slog.v(
5355            TAG, "New app record " + app
5356            + " thread=" + thread.asBinder() + " pid=" + pid);
5357        try {
5358            int testMode = IApplicationThread.DEBUG_OFF;
5359            if (mDebugApp != null && mDebugApp.equals(processName)) {
5360                testMode = mWaitForDebugger
5361                    ? IApplicationThread.DEBUG_WAIT
5362                    : IApplicationThread.DEBUG_ON;
5363                app.debugging = true;
5364                if (mDebugTransient) {
5365                    mDebugApp = mOrigDebugApp;
5366                    mWaitForDebugger = mOrigWaitForDebugger;
5367                }
5368            }
5369            String profileFile = app.instrumentationProfileFile;
5370            ParcelFileDescriptor profileFd = null;
5371            boolean profileAutoStop = false;
5372            if (mProfileApp != null && mProfileApp.equals(processName)) {
5373                mProfileProc = app;
5374                profileFile = mProfileFile;
5375                profileFd = mProfileFd;
5376                profileAutoStop = mAutoStopProfiler;
5377            }
5378            boolean enableOpenGlTrace = false;
5379            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5380                enableOpenGlTrace = true;
5381                mOpenGlTraceApp = null;
5382            }
5383
5384            // If the app is being launched for restore or full backup, set it up specially
5385            boolean isRestrictedBackupMode = false;
5386            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5387                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5388                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5389                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5390            }
5391
5392            ensurePackageDexOpt(app.instrumentationInfo != null
5393                    ? app.instrumentationInfo.packageName
5394                    : app.info.packageName);
5395            if (app.instrumentationClass != null) {
5396                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5397            }
5398            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5399                    + processName + " with config " + mConfiguration);
5400            ApplicationInfo appInfo = app.instrumentationInfo != null
5401                    ? app.instrumentationInfo : app.info;
5402            app.compat = compatibilityInfoForPackageLocked(appInfo);
5403            if (profileFd != null) {
5404                profileFd = profileFd.dup();
5405            }
5406            thread.bindApplication(processName, appInfo, providers,
5407                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5408                    app.instrumentationArguments, app.instrumentationWatcher,
5409                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5410                    isRestrictedBackupMode || !normalMode, app.persistent,
5411                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5412                    mCoreSettingsObserver.getCoreSettingsLocked());
5413            updateLruProcessLocked(app, false, null);
5414            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5415        } catch (Exception e) {
5416            // todo: Yikes!  What should we do?  For now we will try to
5417            // start another process, but that could easily get us in
5418            // an infinite loop of restarting processes...
5419            Slog.w(TAG, "Exception thrown during bind!", e);
5420
5421            app.resetPackageList(mProcessStats);
5422            app.unlinkDeathRecipient();
5423            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5424            return false;
5425        }
5426
5427        // Remove this record from the list of starting applications.
5428        mPersistentStartingProcesses.remove(app);
5429        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5430                "Attach application locked removing on hold: " + app);
5431        mProcessesOnHold.remove(app);
5432
5433        boolean badApp = false;
5434        boolean didSomething = false;
5435
5436        // See if the top visible activity is waiting to run in this process...
5437        if (normalMode) {
5438            try {
5439                if (mStackSupervisor.attachApplicationLocked(app)) {
5440                    didSomething = true;
5441                }
5442            } catch (Exception e) {
5443                badApp = true;
5444            }
5445        }
5446
5447        // Find any services that should be running in this process...
5448        if (!badApp) {
5449            try {
5450                didSomething |= mServices.attachApplicationLocked(app, processName);
5451            } catch (Exception e) {
5452                badApp = true;
5453            }
5454        }
5455
5456        // Check if a next-broadcast receiver is in this process...
5457        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5458            try {
5459                didSomething |= sendPendingBroadcastsLocked(app);
5460            } catch (Exception e) {
5461                // If the app died trying to launch the receiver we declare it 'bad'
5462                badApp = true;
5463            }
5464        }
5465
5466        // Check whether the next backup agent is in this process...
5467        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5468            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5469            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5470            try {
5471                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5472                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5473                        mBackupTarget.backupMode);
5474            } catch (Exception e) {
5475                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5476                e.printStackTrace();
5477            }
5478        }
5479
5480        if (badApp) {
5481            // todo: Also need to kill application to deal with all
5482            // kinds of exceptions.
5483            handleAppDiedLocked(app, false, true);
5484            return false;
5485        }
5486
5487        if (!didSomething) {
5488            updateOomAdjLocked();
5489        }
5490
5491        return true;
5492    }
5493
5494    @Override
5495    public final void attachApplication(IApplicationThread thread) {
5496        synchronized (this) {
5497            int callingPid = Binder.getCallingPid();
5498            final long origId = Binder.clearCallingIdentity();
5499            attachApplicationLocked(thread, callingPid);
5500            Binder.restoreCallingIdentity(origId);
5501        }
5502    }
5503
5504    @Override
5505    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5506        final long origId = Binder.clearCallingIdentity();
5507        synchronized (this) {
5508            ActivityStack stack = ActivityRecord.getStackLocked(token);
5509            if (stack != null) {
5510                ActivityRecord r =
5511                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5512                if (stopProfiling) {
5513                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5514                        try {
5515                            mProfileFd.close();
5516                        } catch (IOException e) {
5517                        }
5518                        clearProfilerLocked();
5519                    }
5520                }
5521            }
5522        }
5523        Binder.restoreCallingIdentity(origId);
5524    }
5525
5526    void enableScreenAfterBoot() {
5527        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5528                SystemClock.uptimeMillis());
5529        mWindowManager.enableScreenAfterBoot();
5530
5531        synchronized (this) {
5532            updateEventDispatchingLocked();
5533        }
5534    }
5535
5536    @Override
5537    public void showBootMessage(final CharSequence msg, final boolean always) {
5538        enforceNotIsolatedCaller("showBootMessage");
5539        mWindowManager.showBootMessage(msg, always);
5540    }
5541
5542    @Override
5543    public void dismissKeyguardOnNextActivity() {
5544        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5545        final long token = Binder.clearCallingIdentity();
5546        try {
5547            synchronized (this) {
5548                if (DEBUG_LOCKSCREEN) logLockScreen("");
5549                if (mLockScreenShown) {
5550                    mLockScreenShown = false;
5551                    comeOutOfSleepIfNeededLocked();
5552                }
5553                mStackSupervisor.setDismissKeyguard(true);
5554            }
5555        } finally {
5556            Binder.restoreCallingIdentity(token);
5557        }
5558    }
5559
5560    final void finishBooting() {
5561        // Register receivers to handle package update events
5562        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5563
5564        synchronized (this) {
5565            // Ensure that any processes we had put on hold are now started
5566            // up.
5567            final int NP = mProcessesOnHold.size();
5568            if (NP > 0) {
5569                ArrayList<ProcessRecord> procs =
5570                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5571                for (int ip=0; ip<NP; ip++) {
5572                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5573                            + procs.get(ip));
5574                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5575                }
5576            }
5577
5578            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5579                // Start looking for apps that are abusing wake locks.
5580                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5581                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5582                // Tell anyone interested that we are done booting!
5583                SystemProperties.set("sys.boot_completed", "1");
5584                SystemProperties.set("dev.bootcomplete", "1");
5585                for (int i=0; i<mStartedUsers.size(); i++) {
5586                    UserStartedState uss = mStartedUsers.valueAt(i);
5587                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5588                        uss.mState = UserStartedState.STATE_RUNNING;
5589                        final int userId = mStartedUsers.keyAt(i);
5590                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5591                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5592                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5593                        broadcastIntentLocked(null, null, intent, null,
5594                                new IIntentReceiver.Stub() {
5595                                    @Override
5596                                    public void performReceive(Intent intent, int resultCode,
5597                                            String data, Bundle extras, boolean ordered,
5598                                            boolean sticky, int sendingUser) {
5599                                        synchronized (ActivityManagerService.this) {
5600                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5601                                                    true, false);
5602                                        }
5603                                    }
5604                                },
5605                                0, null, null,
5606                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5607                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5608                                userId);
5609                    }
5610                }
5611                scheduleStartProfilesLocked();
5612            }
5613        }
5614    }
5615
5616    final void ensureBootCompleted() {
5617        boolean booting;
5618        boolean enableScreen;
5619        synchronized (this) {
5620            booting = mBooting;
5621            mBooting = false;
5622            enableScreen = !mBooted;
5623            mBooted = true;
5624        }
5625
5626        if (booting) {
5627            finishBooting();
5628        }
5629
5630        if (enableScreen) {
5631            enableScreenAfterBoot();
5632        }
5633    }
5634
5635    @Override
5636    public final void activityResumed(IBinder token) {
5637        final long origId = Binder.clearCallingIdentity();
5638        synchronized(this) {
5639            ActivityStack stack = ActivityRecord.getStackLocked(token);
5640            if (stack != null) {
5641                ActivityRecord.activityResumedLocked(token);
5642            }
5643        }
5644        Binder.restoreCallingIdentity(origId);
5645    }
5646
5647    @Override
5648    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5649        final long origId = Binder.clearCallingIdentity();
5650        synchronized(this) {
5651            ActivityStack stack = ActivityRecord.getStackLocked(token);
5652            if (stack != null) {
5653                stack.activityPausedLocked(token, false, persistentState);
5654            }
5655        }
5656        Binder.restoreCallingIdentity(origId);
5657    }
5658
5659    @Override
5660    public final void activityStopped(IBinder token, Bundle icicle,
5661            PersistableBundle persistentState, CharSequence description) {
5662        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5663
5664        // Refuse possible leaked file descriptors
5665        if (icicle != null && icicle.hasFileDescriptors()) {
5666            throw new IllegalArgumentException("File descriptors passed in Bundle");
5667        }
5668
5669        final long origId = Binder.clearCallingIdentity();
5670
5671        synchronized (this) {
5672            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5673            if (r != null) {
5674                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5675            }
5676        }
5677
5678        trimApplications();
5679
5680        Binder.restoreCallingIdentity(origId);
5681    }
5682
5683    @Override
5684    public final void activityDestroyed(IBinder token) {
5685        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5686        synchronized (this) {
5687            ActivityStack stack = ActivityRecord.getStackLocked(token);
5688            if (stack != null) {
5689                stack.activityDestroyedLocked(token);
5690            }
5691        }
5692    }
5693
5694    @Override
5695    public final void mediaResourcesReleased(IBinder token) {
5696        final long origId = Binder.clearCallingIdentity();
5697        try {
5698            synchronized (this) {
5699                ActivityStack stack = ActivityRecord.getStackLocked(token);
5700                if (stack != null) {
5701                    stack.mediaResourcesReleased(token);
5702                }
5703            }
5704        } finally {
5705            Binder.restoreCallingIdentity(origId);
5706        }
5707    }
5708
5709    @Override
5710    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5711        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5712    }
5713
5714    @Override
5715    public final void notifyEnterAnimationComplete(IBinder token) {
5716        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5717    }
5718
5719    @Override
5720    public String getCallingPackage(IBinder token) {
5721        synchronized (this) {
5722            ActivityRecord r = getCallingRecordLocked(token);
5723            return r != null ? r.info.packageName : null;
5724        }
5725    }
5726
5727    @Override
5728    public ComponentName getCallingActivity(IBinder token) {
5729        synchronized (this) {
5730            ActivityRecord r = getCallingRecordLocked(token);
5731            return r != null ? r.intent.getComponent() : null;
5732        }
5733    }
5734
5735    private ActivityRecord getCallingRecordLocked(IBinder token) {
5736        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5737        if (r == null) {
5738            return null;
5739        }
5740        return r.resultTo;
5741    }
5742
5743    @Override
5744    public ComponentName getActivityClassForToken(IBinder token) {
5745        synchronized(this) {
5746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5747            if (r == null) {
5748                return null;
5749            }
5750            return r.intent.getComponent();
5751        }
5752    }
5753
5754    @Override
5755    public String getPackageForToken(IBinder token) {
5756        synchronized(this) {
5757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5758            if (r == null) {
5759                return null;
5760            }
5761            return r.packageName;
5762        }
5763    }
5764
5765    @Override
5766    public IIntentSender getIntentSender(int type,
5767            String packageName, IBinder token, String resultWho,
5768            int requestCode, Intent[] intents, String[] resolvedTypes,
5769            int flags, Bundle options, int userId) {
5770        enforceNotIsolatedCaller("getIntentSender");
5771        // Refuse possible leaked file descriptors
5772        if (intents != null) {
5773            if (intents.length < 1) {
5774                throw new IllegalArgumentException("Intents array length must be >= 1");
5775            }
5776            for (int i=0; i<intents.length; i++) {
5777                Intent intent = intents[i];
5778                if (intent != null) {
5779                    if (intent.hasFileDescriptors()) {
5780                        throw new IllegalArgumentException("File descriptors passed in Intent");
5781                    }
5782                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5783                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5784                        throw new IllegalArgumentException(
5785                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5786                    }
5787                    intents[i] = new Intent(intent);
5788                }
5789            }
5790            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5791                throw new IllegalArgumentException(
5792                        "Intent array length does not match resolvedTypes length");
5793            }
5794        }
5795        if (options != null) {
5796            if (options.hasFileDescriptors()) {
5797                throw new IllegalArgumentException("File descriptors passed in options");
5798            }
5799        }
5800
5801        synchronized(this) {
5802            int callingUid = Binder.getCallingUid();
5803            int origUserId = userId;
5804            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5805                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5806                    ALLOW_NON_FULL, "getIntentSender", null);
5807            if (origUserId == UserHandle.USER_CURRENT) {
5808                // We don't want to evaluate this until the pending intent is
5809                // actually executed.  However, we do want to always do the
5810                // security checking for it above.
5811                userId = UserHandle.USER_CURRENT;
5812            }
5813            try {
5814                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5815                    int uid = AppGlobals.getPackageManager()
5816                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5817                    if (!UserHandle.isSameApp(callingUid, uid)) {
5818                        String msg = "Permission Denial: getIntentSender() from pid="
5819                            + Binder.getCallingPid()
5820                            + ", uid=" + Binder.getCallingUid()
5821                            + ", (need uid=" + uid + ")"
5822                            + " is not allowed to send as package " + packageName;
5823                        Slog.w(TAG, msg);
5824                        throw new SecurityException(msg);
5825                    }
5826                }
5827
5828                return getIntentSenderLocked(type, packageName, callingUid, userId,
5829                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5830
5831            } catch (RemoteException e) {
5832                throw new SecurityException(e);
5833            }
5834        }
5835    }
5836
5837    IIntentSender getIntentSenderLocked(int type, String packageName,
5838            int callingUid, int userId, IBinder token, String resultWho,
5839            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5840            Bundle options) {
5841        if (DEBUG_MU)
5842            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5843        ActivityRecord activity = null;
5844        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5845            activity = ActivityRecord.isInStackLocked(token);
5846            if (activity == null) {
5847                return null;
5848            }
5849            if (activity.finishing) {
5850                return null;
5851            }
5852        }
5853
5854        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5855        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5856        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5857        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5858                |PendingIntent.FLAG_UPDATE_CURRENT);
5859
5860        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5861                type, packageName, activity, resultWho,
5862                requestCode, intents, resolvedTypes, flags, options, userId);
5863        WeakReference<PendingIntentRecord> ref;
5864        ref = mIntentSenderRecords.get(key);
5865        PendingIntentRecord rec = ref != null ? ref.get() : null;
5866        if (rec != null) {
5867            if (!cancelCurrent) {
5868                if (updateCurrent) {
5869                    if (rec.key.requestIntent != null) {
5870                        rec.key.requestIntent.replaceExtras(intents != null ?
5871                                intents[intents.length - 1] : null);
5872                    }
5873                    if (intents != null) {
5874                        intents[intents.length-1] = rec.key.requestIntent;
5875                        rec.key.allIntents = intents;
5876                        rec.key.allResolvedTypes = resolvedTypes;
5877                    } else {
5878                        rec.key.allIntents = null;
5879                        rec.key.allResolvedTypes = null;
5880                    }
5881                }
5882                return rec;
5883            }
5884            rec.canceled = true;
5885            mIntentSenderRecords.remove(key);
5886        }
5887        if (noCreate) {
5888            return rec;
5889        }
5890        rec = new PendingIntentRecord(this, key, callingUid);
5891        mIntentSenderRecords.put(key, rec.ref);
5892        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5893            if (activity.pendingResults == null) {
5894                activity.pendingResults
5895                        = new HashSet<WeakReference<PendingIntentRecord>>();
5896            }
5897            activity.pendingResults.add(rec.ref);
5898        }
5899        return rec;
5900    }
5901
5902    @Override
5903    public void cancelIntentSender(IIntentSender sender) {
5904        if (!(sender instanceof PendingIntentRecord)) {
5905            return;
5906        }
5907        synchronized(this) {
5908            PendingIntentRecord rec = (PendingIntentRecord)sender;
5909            try {
5910                int uid = AppGlobals.getPackageManager()
5911                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5912                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5913                    String msg = "Permission Denial: cancelIntentSender() from pid="
5914                        + Binder.getCallingPid()
5915                        + ", uid=" + Binder.getCallingUid()
5916                        + " is not allowed to cancel packges "
5917                        + rec.key.packageName;
5918                    Slog.w(TAG, msg);
5919                    throw new SecurityException(msg);
5920                }
5921            } catch (RemoteException e) {
5922                throw new SecurityException(e);
5923            }
5924            cancelIntentSenderLocked(rec, true);
5925        }
5926    }
5927
5928    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5929        rec.canceled = true;
5930        mIntentSenderRecords.remove(rec.key);
5931        if (cleanActivity && rec.key.activity != null) {
5932            rec.key.activity.pendingResults.remove(rec.ref);
5933        }
5934    }
5935
5936    @Override
5937    public String getPackageForIntentSender(IIntentSender pendingResult) {
5938        if (!(pendingResult instanceof PendingIntentRecord)) {
5939            return null;
5940        }
5941        try {
5942            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5943            return res.key.packageName;
5944        } catch (ClassCastException e) {
5945        }
5946        return null;
5947    }
5948
5949    @Override
5950    public int getUidForIntentSender(IIntentSender sender) {
5951        if (sender instanceof PendingIntentRecord) {
5952            try {
5953                PendingIntentRecord res = (PendingIntentRecord)sender;
5954                return res.uid;
5955            } catch (ClassCastException e) {
5956            }
5957        }
5958        return -1;
5959    }
5960
5961    @Override
5962    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5963        if (!(pendingResult instanceof PendingIntentRecord)) {
5964            return false;
5965        }
5966        try {
5967            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5968            if (res.key.allIntents == null) {
5969                return false;
5970            }
5971            for (int i=0; i<res.key.allIntents.length; i++) {
5972                Intent intent = res.key.allIntents[i];
5973                if (intent.getPackage() != null && intent.getComponent() != null) {
5974                    return false;
5975                }
5976            }
5977            return true;
5978        } catch (ClassCastException e) {
5979        }
5980        return false;
5981    }
5982
5983    @Override
5984    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5985        if (!(pendingResult instanceof PendingIntentRecord)) {
5986            return false;
5987        }
5988        try {
5989            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5990            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5991                return true;
5992            }
5993            return false;
5994        } catch (ClassCastException e) {
5995        }
5996        return false;
5997    }
5998
5999    @Override
6000    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6001        if (!(pendingResult instanceof PendingIntentRecord)) {
6002            return null;
6003        }
6004        try {
6005            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6006            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6007        } catch (ClassCastException e) {
6008        }
6009        return null;
6010    }
6011
6012    @Override
6013    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6014        if (!(pendingResult instanceof PendingIntentRecord)) {
6015            return null;
6016        }
6017        try {
6018            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6019            Intent intent = res.key.requestIntent;
6020            if (intent != null) {
6021                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6022                        || res.lastTagPrefix.equals(prefix))) {
6023                    return res.lastTag;
6024                }
6025                res.lastTagPrefix = prefix;
6026                StringBuilder sb = new StringBuilder(128);
6027                if (prefix != null) {
6028                    sb.append(prefix);
6029                }
6030                if (intent.getAction() != null) {
6031                    sb.append(intent.getAction());
6032                } else if (intent.getComponent() != null) {
6033                    intent.getComponent().appendShortString(sb);
6034                } else {
6035                    sb.append("?");
6036                }
6037                return res.lastTag = sb.toString();
6038            }
6039        } catch (ClassCastException e) {
6040        }
6041        return null;
6042    }
6043
6044    @Override
6045    public void setProcessLimit(int max) {
6046        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6047                "setProcessLimit()");
6048        synchronized (this) {
6049            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6050            mProcessLimitOverride = max;
6051        }
6052        trimApplications();
6053    }
6054
6055    @Override
6056    public int getProcessLimit() {
6057        synchronized (this) {
6058            return mProcessLimitOverride;
6059        }
6060    }
6061
6062    void foregroundTokenDied(ForegroundToken token) {
6063        synchronized (ActivityManagerService.this) {
6064            synchronized (mPidsSelfLocked) {
6065                ForegroundToken cur
6066                    = mForegroundProcesses.get(token.pid);
6067                if (cur != token) {
6068                    return;
6069                }
6070                mForegroundProcesses.remove(token.pid);
6071                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6072                if (pr == null) {
6073                    return;
6074                }
6075                pr.forcingToForeground = null;
6076                updateProcessForegroundLocked(pr, false, false);
6077            }
6078            updateOomAdjLocked();
6079        }
6080    }
6081
6082    @Override
6083    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6084        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6085                "setProcessForeground()");
6086        synchronized(this) {
6087            boolean changed = false;
6088
6089            synchronized (mPidsSelfLocked) {
6090                ProcessRecord pr = mPidsSelfLocked.get(pid);
6091                if (pr == null && isForeground) {
6092                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6093                    return;
6094                }
6095                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6096                if (oldToken != null) {
6097                    oldToken.token.unlinkToDeath(oldToken, 0);
6098                    mForegroundProcesses.remove(pid);
6099                    if (pr != null) {
6100                        pr.forcingToForeground = null;
6101                    }
6102                    changed = true;
6103                }
6104                if (isForeground && token != null) {
6105                    ForegroundToken newToken = new ForegroundToken() {
6106                        @Override
6107                        public void binderDied() {
6108                            foregroundTokenDied(this);
6109                        }
6110                    };
6111                    newToken.pid = pid;
6112                    newToken.token = token;
6113                    try {
6114                        token.linkToDeath(newToken, 0);
6115                        mForegroundProcesses.put(pid, newToken);
6116                        pr.forcingToForeground = token;
6117                        changed = true;
6118                    } catch (RemoteException e) {
6119                        // If the process died while doing this, we will later
6120                        // do the cleanup with the process death link.
6121                    }
6122                }
6123            }
6124
6125            if (changed) {
6126                updateOomAdjLocked();
6127            }
6128        }
6129    }
6130
6131    // =========================================================
6132    // PERMISSIONS
6133    // =========================================================
6134
6135    static class PermissionController extends IPermissionController.Stub {
6136        ActivityManagerService mActivityManagerService;
6137        PermissionController(ActivityManagerService activityManagerService) {
6138            mActivityManagerService = activityManagerService;
6139        }
6140
6141        @Override
6142        public boolean checkPermission(String permission, int pid, int uid) {
6143            return mActivityManagerService.checkPermission(permission, pid,
6144                    uid) == PackageManager.PERMISSION_GRANTED;
6145        }
6146    }
6147
6148    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6149        @Override
6150        public int checkComponentPermission(String permission, int pid, int uid,
6151                int owningUid, boolean exported) {
6152            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6153                    owningUid, exported);
6154        }
6155
6156        @Override
6157        public Object getAMSLock() {
6158            return ActivityManagerService.this;
6159        }
6160    }
6161
6162    /**
6163     * This can be called with or without the global lock held.
6164     */
6165    int checkComponentPermission(String permission, int pid, int uid,
6166            int owningUid, boolean exported) {
6167        // We might be performing an operation on behalf of an indirect binder
6168        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6169        // client identity accordingly before proceeding.
6170        Identity tlsIdentity = sCallerIdentity.get();
6171        if (tlsIdentity != null) {
6172            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6173                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6174            uid = tlsIdentity.uid;
6175            pid = tlsIdentity.pid;
6176        }
6177
6178        if (pid == MY_PID) {
6179            return PackageManager.PERMISSION_GRANTED;
6180        }
6181
6182        return ActivityManager.checkComponentPermission(permission, uid,
6183                owningUid, exported);
6184    }
6185
6186    /**
6187     * As the only public entry point for permissions checking, this method
6188     * can enforce the semantic that requesting a check on a null global
6189     * permission is automatically denied.  (Internally a null permission
6190     * string is used when calling {@link #checkComponentPermission} in cases
6191     * when only uid-based security is needed.)
6192     *
6193     * This can be called with or without the global lock held.
6194     */
6195    @Override
6196    public int checkPermission(String permission, int pid, int uid) {
6197        if (permission == null) {
6198            return PackageManager.PERMISSION_DENIED;
6199        }
6200        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6201    }
6202
6203    /**
6204     * Binder IPC calls go through the public entry point.
6205     * This can be called with or without the global lock held.
6206     */
6207    int checkCallingPermission(String permission) {
6208        return checkPermission(permission,
6209                Binder.getCallingPid(),
6210                UserHandle.getAppId(Binder.getCallingUid()));
6211    }
6212
6213    /**
6214     * This can be called with or without the global lock held.
6215     */
6216    void enforceCallingPermission(String permission, String func) {
6217        if (checkCallingPermission(permission)
6218                == PackageManager.PERMISSION_GRANTED) {
6219            return;
6220        }
6221
6222        String msg = "Permission Denial: " + func + " from pid="
6223                + Binder.getCallingPid()
6224                + ", uid=" + Binder.getCallingUid()
6225                + " requires " + permission;
6226        Slog.w(TAG, msg);
6227        throw new SecurityException(msg);
6228    }
6229
6230    /**
6231     * Determine if UID is holding permissions required to access {@link Uri} in
6232     * the given {@link ProviderInfo}. Final permission checking is always done
6233     * in {@link ContentProvider}.
6234     */
6235    private final boolean checkHoldingPermissionsLocked(
6236            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6237        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6238                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6239        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6240            return false;
6241        }
6242        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6243    }
6244
6245    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6246            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6247        if (pi.applicationInfo.uid == uid) {
6248            return true;
6249        } else if (!pi.exported) {
6250            return false;
6251        }
6252
6253        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6254        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6255        try {
6256            // check if target holds top-level <provider> permissions
6257            if (!readMet && pi.readPermission != null && considerUidPermissions
6258                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6259                readMet = true;
6260            }
6261            if (!writeMet && pi.writePermission != null && considerUidPermissions
6262                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6263                writeMet = true;
6264            }
6265
6266            // track if unprotected read/write is allowed; any denied
6267            // <path-permission> below removes this ability
6268            boolean allowDefaultRead = pi.readPermission == null;
6269            boolean allowDefaultWrite = pi.writePermission == null;
6270
6271            // check if target holds any <path-permission> that match uri
6272            final PathPermission[] pps = pi.pathPermissions;
6273            if (pps != null) {
6274                final String path = grantUri.uri.getPath();
6275                int i = pps.length;
6276                while (i > 0 && (!readMet || !writeMet)) {
6277                    i--;
6278                    PathPermission pp = pps[i];
6279                    if (pp.match(path)) {
6280                        if (!readMet) {
6281                            final String pprperm = pp.getReadPermission();
6282                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6283                                    + pprperm + " for " + pp.getPath()
6284                                    + ": match=" + pp.match(path)
6285                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6286                            if (pprperm != null) {
6287                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6288                                        == PERMISSION_GRANTED) {
6289                                    readMet = true;
6290                                } else {
6291                                    allowDefaultRead = false;
6292                                }
6293                            }
6294                        }
6295                        if (!writeMet) {
6296                            final String ppwperm = pp.getWritePermission();
6297                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6298                                    + ppwperm + " for " + pp.getPath()
6299                                    + ": match=" + pp.match(path)
6300                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6301                            if (ppwperm != null) {
6302                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6303                                        == PERMISSION_GRANTED) {
6304                                    writeMet = true;
6305                                } else {
6306                                    allowDefaultWrite = false;
6307                                }
6308                            }
6309                        }
6310                    }
6311                }
6312            }
6313
6314            // grant unprotected <provider> read/write, if not blocked by
6315            // <path-permission> above
6316            if (allowDefaultRead) readMet = true;
6317            if (allowDefaultWrite) writeMet = true;
6318
6319        } catch (RemoteException e) {
6320            return false;
6321        }
6322
6323        return readMet && writeMet;
6324    }
6325
6326    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6327        ProviderInfo pi = null;
6328        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6329        if (cpr != null) {
6330            pi = cpr.info;
6331        } else {
6332            try {
6333                pi = AppGlobals.getPackageManager().resolveContentProvider(
6334                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6335            } catch (RemoteException ex) {
6336            }
6337        }
6338        return pi;
6339    }
6340
6341    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6342        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6343        if (targetUris != null) {
6344            return targetUris.get(grantUri);
6345        }
6346        return null;
6347    }
6348
6349    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6350            String targetPkg, int targetUid, GrantUri grantUri) {
6351        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6352        if (targetUris == null) {
6353            targetUris = Maps.newArrayMap();
6354            mGrantedUriPermissions.put(targetUid, targetUris);
6355        }
6356
6357        UriPermission perm = targetUris.get(grantUri);
6358        if (perm == null) {
6359            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6360            targetUris.put(grantUri, perm);
6361        }
6362
6363        return perm;
6364    }
6365
6366    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6367            final int modeFlags) {
6368        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6369        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6370                : UriPermission.STRENGTH_OWNED;
6371
6372        // Root gets to do everything.
6373        if (uid == 0) {
6374            return true;
6375        }
6376
6377        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6378        if (perms == null) return false;
6379
6380        // First look for exact match
6381        final UriPermission exactPerm = perms.get(grantUri);
6382        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6383            return true;
6384        }
6385
6386        // No exact match, look for prefixes
6387        final int N = perms.size();
6388        for (int i = 0; i < N; i++) {
6389            final UriPermission perm = perms.valueAt(i);
6390            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6391                    && perm.getStrength(modeFlags) >= minStrength) {
6392                return true;
6393            }
6394        }
6395
6396        return false;
6397    }
6398
6399    @Override
6400    public int checkUriPermission(Uri uri, int pid, int uid,
6401            final int modeFlags, int userId) {
6402        enforceNotIsolatedCaller("checkUriPermission");
6403
6404        // Another redirected-binder-call permissions check as in
6405        // {@link checkComponentPermission}.
6406        Identity tlsIdentity = sCallerIdentity.get();
6407        if (tlsIdentity != null) {
6408            uid = tlsIdentity.uid;
6409            pid = tlsIdentity.pid;
6410        }
6411
6412        // Our own process gets to do everything.
6413        if (pid == MY_PID) {
6414            return PackageManager.PERMISSION_GRANTED;
6415        }
6416        synchronized (this) {
6417            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6418                    ? PackageManager.PERMISSION_GRANTED
6419                    : PackageManager.PERMISSION_DENIED;
6420        }
6421    }
6422
6423    /**
6424     * Check if the targetPkg can be granted permission to access uri by
6425     * the callingUid using the given modeFlags.  Throws a security exception
6426     * if callingUid is not allowed to do this.  Returns the uid of the target
6427     * if the URI permission grant should be performed; returns -1 if it is not
6428     * needed (for example targetPkg already has permission to access the URI).
6429     * If you already know the uid of the target, you can supply it in
6430     * lastTargetUid else set that to -1.
6431     */
6432    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6433            final int modeFlags, int lastTargetUid) {
6434        if (!Intent.isAccessUriMode(modeFlags)) {
6435            return -1;
6436        }
6437
6438        if (targetPkg != null) {
6439            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6440                    "Checking grant " + targetPkg + " permission to " + grantUri);
6441        }
6442
6443        final IPackageManager pm = AppGlobals.getPackageManager();
6444
6445        // If this is not a content: uri, we can't do anything with it.
6446        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6447            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6448                    "Can't grant URI permission for non-content URI: " + grantUri);
6449            return -1;
6450        }
6451
6452        final String authority = grantUri.uri.getAuthority();
6453        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6454        if (pi == null) {
6455            Slog.w(TAG, "No content provider found for permission check: " +
6456                    grantUri.uri.toSafeString());
6457            return -1;
6458        }
6459
6460        int targetUid = lastTargetUid;
6461        if (targetUid < 0 && targetPkg != null) {
6462            try {
6463                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6464                if (targetUid < 0) {
6465                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6466                            "Can't grant URI permission no uid for: " + targetPkg);
6467                    return -1;
6468                }
6469            } catch (RemoteException ex) {
6470                return -1;
6471            }
6472        }
6473
6474        if (targetUid >= 0) {
6475            // First...  does the target actually need this permission?
6476            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6477                // No need to grant the target this permission.
6478                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6479                        "Target " + targetPkg + " already has full permission to " + grantUri);
6480                return -1;
6481            }
6482        } else {
6483            // First...  there is no target package, so can anyone access it?
6484            boolean allowed = pi.exported;
6485            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6486                if (pi.readPermission != null) {
6487                    allowed = false;
6488                }
6489            }
6490            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6491                if (pi.writePermission != null) {
6492                    allowed = false;
6493                }
6494            }
6495            if (allowed) {
6496                return -1;
6497            }
6498        }
6499
6500        /* There is a special cross user grant if:
6501         * - The target is on another user.
6502         * - Apps on the current user can access the uri without any uid permissions.
6503         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6504         * grant uri permissions.
6505         */
6506        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6507                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6508                modeFlags, false /*without considering the uid permissions*/);
6509
6510        // Second...  is the provider allowing granting of URI permissions?
6511        if (!specialCrossUserGrant) {
6512            if (!pi.grantUriPermissions) {
6513                throw new SecurityException("Provider " + pi.packageName
6514                        + "/" + pi.name
6515                        + " does not allow granting of Uri permissions (uri "
6516                        + grantUri + ")");
6517            }
6518            if (pi.uriPermissionPatterns != null) {
6519                final int N = pi.uriPermissionPatterns.length;
6520                boolean allowed = false;
6521                for (int i=0; i<N; i++) {
6522                    if (pi.uriPermissionPatterns[i] != null
6523                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6524                        allowed = true;
6525                        break;
6526                    }
6527                }
6528                if (!allowed) {
6529                    throw new SecurityException("Provider " + pi.packageName
6530                            + "/" + pi.name
6531                            + " does not allow granting of permission to path of Uri "
6532                            + grantUri);
6533                }
6534            }
6535        }
6536
6537        // Third...  does the caller itself have permission to access
6538        // this uri?
6539        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6540            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6541                // Require they hold a strong enough Uri permission
6542                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6543                    throw new SecurityException("Uid " + callingUid
6544                            + " does not have permission to uri " + grantUri);
6545                }
6546            }
6547        }
6548        return targetUid;
6549    }
6550
6551    @Override
6552    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6553            final int modeFlags, int userId) {
6554        enforceNotIsolatedCaller("checkGrantUriPermission");
6555        synchronized(this) {
6556            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6557                    new GrantUri(userId, uri, false), modeFlags, -1);
6558        }
6559    }
6560
6561    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6562            final int modeFlags, UriPermissionOwner owner) {
6563        if (!Intent.isAccessUriMode(modeFlags)) {
6564            return;
6565        }
6566
6567        // So here we are: the caller has the assumed permission
6568        // to the uri, and the target doesn't.  Let's now give this to
6569        // the target.
6570
6571        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6572                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6573
6574        final String authority = grantUri.uri.getAuthority();
6575        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6576        if (pi == null) {
6577            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6578            return;
6579        }
6580
6581        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6582            grantUri.prefix = true;
6583        }
6584        final UriPermission perm = findOrCreateUriPermissionLocked(
6585                pi.packageName, targetPkg, targetUid, grantUri);
6586        perm.grantModes(modeFlags, owner);
6587    }
6588
6589    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6590            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6591        if (targetPkg == null) {
6592            throw new NullPointerException("targetPkg");
6593        }
6594        int targetUid;
6595        final IPackageManager pm = AppGlobals.getPackageManager();
6596        try {
6597            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6598        } catch (RemoteException ex) {
6599            return;
6600        }
6601
6602        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6603                targetUid);
6604        if (targetUid < 0) {
6605            return;
6606        }
6607
6608        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6609                owner);
6610    }
6611
6612    static class NeededUriGrants extends ArrayList<GrantUri> {
6613        final String targetPkg;
6614        final int targetUid;
6615        final int flags;
6616
6617        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6618            this.targetPkg = targetPkg;
6619            this.targetUid = targetUid;
6620            this.flags = flags;
6621        }
6622    }
6623
6624    /**
6625     * Like checkGrantUriPermissionLocked, but takes an Intent.
6626     */
6627    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6628            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6629        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6630                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6631                + " clip=" + (intent != null ? intent.getClipData() : null)
6632                + " from " + intent + "; flags=0x"
6633                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6634
6635        if (targetPkg == null) {
6636            throw new NullPointerException("targetPkg");
6637        }
6638
6639        if (intent == null) {
6640            return null;
6641        }
6642        Uri data = intent.getData();
6643        ClipData clip = intent.getClipData();
6644        if (data == null && clip == null) {
6645            return null;
6646        }
6647        final IPackageManager pm = AppGlobals.getPackageManager();
6648        int targetUid;
6649        if (needed != null) {
6650            targetUid = needed.targetUid;
6651        } else {
6652            try {
6653                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6654            } catch (RemoteException ex) {
6655                return null;
6656            }
6657            if (targetUid < 0) {
6658                if (DEBUG_URI_PERMISSION) {
6659                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6660                            + " on user " + targetUserId);
6661                }
6662                return null;
6663            }
6664        }
6665        if (data != null) {
6666            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6667            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6668                    targetUid);
6669            if (targetUid > 0) {
6670                if (needed == null) {
6671                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6672                }
6673                needed.add(grantUri);
6674            }
6675        }
6676        if (clip != null) {
6677            for (int i=0; i<clip.getItemCount(); i++) {
6678                Uri uri = clip.getItemAt(i).getUri();
6679                if (uri != null) {
6680                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6681                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6682                            targetUid);
6683                    if (targetUid > 0) {
6684                        if (needed == null) {
6685                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6686                        }
6687                        needed.add(grantUri);
6688                    }
6689                } else {
6690                    Intent clipIntent = clip.getItemAt(i).getIntent();
6691                    if (clipIntent != null) {
6692                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6693                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6694                        if (newNeeded != null) {
6695                            needed = newNeeded;
6696                        }
6697                    }
6698                }
6699            }
6700        }
6701
6702        return needed;
6703    }
6704
6705    /**
6706     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6707     */
6708    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6709            UriPermissionOwner owner) {
6710        if (needed != null) {
6711            for (int i=0; i<needed.size(); i++) {
6712                GrantUri grantUri = needed.get(i);
6713                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6714                        grantUri, needed.flags, owner);
6715            }
6716        }
6717    }
6718
6719    void grantUriPermissionFromIntentLocked(int callingUid,
6720            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6721        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6722                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6723        if (needed == null) {
6724            return;
6725        }
6726
6727        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6728    }
6729
6730    @Override
6731    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6732            final int modeFlags, int userId) {
6733        enforceNotIsolatedCaller("grantUriPermission");
6734        GrantUri grantUri = new GrantUri(userId, uri, false);
6735        synchronized(this) {
6736            final ProcessRecord r = getRecordForAppLocked(caller);
6737            if (r == null) {
6738                throw new SecurityException("Unable to find app for caller "
6739                        + caller
6740                        + " when granting permission to uri " + grantUri);
6741            }
6742            if (targetPkg == null) {
6743                throw new IllegalArgumentException("null target");
6744            }
6745            if (grantUri == null) {
6746                throw new IllegalArgumentException("null uri");
6747            }
6748
6749            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6750                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6751                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6752                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6753
6754            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6755                    UserHandle.getUserId(r.uid));
6756        }
6757    }
6758
6759    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6760        if (perm.modeFlags == 0) {
6761            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6762                    perm.targetUid);
6763            if (perms != null) {
6764                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6765                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6766
6767                perms.remove(perm.uri);
6768                if (perms.isEmpty()) {
6769                    mGrantedUriPermissions.remove(perm.targetUid);
6770                }
6771            }
6772        }
6773    }
6774
6775    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6776        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6777
6778        final IPackageManager pm = AppGlobals.getPackageManager();
6779        final String authority = grantUri.uri.getAuthority();
6780        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6781        if (pi == null) {
6782            Slog.w(TAG, "No content provider found for permission revoke: "
6783                    + grantUri.toSafeString());
6784            return;
6785        }
6786
6787        // Does the caller have this permission on the URI?
6788        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6789            // Right now, if you are not the original owner of the permission,
6790            // you are not allowed to revoke it.
6791            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6792                throw new SecurityException("Uid " + callingUid
6793                        + " does not have permission to uri " + grantUri);
6794            //}
6795        }
6796
6797        boolean persistChanged = false;
6798
6799        // Go through all of the permissions and remove any that match.
6800        int N = mGrantedUriPermissions.size();
6801        for (int i = 0; i < N; i++) {
6802            final int targetUid = mGrantedUriPermissions.keyAt(i);
6803            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6804
6805            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6806                final UriPermission perm = it.next();
6807                if (perm.uri.sourceUserId == grantUri.sourceUserId
6808                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6809                    if (DEBUG_URI_PERMISSION)
6810                        Slog.v(TAG,
6811                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6812                    persistChanged |= perm.revokeModes(
6813                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6814                    if (perm.modeFlags == 0) {
6815                        it.remove();
6816                    }
6817                }
6818            }
6819
6820            if (perms.isEmpty()) {
6821                mGrantedUriPermissions.remove(targetUid);
6822                N--;
6823                i--;
6824            }
6825        }
6826
6827        if (persistChanged) {
6828            schedulePersistUriGrants();
6829        }
6830    }
6831
6832    @Override
6833    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6834            int userId) {
6835        enforceNotIsolatedCaller("revokeUriPermission");
6836        synchronized(this) {
6837            final ProcessRecord r = getRecordForAppLocked(caller);
6838            if (r == null) {
6839                throw new SecurityException("Unable to find app for caller "
6840                        + caller
6841                        + " when revoking permission to uri " + uri);
6842            }
6843            if (uri == null) {
6844                Slog.w(TAG, "revokeUriPermission: null uri");
6845                return;
6846            }
6847
6848            if (!Intent.isAccessUriMode(modeFlags)) {
6849                return;
6850            }
6851
6852            final IPackageManager pm = AppGlobals.getPackageManager();
6853            final String authority = uri.getAuthority();
6854            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6855            if (pi == null) {
6856                Slog.w(TAG, "No content provider found for permission revoke: "
6857                        + uri.toSafeString());
6858                return;
6859            }
6860
6861            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6862        }
6863    }
6864
6865    /**
6866     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6867     * given package.
6868     *
6869     * @param packageName Package name to match, or {@code null} to apply to all
6870     *            packages.
6871     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6872     *            to all users.
6873     * @param persistable If persistable grants should be removed.
6874     */
6875    private void removeUriPermissionsForPackageLocked(
6876            String packageName, int userHandle, boolean persistable) {
6877        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6878            throw new IllegalArgumentException("Must narrow by either package or user");
6879        }
6880
6881        boolean persistChanged = false;
6882
6883        int N = mGrantedUriPermissions.size();
6884        for (int i = 0; i < N; i++) {
6885            final int targetUid = mGrantedUriPermissions.keyAt(i);
6886            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6887
6888            // Only inspect grants matching user
6889            if (userHandle == UserHandle.USER_ALL
6890                    || userHandle == UserHandle.getUserId(targetUid)) {
6891                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6892                    final UriPermission perm = it.next();
6893
6894                    // Only inspect grants matching package
6895                    if (packageName == null || perm.sourcePkg.equals(packageName)
6896                            || perm.targetPkg.equals(packageName)) {
6897                        persistChanged |= perm.revokeModes(
6898                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6899
6900                        // Only remove when no modes remain; any persisted grants
6901                        // will keep this alive.
6902                        if (perm.modeFlags == 0) {
6903                            it.remove();
6904                        }
6905                    }
6906                }
6907
6908                if (perms.isEmpty()) {
6909                    mGrantedUriPermissions.remove(targetUid);
6910                    N--;
6911                    i--;
6912                }
6913            }
6914        }
6915
6916        if (persistChanged) {
6917            schedulePersistUriGrants();
6918        }
6919    }
6920
6921    @Override
6922    public IBinder newUriPermissionOwner(String name) {
6923        enforceNotIsolatedCaller("newUriPermissionOwner");
6924        synchronized(this) {
6925            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6926            return owner.getExternalTokenLocked();
6927        }
6928    }
6929
6930    @Override
6931    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6932            final int modeFlags, int sourceUserId, int targetUserId) {
6933        synchronized(this) {
6934            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6935            if (owner == null) {
6936                throw new IllegalArgumentException("Unknown owner: " + token);
6937            }
6938            if (fromUid != Binder.getCallingUid()) {
6939                if (Binder.getCallingUid() != Process.myUid()) {
6940                    // Only system code can grant URI permissions on behalf
6941                    // of other users.
6942                    throw new SecurityException("nice try");
6943                }
6944            }
6945            if (targetPkg == null) {
6946                throw new IllegalArgumentException("null target");
6947            }
6948            if (uri == null) {
6949                throw new IllegalArgumentException("null uri");
6950            }
6951
6952            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6953                    modeFlags, owner, targetUserId);
6954        }
6955    }
6956
6957    @Override
6958    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6959        synchronized(this) {
6960            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6961            if (owner == null) {
6962                throw new IllegalArgumentException("Unknown owner: " + token);
6963            }
6964
6965            if (uri == null) {
6966                owner.removeUriPermissionsLocked(mode);
6967            } else {
6968                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6969            }
6970        }
6971    }
6972
6973    private void schedulePersistUriGrants() {
6974        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6975            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6976                    10 * DateUtils.SECOND_IN_MILLIS);
6977        }
6978    }
6979
6980    private void writeGrantedUriPermissions() {
6981        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6982
6983        // Snapshot permissions so we can persist without lock
6984        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6985        synchronized (this) {
6986            final int size = mGrantedUriPermissions.size();
6987            for (int i = 0; i < size; i++) {
6988                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6989                for (UriPermission perm : perms.values()) {
6990                    if (perm.persistedModeFlags != 0) {
6991                        persist.add(perm.snapshot());
6992                    }
6993                }
6994            }
6995        }
6996
6997        FileOutputStream fos = null;
6998        try {
6999            fos = mGrantFile.startWrite();
7000
7001            XmlSerializer out = new FastXmlSerializer();
7002            out.setOutput(fos, "utf-8");
7003            out.startDocument(null, true);
7004            out.startTag(null, TAG_URI_GRANTS);
7005            for (UriPermission.Snapshot perm : persist) {
7006                out.startTag(null, TAG_URI_GRANT);
7007                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7008                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7009                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7010                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7011                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7012                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7013                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7014                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7015                out.endTag(null, TAG_URI_GRANT);
7016            }
7017            out.endTag(null, TAG_URI_GRANTS);
7018            out.endDocument();
7019
7020            mGrantFile.finishWrite(fos);
7021        } catch (IOException e) {
7022            if (fos != null) {
7023                mGrantFile.failWrite(fos);
7024            }
7025        }
7026    }
7027
7028    private void readGrantedUriPermissionsLocked() {
7029        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7030
7031        final long now = System.currentTimeMillis();
7032
7033        FileInputStream fis = null;
7034        try {
7035            fis = mGrantFile.openRead();
7036            final XmlPullParser in = Xml.newPullParser();
7037            in.setInput(fis, null);
7038
7039            int type;
7040            while ((type = in.next()) != END_DOCUMENT) {
7041                final String tag = in.getName();
7042                if (type == START_TAG) {
7043                    if (TAG_URI_GRANT.equals(tag)) {
7044                        final int sourceUserId;
7045                        final int targetUserId;
7046                        final int userHandle = readIntAttribute(in,
7047                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7048                        if (userHandle != UserHandle.USER_NULL) {
7049                            // For backwards compatibility.
7050                            sourceUserId = userHandle;
7051                            targetUserId = userHandle;
7052                        } else {
7053                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7054                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7055                        }
7056                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7057                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7058                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7059                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7060                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7061                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7062
7063                        // Sanity check that provider still belongs to source package
7064                        final ProviderInfo pi = getProviderInfoLocked(
7065                                uri.getAuthority(), sourceUserId);
7066                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7067                            int targetUid = -1;
7068                            try {
7069                                targetUid = AppGlobals.getPackageManager()
7070                                        .getPackageUid(targetPkg, targetUserId);
7071                            } catch (RemoteException e) {
7072                            }
7073                            if (targetUid != -1) {
7074                                final UriPermission perm = findOrCreateUriPermissionLocked(
7075                                        sourcePkg, targetPkg, targetUid,
7076                                        new GrantUri(sourceUserId, uri, prefix));
7077                                perm.initPersistedModes(modeFlags, createdTime);
7078                            }
7079                        } else {
7080                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7081                                    + " but instead found " + pi);
7082                        }
7083                    }
7084                }
7085            }
7086        } catch (FileNotFoundException e) {
7087            // Missing grants is okay
7088        } catch (IOException e) {
7089            Log.wtf(TAG, "Failed reading Uri grants", e);
7090        } catch (XmlPullParserException e) {
7091            Log.wtf(TAG, "Failed reading Uri grants", e);
7092        } finally {
7093            IoUtils.closeQuietly(fis);
7094        }
7095    }
7096
7097    @Override
7098    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7099        enforceNotIsolatedCaller("takePersistableUriPermission");
7100
7101        Preconditions.checkFlagsArgument(modeFlags,
7102                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7103
7104        synchronized (this) {
7105            final int callingUid = Binder.getCallingUid();
7106            boolean persistChanged = false;
7107            GrantUri grantUri = new GrantUri(userId, uri, false);
7108
7109            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7110                    new GrantUri(userId, uri, false));
7111            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7112                    new GrantUri(userId, uri, true));
7113
7114            final boolean exactValid = (exactPerm != null)
7115                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7116            final boolean prefixValid = (prefixPerm != null)
7117                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7118
7119            if (!(exactValid || prefixValid)) {
7120                throw new SecurityException("No persistable permission grants found for UID "
7121                        + callingUid + " and Uri " + grantUri.toSafeString());
7122            }
7123
7124            if (exactValid) {
7125                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7126            }
7127            if (prefixValid) {
7128                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7129            }
7130
7131            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7132
7133            if (persistChanged) {
7134                schedulePersistUriGrants();
7135            }
7136        }
7137    }
7138
7139    @Override
7140    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7141        enforceNotIsolatedCaller("releasePersistableUriPermission");
7142
7143        Preconditions.checkFlagsArgument(modeFlags,
7144                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7145
7146        synchronized (this) {
7147            final int callingUid = Binder.getCallingUid();
7148            boolean persistChanged = false;
7149
7150            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7151                    new GrantUri(userId, uri, false));
7152            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7153                    new GrantUri(userId, uri, true));
7154            if (exactPerm == null && prefixPerm == null) {
7155                throw new SecurityException("No permission grants found for UID " + callingUid
7156                        + " and Uri " + uri.toSafeString());
7157            }
7158
7159            if (exactPerm != null) {
7160                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7161                removeUriPermissionIfNeededLocked(exactPerm);
7162            }
7163            if (prefixPerm != null) {
7164                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7165                removeUriPermissionIfNeededLocked(prefixPerm);
7166            }
7167
7168            if (persistChanged) {
7169                schedulePersistUriGrants();
7170            }
7171        }
7172    }
7173
7174    /**
7175     * Prune any older {@link UriPermission} for the given UID until outstanding
7176     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7177     *
7178     * @return if any mutations occured that require persisting.
7179     */
7180    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7181        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7182        if (perms == null) return false;
7183        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7184
7185        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7186        for (UriPermission perm : perms.values()) {
7187            if (perm.persistedModeFlags != 0) {
7188                persisted.add(perm);
7189            }
7190        }
7191
7192        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7193        if (trimCount <= 0) return false;
7194
7195        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7196        for (int i = 0; i < trimCount; i++) {
7197            final UriPermission perm = persisted.get(i);
7198
7199            if (DEBUG_URI_PERMISSION) {
7200                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7201            }
7202
7203            perm.releasePersistableModes(~0);
7204            removeUriPermissionIfNeededLocked(perm);
7205        }
7206
7207        return true;
7208    }
7209
7210    @Override
7211    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7212            String packageName, boolean incoming) {
7213        enforceNotIsolatedCaller("getPersistedUriPermissions");
7214        Preconditions.checkNotNull(packageName, "packageName");
7215
7216        final int callingUid = Binder.getCallingUid();
7217        final IPackageManager pm = AppGlobals.getPackageManager();
7218        try {
7219            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7220            if (packageUid != callingUid) {
7221                throw new SecurityException(
7222                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7223            }
7224        } catch (RemoteException e) {
7225            throw new SecurityException("Failed to verify package name ownership");
7226        }
7227
7228        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7229        synchronized (this) {
7230            if (incoming) {
7231                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7232                        callingUid);
7233                if (perms == null) {
7234                    Slog.w(TAG, "No permission grants found for " + packageName);
7235                } else {
7236                    for (UriPermission perm : perms.values()) {
7237                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7238                            result.add(perm.buildPersistedPublicApiObject());
7239                        }
7240                    }
7241                }
7242            } else {
7243                final int size = mGrantedUriPermissions.size();
7244                for (int i = 0; i < size; i++) {
7245                    final ArrayMap<GrantUri, UriPermission> perms =
7246                            mGrantedUriPermissions.valueAt(i);
7247                    for (UriPermission perm : perms.values()) {
7248                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7249                            result.add(perm.buildPersistedPublicApiObject());
7250                        }
7251                    }
7252                }
7253            }
7254        }
7255        return new ParceledListSlice<android.content.UriPermission>(result);
7256    }
7257
7258    @Override
7259    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7260        synchronized (this) {
7261            ProcessRecord app =
7262                who != null ? getRecordForAppLocked(who) : null;
7263            if (app == null) return;
7264
7265            Message msg = Message.obtain();
7266            msg.what = WAIT_FOR_DEBUGGER_MSG;
7267            msg.obj = app;
7268            msg.arg1 = waiting ? 1 : 0;
7269            mHandler.sendMessage(msg);
7270        }
7271    }
7272
7273    @Override
7274    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7275        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7276        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7277        outInfo.availMem = Process.getFreeMemory();
7278        outInfo.totalMem = Process.getTotalMemory();
7279        outInfo.threshold = homeAppMem;
7280        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7281        outInfo.hiddenAppThreshold = cachedAppMem;
7282        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7283                ProcessList.SERVICE_ADJ);
7284        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7285                ProcessList.VISIBLE_APP_ADJ);
7286        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7287                ProcessList.FOREGROUND_APP_ADJ);
7288    }
7289
7290    // =========================================================
7291    // TASK MANAGEMENT
7292    // =========================================================
7293
7294    @Override
7295    public List<IAppTask> getAppTasks() {
7296        final PackageManager pm = mContext.getPackageManager();
7297        int callingUid = Binder.getCallingUid();
7298        long ident = Binder.clearCallingIdentity();
7299
7300        // Compose the list of packages for this id to test against
7301        HashSet<String> packages = new HashSet<String>();
7302        String[] uidPackages = pm.getPackagesForUid(callingUid);
7303        for (int i = 0; i < uidPackages.length; i++) {
7304            packages.add(uidPackages[i]);
7305        }
7306
7307        synchronized(this) {
7308            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7309            try {
7310                if (localLOGV) Slog.v(TAG, "getAppTasks");
7311
7312                final int N = mRecentTasks.size();
7313                for (int i = 0; i < N; i++) {
7314                    TaskRecord tr = mRecentTasks.get(i);
7315                    // Skip tasks that are not created by the caller
7316                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7317                        ActivityManager.RecentTaskInfo taskInfo =
7318                                createRecentTaskInfoFromTaskRecord(tr);
7319                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7320                        list.add(taskImpl);
7321                    }
7322                }
7323            } finally {
7324                Binder.restoreCallingIdentity(ident);
7325            }
7326            return list;
7327        }
7328    }
7329
7330    @Override
7331    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7332        final int callingUid = Binder.getCallingUid();
7333        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7334
7335        synchronized(this) {
7336            if (localLOGV) Slog.v(
7337                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7338
7339            final boolean allowed = checkCallingPermission(
7340                    android.Manifest.permission.GET_TASKS)
7341                    == PackageManager.PERMISSION_GRANTED;
7342            if (!allowed) {
7343                Slog.w(TAG, "getTasks: caller " + callingUid
7344                        + " does not hold GET_TASKS; limiting output");
7345            }
7346
7347            // TODO: Improve with MRU list from all ActivityStacks.
7348            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7349        }
7350
7351        return list;
7352    }
7353
7354    TaskRecord getMostRecentTask() {
7355        return mRecentTasks.get(0);
7356    }
7357
7358    /**
7359     * Creates a new RecentTaskInfo from a TaskRecord.
7360     */
7361    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7362        // Update the task description to reflect any changes in the task stack
7363        tr.updateTaskDescription();
7364
7365        // Compose the recent task info
7366        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7367        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7368        rti.persistentId = tr.taskId;
7369        rti.baseIntent = new Intent(tr.getBaseIntent());
7370        rti.origActivity = tr.origActivity;
7371        rti.description = tr.lastDescription;
7372        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7373        rti.userId = tr.userId;
7374        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7375        rti.firstActiveTime = tr.firstActiveTime;
7376        rti.lastActiveTime = tr.lastActiveTime;
7377        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7378        return rti;
7379    }
7380
7381    @Override
7382    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7383        final int callingUid = Binder.getCallingUid();
7384        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7385                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7386
7387        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7388        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7389        synchronized (this) {
7390            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7391                    == PackageManager.PERMISSION_GRANTED;
7392            if (!allowed) {
7393                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7394                        + " does not hold GET_TASKS; limiting output");
7395            }
7396            final boolean detailed = checkCallingPermission(
7397                    android.Manifest.permission.GET_DETAILED_TASKS)
7398                    == PackageManager.PERMISSION_GRANTED;
7399
7400            IPackageManager pm = AppGlobals.getPackageManager();
7401
7402            final int N = mRecentTasks.size();
7403            ArrayList<ActivityManager.RecentTaskInfo> res
7404                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7405                            maxNum < N ? maxNum : N);
7406
7407            final Set<Integer> includedUsers;
7408            if (includeProfiles) {
7409                includedUsers = getProfileIdsLocked(userId);
7410            } else {
7411                includedUsers = new HashSet<Integer>();
7412            }
7413            includedUsers.add(Integer.valueOf(userId));
7414
7415            // Regroup affiliated tasks together.
7416            for (int i = 0; i < N; ) {
7417                TaskRecord task = mRecentTasks.remove(i);
7418                if (mTmpRecents.contains(task)) {
7419                    continue;
7420                }
7421                int affiliatedTaskId = task.mAffiliatedTaskId;
7422                while (true) {
7423                    TaskRecord next = task.mNextAffiliate;
7424                    if (next == null) {
7425                        break;
7426                    }
7427                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7428                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7429                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7430                        task.setNextAffiliate(null);
7431                        if (next.mPrevAffiliate == task) {
7432                            next.setPrevAffiliate(null);
7433                        }
7434                        break;
7435                    }
7436                    if (next.mPrevAffiliate != task) {
7437                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7438                                next.mPrevAffiliate + " task=" + task);
7439                        next.setPrevAffiliate(null);
7440                        break;
7441                    }
7442                    if (!mRecentTasks.contains(next)) {
7443                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7444                        task.setNextAffiliate(null);
7445                        if (next.mPrevAffiliate == task) {
7446                            next.setPrevAffiliate(null);
7447                        }
7448                        break;
7449                    }
7450                    task = next;
7451                }
7452                // task is now the end of the list
7453                do {
7454                    mRecentTasks.remove(task);
7455                    mRecentTasks.add(i++, task);
7456                    mTmpRecents.add(task);
7457                } while ((task = task.mPrevAffiliate) != null);
7458            }
7459            mTmpRecents.clear();
7460            // mRecentTasks is now in sorted, affiliated order.
7461
7462            for (int i=0; i<N && maxNum > 0; i++) {
7463                TaskRecord tr = mRecentTasks.get(i);
7464                // Only add calling user or related users recent tasks
7465                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7466
7467                // Return the entry if desired by the caller.  We always return
7468                // the first entry, because callers always expect this to be the
7469                // foreground app.  We may filter others if the caller has
7470                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7471                // we should exclude the entry.
7472
7473                if (i == 0
7474                        || withExcluded
7475                        || (tr.intent == null)
7476                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7477                                == 0)) {
7478                    if (!allowed) {
7479                        // If the caller doesn't have the GET_TASKS permission, then only
7480                        // allow them to see a small subset of tasks -- their own and home.
7481                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7482                            continue;
7483                        }
7484                    }
7485                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7486                        // Don't include auto remove tasks that are finished or finishing.
7487                        continue;
7488                    }
7489
7490                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7491                    if (!detailed) {
7492                        rti.baseIntent.replaceExtras((Bundle)null);
7493                    }
7494
7495                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7496                        // Check whether this activity is currently available.
7497                        try {
7498                            if (rti.origActivity != null) {
7499                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7500                                        == null) {
7501                                    continue;
7502                                }
7503                            } else if (rti.baseIntent != null) {
7504                                if (pm.queryIntentActivities(rti.baseIntent,
7505                                        null, 0, userId) == null) {
7506                                    continue;
7507                                }
7508                            }
7509                        } catch (RemoteException e) {
7510                            // Will never happen.
7511                        }
7512                    }
7513
7514                    res.add(rti);
7515                    maxNum--;
7516                }
7517            }
7518            return res;
7519        }
7520    }
7521
7522    private TaskRecord recentTaskForIdLocked(int id) {
7523        final int N = mRecentTasks.size();
7524            for (int i=0; i<N; i++) {
7525                TaskRecord tr = mRecentTasks.get(i);
7526                if (tr.taskId == id) {
7527                    return tr;
7528                }
7529            }
7530            return null;
7531    }
7532
7533    @Override
7534    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7535        synchronized (this) {
7536            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7537                    "getTaskThumbnail()");
7538            TaskRecord tr = recentTaskForIdLocked(id);
7539            if (tr != null) {
7540                return tr.getTaskThumbnailLocked();
7541            }
7542        }
7543        return null;
7544    }
7545
7546    @Override
7547    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7548        synchronized (this) {
7549            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7550            if (r != null) {
7551                r.taskDescription = td;
7552                r.task.updateTaskDescription();
7553            }
7554        }
7555    }
7556
7557    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7558        if (!pr.killedByAm) {
7559            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7560            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7561                    pr.processName, pr.setAdj, reason);
7562            pr.killedByAm = true;
7563            Process.killProcessQuiet(pr.pid);
7564            Process.killProcessGroup(pr.info.uid, pr.pid);
7565        }
7566    }
7567
7568    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7569        tr.disposeThumbnail();
7570        mRecentTasks.remove(tr);
7571        tr.closeRecentsChain();
7572        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7573        Intent baseIntent = new Intent(
7574                tr.intent != null ? tr.intent : tr.affinityIntent);
7575        ComponentName component = baseIntent.getComponent();
7576        if (component == null) {
7577            Slog.w(TAG, "Now component for base intent of task: " + tr);
7578            return;
7579        }
7580
7581        // Find any running services associated with this app.
7582        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7583
7584        if (killProcesses) {
7585            // Find any running processes associated with this app.
7586            final String pkg = component.getPackageName();
7587            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7588            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7589            for (int i=0; i<pmap.size(); i++) {
7590                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7591                for (int j=0; j<uids.size(); j++) {
7592                    ProcessRecord proc = uids.valueAt(j);
7593                    if (proc.userId != tr.userId) {
7594                        continue;
7595                    }
7596                    if (!proc.pkgList.containsKey(pkg)) {
7597                        continue;
7598                    }
7599                    procs.add(proc);
7600                }
7601            }
7602
7603            // Kill the running processes.
7604            for (int i=0; i<procs.size(); i++) {
7605                ProcessRecord pr = procs.get(i);
7606                if (pr == mHomeProcess) {
7607                    // Don't kill the home process along with tasks from the same package.
7608                    continue;
7609                }
7610                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7611                    killUnneededProcessLocked(pr, "remove task");
7612                } else {
7613                    pr.waitingToKill = "remove task";
7614                }
7615            }
7616        }
7617    }
7618
7619    /**
7620     * Removes the task with the specified task id.
7621     *
7622     * @param taskId Identifier of the task to be removed.
7623     * @param flags Additional operational flags.  May be 0 or
7624     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7625     * @return Returns true if the given task was found and removed.
7626     */
7627    private boolean removeTaskByIdLocked(int taskId, int flags) {
7628        TaskRecord tr = recentTaskForIdLocked(taskId);
7629        if (tr != null) {
7630            tr.removeTaskActivitiesLocked();
7631            cleanUpRemovedTaskLocked(tr, flags);
7632            if (tr.isPersistable) {
7633                notifyTaskPersisterLocked(tr, true);
7634            }
7635            return true;
7636        }
7637        return false;
7638    }
7639
7640    @Override
7641    public boolean removeTask(int taskId, int flags) {
7642        synchronized (this) {
7643            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7644                    "removeTask()");
7645            long ident = Binder.clearCallingIdentity();
7646            try {
7647                return removeTaskByIdLocked(taskId, flags);
7648            } finally {
7649                Binder.restoreCallingIdentity(ident);
7650            }
7651        }
7652    }
7653
7654    /**
7655     * TODO: Add mController hook
7656     */
7657    @Override
7658    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7659        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7660                "moveTaskToFront()");
7661
7662        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7663        synchronized(this) {
7664            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7665                    Binder.getCallingUid(), "Task to front")) {
7666                ActivityOptions.abort(options);
7667                return;
7668            }
7669            final long origId = Binder.clearCallingIdentity();
7670            try {
7671                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7672                if (task == null) {
7673                    return;
7674                }
7675                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7676                    mStackSupervisor.showLockTaskToast();
7677                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7678                    return;
7679                }
7680                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7681                if (prev != null && prev.isRecentsActivity()) {
7682                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7683                }
7684                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7685            } finally {
7686                Binder.restoreCallingIdentity(origId);
7687            }
7688            ActivityOptions.abort(options);
7689        }
7690    }
7691
7692    @Override
7693    public void moveTaskToBack(int taskId) {
7694        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7695                "moveTaskToBack()");
7696
7697        synchronized(this) {
7698            TaskRecord tr = recentTaskForIdLocked(taskId);
7699            if (tr != null) {
7700                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7701                ActivityStack stack = tr.stack;
7702                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7703                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7704                            Binder.getCallingUid(), "Task to back")) {
7705                        return;
7706                    }
7707                }
7708                final long origId = Binder.clearCallingIdentity();
7709                try {
7710                    stack.moveTaskToBackLocked(taskId, null);
7711                } finally {
7712                    Binder.restoreCallingIdentity(origId);
7713                }
7714            }
7715        }
7716    }
7717
7718    /**
7719     * Moves an activity, and all of the other activities within the same task, to the bottom
7720     * of the history stack.  The activity's order within the task is unchanged.
7721     *
7722     * @param token A reference to the activity we wish to move
7723     * @param nonRoot If false then this only works if the activity is the root
7724     *                of a task; if true it will work for any activity in a task.
7725     * @return Returns true if the move completed, false if not.
7726     */
7727    @Override
7728    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7729        enforceNotIsolatedCaller("moveActivityTaskToBack");
7730        synchronized(this) {
7731            final long origId = Binder.clearCallingIdentity();
7732            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7733            if (taskId >= 0) {
7734                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7735            }
7736            Binder.restoreCallingIdentity(origId);
7737        }
7738        return false;
7739    }
7740
7741    @Override
7742    public void moveTaskBackwards(int task) {
7743        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7744                "moveTaskBackwards()");
7745
7746        synchronized(this) {
7747            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7748                    Binder.getCallingUid(), "Task backwards")) {
7749                return;
7750            }
7751            final long origId = Binder.clearCallingIdentity();
7752            moveTaskBackwardsLocked(task);
7753            Binder.restoreCallingIdentity(origId);
7754        }
7755    }
7756
7757    private final void moveTaskBackwardsLocked(int task) {
7758        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7759    }
7760
7761    @Override
7762    public IBinder getHomeActivityToken() throws RemoteException {
7763        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7764                "getHomeActivityToken()");
7765        synchronized (this) {
7766            return mStackSupervisor.getHomeActivityToken();
7767        }
7768    }
7769
7770    @Override
7771    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7772            IActivityContainerCallback callback) throws RemoteException {
7773        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7774                "createActivityContainer()");
7775        synchronized (this) {
7776            if (parentActivityToken == null) {
7777                throw new IllegalArgumentException("parent token must not be null");
7778            }
7779            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7780            if (r == null) {
7781                return null;
7782            }
7783            if (callback == null) {
7784                throw new IllegalArgumentException("callback must not be null");
7785            }
7786            return mStackSupervisor.createActivityContainer(r, callback);
7787        }
7788    }
7789
7790    @Override
7791    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7792        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7793                "deleteActivityContainer()");
7794        synchronized (this) {
7795            mStackSupervisor.deleteActivityContainer(container);
7796        }
7797    }
7798
7799    @Override
7800    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7801            throws RemoteException {
7802        synchronized (this) {
7803            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7804            if (stack != null) {
7805                return stack.mActivityContainer;
7806            }
7807            return null;
7808        }
7809    }
7810
7811    @Override
7812    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7813        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7814                "moveTaskToStack()");
7815        if (stackId == HOME_STACK_ID) {
7816            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7817                    new RuntimeException("here").fillInStackTrace());
7818        }
7819        synchronized (this) {
7820            long ident = Binder.clearCallingIdentity();
7821            try {
7822                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7823                        + stackId + " toTop=" + toTop);
7824                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7825            } finally {
7826                Binder.restoreCallingIdentity(ident);
7827            }
7828        }
7829    }
7830
7831    @Override
7832    public void resizeStack(int stackBoxId, Rect bounds) {
7833        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7834                "resizeStackBox()");
7835        long ident = Binder.clearCallingIdentity();
7836        try {
7837            mWindowManager.resizeStack(stackBoxId, bounds);
7838        } finally {
7839            Binder.restoreCallingIdentity(ident);
7840        }
7841    }
7842
7843    @Override
7844    public List<StackInfo> getAllStackInfos() {
7845        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7846                "getAllStackInfos()");
7847        long ident = Binder.clearCallingIdentity();
7848        try {
7849            synchronized (this) {
7850                return mStackSupervisor.getAllStackInfosLocked();
7851            }
7852        } finally {
7853            Binder.restoreCallingIdentity(ident);
7854        }
7855    }
7856
7857    @Override
7858    public StackInfo getStackInfo(int stackId) {
7859        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7860                "getStackInfo()");
7861        long ident = Binder.clearCallingIdentity();
7862        try {
7863            synchronized (this) {
7864                return mStackSupervisor.getStackInfoLocked(stackId);
7865            }
7866        } finally {
7867            Binder.restoreCallingIdentity(ident);
7868        }
7869    }
7870
7871    @Override
7872    public boolean isInHomeStack(int taskId) {
7873        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7874                "getStackInfo()");
7875        long ident = Binder.clearCallingIdentity();
7876        try {
7877            synchronized (this) {
7878                TaskRecord tr = recentTaskForIdLocked(taskId);
7879                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7880            }
7881        } finally {
7882            Binder.restoreCallingIdentity(ident);
7883        }
7884    }
7885
7886    @Override
7887    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7888        synchronized(this) {
7889            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7890        }
7891    }
7892
7893    private boolean isLockTaskAuthorized(String pkg) {
7894        final DevicePolicyManager dpm = (DevicePolicyManager)
7895                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7896        try {
7897            int uid = mContext.getPackageManager().getPackageUid(pkg,
7898                    Binder.getCallingUserHandle().getIdentifier());
7899            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7900        } catch (NameNotFoundException e) {
7901            return false;
7902        }
7903    }
7904
7905    void startLockTaskMode(TaskRecord task) {
7906        final String pkg;
7907        synchronized (this) {
7908            pkg = task.intent.getComponent().getPackageName();
7909        }
7910        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7911        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7912            final TaskRecord taskRecord = task;
7913            mHandler.post(new Runnable() {
7914                @Override
7915                public void run() {
7916                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7917                }
7918            });
7919            return;
7920        }
7921        long ident = Binder.clearCallingIdentity();
7922        try {
7923            synchronized (this) {
7924                // Since we lost lock on task, make sure it is still there.
7925                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7926                if (task != null) {
7927                    if (!isSystemInitiated
7928                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7929                        throw new IllegalArgumentException("Invalid task, not in foreground");
7930                    }
7931                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7932                }
7933            }
7934        } finally {
7935            Binder.restoreCallingIdentity(ident);
7936        }
7937    }
7938
7939    @Override
7940    public void startLockTaskMode(int taskId) {
7941        final TaskRecord task;
7942        long ident = Binder.clearCallingIdentity();
7943        try {
7944            synchronized (this) {
7945                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7946            }
7947        } finally {
7948            Binder.restoreCallingIdentity(ident);
7949        }
7950        if (task != null) {
7951            startLockTaskMode(task);
7952        }
7953    }
7954
7955    @Override
7956    public void startLockTaskMode(IBinder token) {
7957        final TaskRecord task;
7958        long ident = Binder.clearCallingIdentity();
7959        try {
7960            synchronized (this) {
7961                final ActivityRecord r = ActivityRecord.forToken(token);
7962                if (r == null) {
7963                    return;
7964                }
7965                task = r.task;
7966            }
7967        } finally {
7968            Binder.restoreCallingIdentity(ident);
7969        }
7970        if (task != null) {
7971            startLockTaskMode(task);
7972        }
7973    }
7974
7975    @Override
7976    public void startLockTaskModeOnCurrent() throws RemoteException {
7977        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7978        ActivityRecord r = null;
7979        synchronized (this) {
7980            r = mStackSupervisor.topRunningActivityLocked();
7981        }
7982        startLockTaskMode(r.task);
7983    }
7984
7985    @Override
7986    public void stopLockTaskMode() {
7987        // Verify that the user matches the package of the intent for the TaskRecord
7988        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7989        // and stopLockTaskMode.
7990        final int callingUid = Binder.getCallingUid();
7991        if (callingUid != Process.SYSTEM_UID) {
7992            try {
7993                String pkg =
7994                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7995                int uid = mContext.getPackageManager().getPackageUid(pkg,
7996                        Binder.getCallingUserHandle().getIdentifier());
7997                if (uid != callingUid) {
7998                    throw new SecurityException("Invalid uid, expected " + uid);
7999                }
8000            } catch (NameNotFoundException e) {
8001                Log.d(TAG, "stopLockTaskMode " + e);
8002                return;
8003            }
8004        }
8005        long ident = Binder.clearCallingIdentity();
8006        try {
8007            Log.d(TAG, "stopLockTaskMode");
8008            // Stop lock task
8009            synchronized (this) {
8010                mStackSupervisor.setLockTaskModeLocked(null, false);
8011            }
8012        } finally {
8013            Binder.restoreCallingIdentity(ident);
8014        }
8015    }
8016
8017    @Override
8018    public void stopLockTaskModeOnCurrent() throws RemoteException {
8019        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8020        long ident = Binder.clearCallingIdentity();
8021        try {
8022            stopLockTaskMode();
8023        } finally {
8024            Binder.restoreCallingIdentity(ident);
8025        }
8026    }
8027
8028    @Override
8029    public boolean isInLockTaskMode() {
8030        synchronized (this) {
8031            return mStackSupervisor.isInLockTaskMode();
8032        }
8033    }
8034
8035    // =========================================================
8036    // CONTENT PROVIDERS
8037    // =========================================================
8038
8039    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8040        List<ProviderInfo> providers = null;
8041        try {
8042            providers = AppGlobals.getPackageManager().
8043                queryContentProviders(app.processName, app.uid,
8044                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8045        } catch (RemoteException ex) {
8046        }
8047        if (DEBUG_MU)
8048            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8049        int userId = app.userId;
8050        if (providers != null) {
8051            int N = providers.size();
8052            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8053            for (int i=0; i<N; i++) {
8054                ProviderInfo cpi =
8055                    (ProviderInfo)providers.get(i);
8056                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8057                        cpi.name, cpi.flags);
8058                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8059                    // This is a singleton provider, but a user besides the
8060                    // default user is asking to initialize a process it runs
8061                    // in...  well, no, it doesn't actually run in this process,
8062                    // it runs in the process of the default user.  Get rid of it.
8063                    providers.remove(i);
8064                    N--;
8065                    i--;
8066                    continue;
8067                }
8068
8069                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8070                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8071                if (cpr == null) {
8072                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8073                    mProviderMap.putProviderByClass(comp, cpr);
8074                }
8075                if (DEBUG_MU)
8076                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8077                app.pubProviders.put(cpi.name, cpr);
8078                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8079                    // Don't add this if it is a platform component that is marked
8080                    // to run in multiple processes, because this is actually
8081                    // part of the framework so doesn't make sense to track as a
8082                    // separate apk in the process.
8083                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8084                            mProcessStats);
8085                }
8086                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8087            }
8088        }
8089        return providers;
8090    }
8091
8092    /**
8093     * Check if {@link ProcessRecord} has a possible chance at accessing the
8094     * given {@link ProviderInfo}. Final permission checking is always done
8095     * in {@link ContentProvider}.
8096     */
8097    private final String checkContentProviderPermissionLocked(
8098            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8099        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8100        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8101        boolean checkedGrants = false;
8102        if (checkUser) {
8103            // Looking for cross-user grants before enforcing the typical cross-users permissions
8104            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8105            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8106                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8107                    return null;
8108                }
8109                checkedGrants = true;
8110            }
8111            userId = handleIncomingUser(callingPid, callingUid, userId,
8112                    false, ALLOW_NON_FULL,
8113                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8114            if (userId != tmpTargetUserId) {
8115                // When we actually went to determine the final targer user ID, this ended
8116                // up different than our initial check for the authority.  This is because
8117                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8118                // SELF.  So we need to re-check the grants again.
8119                checkedGrants = false;
8120            }
8121        }
8122        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8123                cpi.applicationInfo.uid, cpi.exported)
8124                == PackageManager.PERMISSION_GRANTED) {
8125            return null;
8126        }
8127        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8128                cpi.applicationInfo.uid, cpi.exported)
8129                == PackageManager.PERMISSION_GRANTED) {
8130            return null;
8131        }
8132
8133        PathPermission[] pps = cpi.pathPermissions;
8134        if (pps != null) {
8135            int i = pps.length;
8136            while (i > 0) {
8137                i--;
8138                PathPermission pp = pps[i];
8139                String pprperm = pp.getReadPermission();
8140                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8141                        cpi.applicationInfo.uid, cpi.exported)
8142                        == PackageManager.PERMISSION_GRANTED) {
8143                    return null;
8144                }
8145                String ppwperm = pp.getWritePermission();
8146                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8147                        cpi.applicationInfo.uid, cpi.exported)
8148                        == PackageManager.PERMISSION_GRANTED) {
8149                    return null;
8150                }
8151            }
8152        }
8153        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8154            return null;
8155        }
8156
8157        String msg;
8158        if (!cpi.exported) {
8159            msg = "Permission Denial: opening provider " + cpi.name
8160                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8161                    + ", uid=" + callingUid + ") that is not exported from uid "
8162                    + cpi.applicationInfo.uid;
8163        } else {
8164            msg = "Permission Denial: opening provider " + cpi.name
8165                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8166                    + ", uid=" + callingUid + ") requires "
8167                    + cpi.readPermission + " or " + cpi.writePermission;
8168        }
8169        Slog.w(TAG, msg);
8170        return msg;
8171    }
8172
8173    /**
8174     * Returns if the ContentProvider has granted a uri to callingUid
8175     */
8176    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8177        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8178        if (perms != null) {
8179            for (int i=perms.size()-1; i>=0; i--) {
8180                GrantUri grantUri = perms.keyAt(i);
8181                if (grantUri.sourceUserId == userId || !checkUser) {
8182                    if (matchesProvider(grantUri.uri, cpi)) {
8183                        return true;
8184                    }
8185                }
8186            }
8187        }
8188        return false;
8189    }
8190
8191    /**
8192     * Returns true if the uri authority is one of the authorities specified in the provider.
8193     */
8194    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8195        String uriAuth = uri.getAuthority();
8196        String cpiAuth = cpi.authority;
8197        if (cpiAuth.indexOf(';') == -1) {
8198            return cpiAuth.equals(uriAuth);
8199        }
8200        String[] cpiAuths = cpiAuth.split(";");
8201        int length = cpiAuths.length;
8202        for (int i = 0; i < length; i++) {
8203            if (cpiAuths[i].equals(uriAuth)) return true;
8204        }
8205        return false;
8206    }
8207
8208    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8209            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8210        if (r != null) {
8211            for (int i=0; i<r.conProviders.size(); i++) {
8212                ContentProviderConnection conn = r.conProviders.get(i);
8213                if (conn.provider == cpr) {
8214                    if (DEBUG_PROVIDER) Slog.v(TAG,
8215                            "Adding provider requested by "
8216                            + r.processName + " from process "
8217                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8218                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8219                    if (stable) {
8220                        conn.stableCount++;
8221                        conn.numStableIncs++;
8222                    } else {
8223                        conn.unstableCount++;
8224                        conn.numUnstableIncs++;
8225                    }
8226                    return conn;
8227                }
8228            }
8229            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8230            if (stable) {
8231                conn.stableCount = 1;
8232                conn.numStableIncs = 1;
8233            } else {
8234                conn.unstableCount = 1;
8235                conn.numUnstableIncs = 1;
8236            }
8237            cpr.connections.add(conn);
8238            r.conProviders.add(conn);
8239            return conn;
8240        }
8241        cpr.addExternalProcessHandleLocked(externalProcessToken);
8242        return null;
8243    }
8244
8245    boolean decProviderCountLocked(ContentProviderConnection conn,
8246            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8247        if (conn != null) {
8248            cpr = conn.provider;
8249            if (DEBUG_PROVIDER) Slog.v(TAG,
8250                    "Removing provider requested by "
8251                    + conn.client.processName + " from process "
8252                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8253                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8254            if (stable) {
8255                conn.stableCount--;
8256            } else {
8257                conn.unstableCount--;
8258            }
8259            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8260                cpr.connections.remove(conn);
8261                conn.client.conProviders.remove(conn);
8262                return true;
8263            }
8264            return false;
8265        }
8266        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8267        return false;
8268    }
8269
8270    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8271            String name, IBinder token, boolean stable, int userId) {
8272        ContentProviderRecord cpr;
8273        ContentProviderConnection conn = null;
8274        ProviderInfo cpi = null;
8275
8276        synchronized(this) {
8277            ProcessRecord r = null;
8278            if (caller != null) {
8279                r = getRecordForAppLocked(caller);
8280                if (r == null) {
8281                    throw new SecurityException(
8282                            "Unable to find app for caller " + caller
8283                          + " (pid=" + Binder.getCallingPid()
8284                          + ") when getting content provider " + name);
8285                }
8286            }
8287
8288            boolean checkCrossUser = true;
8289
8290            // First check if this content provider has been published...
8291            cpr = mProviderMap.getProviderByName(name, userId);
8292            // If that didn't work, check if it exists for user 0 and then
8293            // verify that it's a singleton provider before using it.
8294            if (cpr == null && userId != UserHandle.USER_OWNER) {
8295                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8296                if (cpr != null) {
8297                    cpi = cpr.info;
8298                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8299                            cpi.name, cpi.flags)
8300                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8301                        userId = UserHandle.USER_OWNER;
8302                        checkCrossUser = false;
8303                    } else {
8304                        cpr = null;
8305                        cpi = null;
8306                    }
8307                }
8308            }
8309
8310            boolean providerRunning = cpr != null;
8311            if (providerRunning) {
8312                cpi = cpr.info;
8313                String msg;
8314                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8315                        != null) {
8316                    throw new SecurityException(msg);
8317                }
8318
8319                if (r != null && cpr.canRunHere(r)) {
8320                    // This provider has been published or is in the process
8321                    // of being published...  but it is also allowed to run
8322                    // in the caller's process, so don't make a connection
8323                    // and just let the caller instantiate its own instance.
8324                    ContentProviderHolder holder = cpr.newHolder(null);
8325                    // don't give caller the provider object, it needs
8326                    // to make its own.
8327                    holder.provider = null;
8328                    return holder;
8329                }
8330
8331                final long origId = Binder.clearCallingIdentity();
8332
8333                // In this case the provider instance already exists, so we can
8334                // return it right away.
8335                conn = incProviderCountLocked(r, cpr, token, stable);
8336                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8337                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8338                        // If this is a perceptible app accessing the provider,
8339                        // make sure to count it as being accessed and thus
8340                        // back up on the LRU list.  This is good because
8341                        // content providers are often expensive to start.
8342                        updateLruProcessLocked(cpr.proc, false, null);
8343                    }
8344                }
8345
8346                if (cpr.proc != null) {
8347                    if (false) {
8348                        if (cpr.name.flattenToShortString().equals(
8349                                "com.android.providers.calendar/.CalendarProvider2")) {
8350                            Slog.v(TAG, "****************** KILLING "
8351                                + cpr.name.flattenToShortString());
8352                            Process.killProcess(cpr.proc.pid);
8353                        }
8354                    }
8355                    boolean success = updateOomAdjLocked(cpr.proc);
8356                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8357                    // NOTE: there is still a race here where a signal could be
8358                    // pending on the process even though we managed to update its
8359                    // adj level.  Not sure what to do about this, but at least
8360                    // the race is now smaller.
8361                    if (!success) {
8362                        // Uh oh...  it looks like the provider's process
8363                        // has been killed on us.  We need to wait for a new
8364                        // process to be started, and make sure its death
8365                        // doesn't kill our process.
8366                        Slog.i(TAG,
8367                                "Existing provider " + cpr.name.flattenToShortString()
8368                                + " is crashing; detaching " + r);
8369                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8370                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8371                        if (!lastRef) {
8372                            // This wasn't the last ref our process had on
8373                            // the provider...  we have now been killed, bail.
8374                            return null;
8375                        }
8376                        providerRunning = false;
8377                        conn = null;
8378                    }
8379                }
8380
8381                Binder.restoreCallingIdentity(origId);
8382            }
8383
8384            boolean singleton;
8385            if (!providerRunning) {
8386                try {
8387                    cpi = AppGlobals.getPackageManager().
8388                        resolveContentProvider(name,
8389                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8390                } catch (RemoteException ex) {
8391                }
8392                if (cpi == null) {
8393                    return null;
8394                }
8395                // If the provider is a singleton AND
8396                // (it's a call within the same user || the provider is a
8397                // privileged app)
8398                // Then allow connecting to the singleton provider
8399                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8400                        cpi.name, cpi.flags)
8401                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8402                if (singleton) {
8403                    userId = UserHandle.USER_OWNER;
8404                }
8405                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8406
8407                String msg;
8408                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8409                        != null) {
8410                    throw new SecurityException(msg);
8411                }
8412
8413                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8414                        && !cpi.processName.equals("system")) {
8415                    // If this content provider does not run in the system
8416                    // process, and the system is not yet ready to run other
8417                    // processes, then fail fast instead of hanging.
8418                    throw new IllegalArgumentException(
8419                            "Attempt to launch content provider before system ready");
8420                }
8421
8422                // Make sure that the user who owns this provider is started.  If not,
8423                // we don't want to allow it to run.
8424                if (mStartedUsers.get(userId) == null) {
8425                    Slog.w(TAG, "Unable to launch app "
8426                            + cpi.applicationInfo.packageName + "/"
8427                            + cpi.applicationInfo.uid + " for provider "
8428                            + name + ": user " + userId + " is stopped");
8429                    return null;
8430                }
8431
8432                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8433                cpr = mProviderMap.getProviderByClass(comp, userId);
8434                final boolean firstClass = cpr == null;
8435                if (firstClass) {
8436                    try {
8437                        ApplicationInfo ai =
8438                            AppGlobals.getPackageManager().
8439                                getApplicationInfo(
8440                                        cpi.applicationInfo.packageName,
8441                                        STOCK_PM_FLAGS, userId);
8442                        if (ai == null) {
8443                            Slog.w(TAG, "No package info for content provider "
8444                                    + cpi.name);
8445                            return null;
8446                        }
8447                        ai = getAppInfoForUser(ai, userId);
8448                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8449                    } catch (RemoteException ex) {
8450                        // pm is in same process, this will never happen.
8451                    }
8452                }
8453
8454                if (r != null && cpr.canRunHere(r)) {
8455                    // If this is a multiprocess provider, then just return its
8456                    // info and allow the caller to instantiate it.  Only do
8457                    // this if the provider is the same user as the caller's
8458                    // process, or can run as root (so can be in any process).
8459                    return cpr.newHolder(null);
8460                }
8461
8462                if (DEBUG_PROVIDER) {
8463                    RuntimeException e = new RuntimeException("here");
8464                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8465                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8466                }
8467
8468                // This is single process, and our app is now connecting to it.
8469                // See if we are already in the process of launching this
8470                // provider.
8471                final int N = mLaunchingProviders.size();
8472                int i;
8473                for (i=0; i<N; i++) {
8474                    if (mLaunchingProviders.get(i) == cpr) {
8475                        break;
8476                    }
8477                }
8478
8479                // If the provider is not already being launched, then get it
8480                // started.
8481                if (i >= N) {
8482                    final long origId = Binder.clearCallingIdentity();
8483
8484                    try {
8485                        // Content provider is now in use, its package can't be stopped.
8486                        try {
8487                            AppGlobals.getPackageManager().setPackageStoppedState(
8488                                    cpr.appInfo.packageName, false, userId);
8489                        } catch (RemoteException e) {
8490                        } catch (IllegalArgumentException e) {
8491                            Slog.w(TAG, "Failed trying to unstop package "
8492                                    + cpr.appInfo.packageName + ": " + e);
8493                        }
8494
8495                        // Use existing process if already started
8496                        ProcessRecord proc = getProcessRecordLocked(
8497                                cpi.processName, cpr.appInfo.uid, false);
8498                        if (proc != null && proc.thread != null) {
8499                            if (DEBUG_PROVIDER) {
8500                                Slog.d(TAG, "Installing in existing process " + proc);
8501                            }
8502                            proc.pubProviders.put(cpi.name, cpr);
8503                            try {
8504                                proc.thread.scheduleInstallProvider(cpi);
8505                            } catch (RemoteException e) {
8506                            }
8507                        } else {
8508                            proc = startProcessLocked(cpi.processName,
8509                                    cpr.appInfo, false, 0, "content provider",
8510                                    new ComponentName(cpi.applicationInfo.packageName,
8511                                            cpi.name), false, false, false);
8512                            if (proc == null) {
8513                                Slog.w(TAG, "Unable to launch app "
8514                                        + cpi.applicationInfo.packageName + "/"
8515                                        + cpi.applicationInfo.uid + " for provider "
8516                                        + name + ": process is bad");
8517                                return null;
8518                            }
8519                        }
8520                        cpr.launchingApp = proc;
8521                        mLaunchingProviders.add(cpr);
8522                    } finally {
8523                        Binder.restoreCallingIdentity(origId);
8524                    }
8525                }
8526
8527                // Make sure the provider is published (the same provider class
8528                // may be published under multiple names).
8529                if (firstClass) {
8530                    mProviderMap.putProviderByClass(comp, cpr);
8531                }
8532
8533                mProviderMap.putProviderByName(name, cpr);
8534                conn = incProviderCountLocked(r, cpr, token, stable);
8535                if (conn != null) {
8536                    conn.waiting = true;
8537                }
8538            }
8539        }
8540
8541        // Wait for the provider to be published...
8542        synchronized (cpr) {
8543            while (cpr.provider == null) {
8544                if (cpr.launchingApp == null) {
8545                    Slog.w(TAG, "Unable to launch app "
8546                            + cpi.applicationInfo.packageName + "/"
8547                            + cpi.applicationInfo.uid + " for provider "
8548                            + name + ": launching app became null");
8549                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8550                            UserHandle.getUserId(cpi.applicationInfo.uid),
8551                            cpi.applicationInfo.packageName,
8552                            cpi.applicationInfo.uid, name);
8553                    return null;
8554                }
8555                try {
8556                    if (DEBUG_MU) {
8557                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8558                                + cpr.launchingApp);
8559                    }
8560                    if (conn != null) {
8561                        conn.waiting = true;
8562                    }
8563                    cpr.wait();
8564                } catch (InterruptedException ex) {
8565                } finally {
8566                    if (conn != null) {
8567                        conn.waiting = false;
8568                    }
8569                }
8570            }
8571        }
8572        return cpr != null ? cpr.newHolder(conn) : null;
8573    }
8574
8575    @Override
8576    public final ContentProviderHolder getContentProvider(
8577            IApplicationThread caller, String name, int userId, boolean stable) {
8578        enforceNotIsolatedCaller("getContentProvider");
8579        if (caller == null) {
8580            String msg = "null IApplicationThread when getting content provider "
8581                    + name;
8582            Slog.w(TAG, msg);
8583            throw new SecurityException(msg);
8584        }
8585        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8586        // with cross-user grant.
8587        return getContentProviderImpl(caller, name, null, stable, userId);
8588    }
8589
8590    public ContentProviderHolder getContentProviderExternal(
8591            String name, int userId, IBinder token) {
8592        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8593            "Do not have permission in call getContentProviderExternal()");
8594        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8595                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8596        return getContentProviderExternalUnchecked(name, token, userId);
8597    }
8598
8599    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8600            IBinder token, int userId) {
8601        return getContentProviderImpl(null, name, token, true, userId);
8602    }
8603
8604    /**
8605     * Drop a content provider from a ProcessRecord's bookkeeping
8606     */
8607    public void removeContentProvider(IBinder connection, boolean stable) {
8608        enforceNotIsolatedCaller("removeContentProvider");
8609        long ident = Binder.clearCallingIdentity();
8610        try {
8611            synchronized (this) {
8612                ContentProviderConnection conn;
8613                try {
8614                    conn = (ContentProviderConnection)connection;
8615                } catch (ClassCastException e) {
8616                    String msg ="removeContentProvider: " + connection
8617                            + " not a ContentProviderConnection";
8618                    Slog.w(TAG, msg);
8619                    throw new IllegalArgumentException(msg);
8620                }
8621                if (conn == null) {
8622                    throw new NullPointerException("connection is null");
8623                }
8624                if (decProviderCountLocked(conn, null, null, stable)) {
8625                    updateOomAdjLocked();
8626                }
8627            }
8628        } finally {
8629            Binder.restoreCallingIdentity(ident);
8630        }
8631    }
8632
8633    public void removeContentProviderExternal(String name, IBinder token) {
8634        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8635            "Do not have permission in call removeContentProviderExternal()");
8636        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8637    }
8638
8639    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8640        synchronized (this) {
8641            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8642            if(cpr == null) {
8643                //remove from mProvidersByClass
8644                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8645                return;
8646            }
8647
8648            //update content provider record entry info
8649            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8650            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8651            if (localCpr.hasExternalProcessHandles()) {
8652                if (localCpr.removeExternalProcessHandleLocked(token)) {
8653                    updateOomAdjLocked();
8654                } else {
8655                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8656                            + " with no external reference for token: "
8657                            + token + ".");
8658                }
8659            } else {
8660                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8661                        + " with no external references.");
8662            }
8663        }
8664    }
8665
8666    public final void publishContentProviders(IApplicationThread caller,
8667            List<ContentProviderHolder> providers) {
8668        if (providers == null) {
8669            return;
8670        }
8671
8672        enforceNotIsolatedCaller("publishContentProviders");
8673        synchronized (this) {
8674            final ProcessRecord r = getRecordForAppLocked(caller);
8675            if (DEBUG_MU)
8676                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8677            if (r == null) {
8678                throw new SecurityException(
8679                        "Unable to find app for caller " + caller
8680                      + " (pid=" + Binder.getCallingPid()
8681                      + ") when publishing content providers");
8682            }
8683
8684            final long origId = Binder.clearCallingIdentity();
8685
8686            final int N = providers.size();
8687            for (int i=0; i<N; i++) {
8688                ContentProviderHolder src = providers.get(i);
8689                if (src == null || src.info == null || src.provider == null) {
8690                    continue;
8691                }
8692                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8693                if (DEBUG_MU)
8694                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8695                if (dst != null) {
8696                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8697                    mProviderMap.putProviderByClass(comp, dst);
8698                    String names[] = dst.info.authority.split(";");
8699                    for (int j = 0; j < names.length; j++) {
8700                        mProviderMap.putProviderByName(names[j], dst);
8701                    }
8702
8703                    int NL = mLaunchingProviders.size();
8704                    int j;
8705                    for (j=0; j<NL; j++) {
8706                        if (mLaunchingProviders.get(j) == dst) {
8707                            mLaunchingProviders.remove(j);
8708                            j--;
8709                            NL--;
8710                        }
8711                    }
8712                    synchronized (dst) {
8713                        dst.provider = src.provider;
8714                        dst.proc = r;
8715                        dst.notifyAll();
8716                    }
8717                    updateOomAdjLocked(r);
8718                }
8719            }
8720
8721            Binder.restoreCallingIdentity(origId);
8722        }
8723    }
8724
8725    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8726        ContentProviderConnection conn;
8727        try {
8728            conn = (ContentProviderConnection)connection;
8729        } catch (ClassCastException e) {
8730            String msg ="refContentProvider: " + connection
8731                    + " not a ContentProviderConnection";
8732            Slog.w(TAG, msg);
8733            throw new IllegalArgumentException(msg);
8734        }
8735        if (conn == null) {
8736            throw new NullPointerException("connection is null");
8737        }
8738
8739        synchronized (this) {
8740            if (stable > 0) {
8741                conn.numStableIncs += stable;
8742            }
8743            stable = conn.stableCount + stable;
8744            if (stable < 0) {
8745                throw new IllegalStateException("stableCount < 0: " + stable);
8746            }
8747
8748            if (unstable > 0) {
8749                conn.numUnstableIncs += unstable;
8750            }
8751            unstable = conn.unstableCount + unstable;
8752            if (unstable < 0) {
8753                throw new IllegalStateException("unstableCount < 0: " + unstable);
8754            }
8755
8756            if ((stable+unstable) <= 0) {
8757                throw new IllegalStateException("ref counts can't go to zero here: stable="
8758                        + stable + " unstable=" + unstable);
8759            }
8760            conn.stableCount = stable;
8761            conn.unstableCount = unstable;
8762            return !conn.dead;
8763        }
8764    }
8765
8766    public void unstableProviderDied(IBinder connection) {
8767        ContentProviderConnection conn;
8768        try {
8769            conn = (ContentProviderConnection)connection;
8770        } catch (ClassCastException e) {
8771            String msg ="refContentProvider: " + connection
8772                    + " not a ContentProviderConnection";
8773            Slog.w(TAG, msg);
8774            throw new IllegalArgumentException(msg);
8775        }
8776        if (conn == null) {
8777            throw new NullPointerException("connection is null");
8778        }
8779
8780        // Safely retrieve the content provider associated with the connection.
8781        IContentProvider provider;
8782        synchronized (this) {
8783            provider = conn.provider.provider;
8784        }
8785
8786        if (provider == null) {
8787            // Um, yeah, we're way ahead of you.
8788            return;
8789        }
8790
8791        // Make sure the caller is being honest with us.
8792        if (provider.asBinder().pingBinder()) {
8793            // Er, no, still looks good to us.
8794            synchronized (this) {
8795                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8796                        + " says " + conn + " died, but we don't agree");
8797                return;
8798            }
8799        }
8800
8801        // Well look at that!  It's dead!
8802        synchronized (this) {
8803            if (conn.provider.provider != provider) {
8804                // But something changed...  good enough.
8805                return;
8806            }
8807
8808            ProcessRecord proc = conn.provider.proc;
8809            if (proc == null || proc.thread == null) {
8810                // Seems like the process is already cleaned up.
8811                return;
8812            }
8813
8814            // As far as we're concerned, this is just like receiving a
8815            // death notification...  just a bit prematurely.
8816            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8817                    + ") early provider death");
8818            final long ident = Binder.clearCallingIdentity();
8819            try {
8820                appDiedLocked(proc, proc.pid, proc.thread);
8821            } finally {
8822                Binder.restoreCallingIdentity(ident);
8823            }
8824        }
8825    }
8826
8827    @Override
8828    public void appNotRespondingViaProvider(IBinder connection) {
8829        enforceCallingPermission(
8830                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8831
8832        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8833        if (conn == null) {
8834            Slog.w(TAG, "ContentProviderConnection is null");
8835            return;
8836        }
8837
8838        final ProcessRecord host = conn.provider.proc;
8839        if (host == null) {
8840            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8841            return;
8842        }
8843
8844        final long token = Binder.clearCallingIdentity();
8845        try {
8846            appNotResponding(host, null, null, false, "ContentProvider not responding");
8847        } finally {
8848            Binder.restoreCallingIdentity(token);
8849        }
8850    }
8851
8852    public final void installSystemProviders() {
8853        List<ProviderInfo> providers;
8854        synchronized (this) {
8855            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8856            providers = generateApplicationProvidersLocked(app);
8857            if (providers != null) {
8858                for (int i=providers.size()-1; i>=0; i--) {
8859                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8860                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8861                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8862                                + ": not system .apk");
8863                        providers.remove(i);
8864                    }
8865                }
8866            }
8867        }
8868        if (providers != null) {
8869            mSystemThread.installSystemProviders(providers);
8870        }
8871
8872        mCoreSettingsObserver = new CoreSettingsObserver(this);
8873
8874        //mUsageStatsService.monitorPackages();
8875    }
8876
8877    /**
8878     * Allows app to retrieve the MIME type of a URI without having permission
8879     * to access its content provider.
8880     *
8881     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8882     *
8883     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8884     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8885     */
8886    public String getProviderMimeType(Uri uri, int userId) {
8887        enforceNotIsolatedCaller("getProviderMimeType");
8888        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8889                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8890        final String name = uri.getAuthority();
8891        final long ident = Binder.clearCallingIdentity();
8892        ContentProviderHolder holder = null;
8893
8894        try {
8895            holder = getContentProviderExternalUnchecked(name, null, userId);
8896            if (holder != null) {
8897                return holder.provider.getType(uri);
8898            }
8899        } catch (RemoteException e) {
8900            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8901            return null;
8902        } finally {
8903            if (holder != null) {
8904                removeContentProviderExternalUnchecked(name, null, userId);
8905            }
8906            Binder.restoreCallingIdentity(ident);
8907        }
8908
8909        return null;
8910    }
8911
8912    // =========================================================
8913    // GLOBAL MANAGEMENT
8914    // =========================================================
8915
8916    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8917            boolean isolated) {
8918        String proc = customProcess != null ? customProcess : info.processName;
8919        BatteryStatsImpl.Uid.Proc ps = null;
8920        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8921        int uid = info.uid;
8922        if (isolated) {
8923            int userId = UserHandle.getUserId(uid);
8924            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8925            while (true) {
8926                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8927                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8928                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8929                }
8930                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8931                mNextIsolatedProcessUid++;
8932                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8933                    // No process for this uid, use it.
8934                    break;
8935                }
8936                stepsLeft--;
8937                if (stepsLeft <= 0) {
8938                    return null;
8939                }
8940            }
8941        }
8942        return new ProcessRecord(stats, info, proc, uid);
8943    }
8944
8945    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8946            String abiOverride) {
8947        ProcessRecord app;
8948        if (!isolated) {
8949            app = getProcessRecordLocked(info.processName, info.uid, true);
8950        } else {
8951            app = null;
8952        }
8953
8954        if (app == null) {
8955            app = newProcessRecordLocked(info, null, isolated);
8956            mProcessNames.put(info.processName, app.uid, app);
8957            if (isolated) {
8958                mIsolatedProcesses.put(app.uid, app);
8959            }
8960            updateLruProcessLocked(app, false, null);
8961            updateOomAdjLocked();
8962        }
8963
8964        // This package really, really can not be stopped.
8965        try {
8966            AppGlobals.getPackageManager().setPackageStoppedState(
8967                    info.packageName, false, UserHandle.getUserId(app.uid));
8968        } catch (RemoteException e) {
8969        } catch (IllegalArgumentException e) {
8970            Slog.w(TAG, "Failed trying to unstop package "
8971                    + info.packageName + ": " + e);
8972        }
8973
8974        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8975                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8976            app.persistent = true;
8977            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8978        }
8979        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8980            mPersistentStartingProcesses.add(app);
8981            startProcessLocked(app, "added application", app.processName,
8982                    abiOverride);
8983        }
8984
8985        return app;
8986    }
8987
8988    public void unhandledBack() {
8989        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8990                "unhandledBack()");
8991
8992        synchronized(this) {
8993            final long origId = Binder.clearCallingIdentity();
8994            try {
8995                getFocusedStack().unhandledBackLocked();
8996            } finally {
8997                Binder.restoreCallingIdentity(origId);
8998            }
8999        }
9000    }
9001
9002    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9003        enforceNotIsolatedCaller("openContentUri");
9004        final int userId = UserHandle.getCallingUserId();
9005        String name = uri.getAuthority();
9006        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9007        ParcelFileDescriptor pfd = null;
9008        if (cph != null) {
9009            // We record the binder invoker's uid in thread-local storage before
9010            // going to the content provider to open the file.  Later, in the code
9011            // that handles all permissions checks, we look for this uid and use
9012            // that rather than the Activity Manager's own uid.  The effect is that
9013            // we do the check against the caller's permissions even though it looks
9014            // to the content provider like the Activity Manager itself is making
9015            // the request.
9016            sCallerIdentity.set(new Identity(
9017                    Binder.getCallingPid(), Binder.getCallingUid()));
9018            try {
9019                pfd = cph.provider.openFile(null, uri, "r", null);
9020            } catch (FileNotFoundException e) {
9021                // do nothing; pfd will be returned null
9022            } finally {
9023                // Ensure that whatever happens, we clean up the identity state
9024                sCallerIdentity.remove();
9025            }
9026
9027            // We've got the fd now, so we're done with the provider.
9028            removeContentProviderExternalUnchecked(name, null, userId);
9029        } else {
9030            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9031        }
9032        return pfd;
9033    }
9034
9035    // Actually is sleeping or shutting down or whatever else in the future
9036    // is an inactive state.
9037    public boolean isSleepingOrShuttingDown() {
9038        return mSleeping || mShuttingDown;
9039    }
9040
9041    public boolean isSleeping() {
9042        return mSleeping;
9043    }
9044
9045    void goingToSleep() {
9046        synchronized(this) {
9047            mWentToSleep = true;
9048            updateEventDispatchingLocked();
9049            goToSleepIfNeededLocked();
9050        }
9051    }
9052
9053    void finishRunningVoiceLocked() {
9054        if (mRunningVoice) {
9055            mRunningVoice = false;
9056            goToSleepIfNeededLocked();
9057        }
9058    }
9059
9060    void goToSleepIfNeededLocked() {
9061        if (mWentToSleep && !mRunningVoice) {
9062            if (!mSleeping) {
9063                mSleeping = true;
9064                mStackSupervisor.goingToSleepLocked();
9065
9066                // Initialize the wake times of all processes.
9067                checkExcessivePowerUsageLocked(false);
9068                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9069                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9070                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9071            }
9072        }
9073    }
9074
9075    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9076        mTaskPersister.notify(task, flush);
9077    }
9078
9079    @Override
9080    public boolean shutdown(int timeout) {
9081        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9082                != PackageManager.PERMISSION_GRANTED) {
9083            throw new SecurityException("Requires permission "
9084                    + android.Manifest.permission.SHUTDOWN);
9085        }
9086
9087        boolean timedout = false;
9088
9089        synchronized(this) {
9090            mShuttingDown = true;
9091            updateEventDispatchingLocked();
9092            timedout = mStackSupervisor.shutdownLocked(timeout);
9093        }
9094
9095        mAppOpsService.shutdown();
9096        if (mUsageStatsService != null) {
9097            mUsageStatsService.prepareShutdown();
9098        }
9099        mBatteryStatsService.shutdown();
9100        synchronized (this) {
9101            mProcessStats.shutdownLocked();
9102        }
9103        notifyTaskPersisterLocked(null, true);
9104
9105        return timedout;
9106    }
9107
9108    public final void activitySlept(IBinder token) {
9109        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9110
9111        final long origId = Binder.clearCallingIdentity();
9112
9113        synchronized (this) {
9114            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9115            if (r != null) {
9116                mStackSupervisor.activitySleptLocked(r);
9117            }
9118        }
9119
9120        Binder.restoreCallingIdentity(origId);
9121    }
9122
9123    void logLockScreen(String msg) {
9124        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9125                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9126                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9127                mStackSupervisor.mDismissKeyguardOnNextActivity);
9128    }
9129
9130    private void comeOutOfSleepIfNeededLocked() {
9131        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9132            if (mSleeping) {
9133                mSleeping = false;
9134                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9135            }
9136        }
9137    }
9138
9139    void wakingUp() {
9140        synchronized(this) {
9141            mWentToSleep = false;
9142            updateEventDispatchingLocked();
9143            comeOutOfSleepIfNeededLocked();
9144        }
9145    }
9146
9147    void startRunningVoiceLocked() {
9148        if (!mRunningVoice) {
9149            mRunningVoice = true;
9150            comeOutOfSleepIfNeededLocked();
9151        }
9152    }
9153
9154    private void updateEventDispatchingLocked() {
9155        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9156    }
9157
9158    public void setLockScreenShown(boolean shown) {
9159        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9160                != PackageManager.PERMISSION_GRANTED) {
9161            throw new SecurityException("Requires permission "
9162                    + android.Manifest.permission.DEVICE_POWER);
9163        }
9164
9165        synchronized(this) {
9166            long ident = Binder.clearCallingIdentity();
9167            try {
9168                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9169                mLockScreenShown = shown;
9170                comeOutOfSleepIfNeededLocked();
9171            } finally {
9172                Binder.restoreCallingIdentity(ident);
9173            }
9174        }
9175    }
9176
9177    @Override
9178    public void stopAppSwitches() {
9179        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9180                != PackageManager.PERMISSION_GRANTED) {
9181            throw new SecurityException("Requires permission "
9182                    + android.Manifest.permission.STOP_APP_SWITCHES);
9183        }
9184
9185        synchronized(this) {
9186            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9187                    + APP_SWITCH_DELAY_TIME;
9188            mDidAppSwitch = false;
9189            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9190            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9191            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9192        }
9193    }
9194
9195    public void resumeAppSwitches() {
9196        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9197                != PackageManager.PERMISSION_GRANTED) {
9198            throw new SecurityException("Requires permission "
9199                    + android.Manifest.permission.STOP_APP_SWITCHES);
9200        }
9201
9202        synchronized(this) {
9203            // Note that we don't execute any pending app switches... we will
9204            // let those wait until either the timeout, or the next start
9205            // activity request.
9206            mAppSwitchesAllowedTime = 0;
9207        }
9208    }
9209
9210    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9211            String name) {
9212        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9213            return true;
9214        }
9215
9216        final int perm = checkComponentPermission(
9217                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9218                callingUid, -1, true);
9219        if (perm == PackageManager.PERMISSION_GRANTED) {
9220            return true;
9221        }
9222
9223        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9224        return false;
9225    }
9226
9227    public void setDebugApp(String packageName, boolean waitForDebugger,
9228            boolean persistent) {
9229        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9230                "setDebugApp()");
9231
9232        long ident = Binder.clearCallingIdentity();
9233        try {
9234            // Note that this is not really thread safe if there are multiple
9235            // callers into it at the same time, but that's not a situation we
9236            // care about.
9237            if (persistent) {
9238                final ContentResolver resolver = mContext.getContentResolver();
9239                Settings.Global.putString(
9240                    resolver, Settings.Global.DEBUG_APP,
9241                    packageName);
9242                Settings.Global.putInt(
9243                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9244                    waitForDebugger ? 1 : 0);
9245            }
9246
9247            synchronized (this) {
9248                if (!persistent) {
9249                    mOrigDebugApp = mDebugApp;
9250                    mOrigWaitForDebugger = mWaitForDebugger;
9251                }
9252                mDebugApp = packageName;
9253                mWaitForDebugger = waitForDebugger;
9254                mDebugTransient = !persistent;
9255                if (packageName != null) {
9256                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9257                            false, UserHandle.USER_ALL, "set debug app");
9258                }
9259            }
9260        } finally {
9261            Binder.restoreCallingIdentity(ident);
9262        }
9263    }
9264
9265    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9266        synchronized (this) {
9267            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9268            if (!isDebuggable) {
9269                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9270                    throw new SecurityException("Process not debuggable: " + app.packageName);
9271                }
9272            }
9273
9274            mOpenGlTraceApp = processName;
9275        }
9276    }
9277
9278    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9279            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9280        synchronized (this) {
9281            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9282            if (!isDebuggable) {
9283                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9284                    throw new SecurityException("Process not debuggable: " + app.packageName);
9285                }
9286            }
9287            mProfileApp = processName;
9288            mProfileFile = profileFile;
9289            if (mProfileFd != null) {
9290                try {
9291                    mProfileFd.close();
9292                } catch (IOException e) {
9293                }
9294                mProfileFd = null;
9295            }
9296            mProfileFd = profileFd;
9297            mProfileType = 0;
9298            mAutoStopProfiler = autoStopProfiler;
9299        }
9300    }
9301
9302    @Override
9303    public void setAlwaysFinish(boolean enabled) {
9304        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9305                "setAlwaysFinish()");
9306
9307        Settings.Global.putInt(
9308                mContext.getContentResolver(),
9309                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9310
9311        synchronized (this) {
9312            mAlwaysFinishActivities = enabled;
9313        }
9314    }
9315
9316    @Override
9317    public void setActivityController(IActivityController controller) {
9318        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9319                "setActivityController()");
9320        synchronized (this) {
9321            mController = controller;
9322            Watchdog.getInstance().setActivityController(controller);
9323        }
9324    }
9325
9326    @Override
9327    public void setUserIsMonkey(boolean userIsMonkey) {
9328        synchronized (this) {
9329            synchronized (mPidsSelfLocked) {
9330                final int callingPid = Binder.getCallingPid();
9331                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9332                if (precessRecord == null) {
9333                    throw new SecurityException("Unknown process: " + callingPid);
9334                }
9335                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9336                    throw new SecurityException("Only an instrumentation process "
9337                            + "with a UiAutomation can call setUserIsMonkey");
9338                }
9339            }
9340            mUserIsMonkey = userIsMonkey;
9341        }
9342    }
9343
9344    @Override
9345    public boolean isUserAMonkey() {
9346        synchronized (this) {
9347            // If there is a controller also implies the user is a monkey.
9348            return (mUserIsMonkey || mController != null);
9349        }
9350    }
9351
9352    public void requestBugReport() {
9353        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9354        SystemProperties.set("ctl.start", "bugreport");
9355    }
9356
9357    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9358        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9359    }
9360
9361    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9362        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9363            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9364        }
9365        return KEY_DISPATCHING_TIMEOUT;
9366    }
9367
9368    @Override
9369    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9370        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9371                != PackageManager.PERMISSION_GRANTED) {
9372            throw new SecurityException("Requires permission "
9373                    + android.Manifest.permission.FILTER_EVENTS);
9374        }
9375        ProcessRecord proc;
9376        long timeout;
9377        synchronized (this) {
9378            synchronized (mPidsSelfLocked) {
9379                proc = mPidsSelfLocked.get(pid);
9380            }
9381            timeout = getInputDispatchingTimeoutLocked(proc);
9382        }
9383
9384        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9385            return -1;
9386        }
9387
9388        return timeout;
9389    }
9390
9391    /**
9392     * Handle input dispatching timeouts.
9393     * Returns whether input dispatching should be aborted or not.
9394     */
9395    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9396            final ActivityRecord activity, final ActivityRecord parent,
9397            final boolean aboveSystem, String reason) {
9398        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9399                != PackageManager.PERMISSION_GRANTED) {
9400            throw new SecurityException("Requires permission "
9401                    + android.Manifest.permission.FILTER_EVENTS);
9402        }
9403
9404        final String annotation;
9405        if (reason == null) {
9406            annotation = "Input dispatching timed out";
9407        } else {
9408            annotation = "Input dispatching timed out (" + reason + ")";
9409        }
9410
9411        if (proc != null) {
9412            synchronized (this) {
9413                if (proc.debugging) {
9414                    return false;
9415                }
9416
9417                if (mDidDexOpt) {
9418                    // Give more time since we were dexopting.
9419                    mDidDexOpt = false;
9420                    return false;
9421                }
9422
9423                if (proc.instrumentationClass != null) {
9424                    Bundle info = new Bundle();
9425                    info.putString("shortMsg", "keyDispatchingTimedOut");
9426                    info.putString("longMsg", annotation);
9427                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9428                    return true;
9429                }
9430            }
9431            mHandler.post(new Runnable() {
9432                @Override
9433                public void run() {
9434                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9435                }
9436            });
9437        }
9438
9439        return true;
9440    }
9441
9442    public Bundle getAssistContextExtras(int requestType) {
9443        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9444                "getAssistContextExtras()");
9445        PendingAssistExtras pae;
9446        Bundle extras = new Bundle();
9447        synchronized (this) {
9448            ActivityRecord activity = getFocusedStack().mResumedActivity;
9449            if (activity == null) {
9450                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9451                return null;
9452            }
9453            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9454            if (activity.app == null || activity.app.thread == null) {
9455                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9456                return extras;
9457            }
9458            if (activity.app.pid == Binder.getCallingPid()) {
9459                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9460                return extras;
9461            }
9462            pae = new PendingAssistExtras(activity);
9463            try {
9464                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9465                        requestType);
9466                mPendingAssistExtras.add(pae);
9467                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9468            } catch (RemoteException e) {
9469                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9470                return extras;
9471            }
9472        }
9473        synchronized (pae) {
9474            while (!pae.haveResult) {
9475                try {
9476                    pae.wait();
9477                } catch (InterruptedException e) {
9478                }
9479            }
9480            if (pae.result != null) {
9481                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9482            }
9483        }
9484        synchronized (this) {
9485            mPendingAssistExtras.remove(pae);
9486            mHandler.removeCallbacks(pae);
9487        }
9488        return extras;
9489    }
9490
9491    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9492        PendingAssistExtras pae = (PendingAssistExtras)token;
9493        synchronized (pae) {
9494            pae.result = extras;
9495            pae.haveResult = true;
9496            pae.notifyAll();
9497        }
9498    }
9499
9500    public void registerProcessObserver(IProcessObserver observer) {
9501        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9502                "registerProcessObserver()");
9503        synchronized (this) {
9504            mProcessObservers.register(observer);
9505        }
9506    }
9507
9508    @Override
9509    public void unregisterProcessObserver(IProcessObserver observer) {
9510        synchronized (this) {
9511            mProcessObservers.unregister(observer);
9512        }
9513    }
9514
9515    @Override
9516    public boolean convertFromTranslucent(IBinder token) {
9517        final long origId = Binder.clearCallingIdentity();
9518        try {
9519            synchronized (this) {
9520                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9521                if (r == null) {
9522                    return false;
9523                }
9524                if (r.changeWindowTranslucency(true)) {
9525                    mWindowManager.setAppFullscreen(token, true);
9526                    r.task.stack.releaseMediaResources();
9527                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9528                    return true;
9529                }
9530                return false;
9531            }
9532        } finally {
9533            Binder.restoreCallingIdentity(origId);
9534        }
9535    }
9536
9537    @Override
9538    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9539        final long origId = Binder.clearCallingIdentity();
9540        try {
9541            synchronized (this) {
9542                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9543                if (r == null) {
9544                    return false;
9545                }
9546                if (r.changeWindowTranslucency(false)) {
9547                    r.task.stack.convertToTranslucent(r, options);
9548                    mWindowManager.setAppFullscreen(token, false);
9549                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9550                    return true;
9551                } else {
9552                    r.task.stack.mReturningActivityOptions = options;
9553                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9554                    return false;
9555                }
9556            }
9557        } finally {
9558            Binder.restoreCallingIdentity(origId);
9559        }
9560    }
9561
9562    @Override
9563    public boolean setMediaPlaying(IBinder token, boolean playing) {
9564        final long origId = Binder.clearCallingIdentity();
9565        try {
9566            synchronized (this) {
9567                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9568                if (r != null) {
9569                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9570                }
9571            }
9572            return false;
9573        } finally {
9574            Binder.restoreCallingIdentity(origId);
9575        }
9576    }
9577
9578    @Override
9579    public boolean isBackgroundMediaPlaying(IBinder token) {
9580        final long origId = Binder.clearCallingIdentity();
9581        try {
9582            synchronized (this) {
9583                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9584                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9585                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9586                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9587                return playing;
9588            }
9589        } finally {
9590            Binder.restoreCallingIdentity(origId);
9591        }
9592    }
9593
9594    @Override
9595    public ActivityOptions getActivityOptions(IBinder token) {
9596        final long origId = Binder.clearCallingIdentity();
9597        try {
9598            synchronized (this) {
9599                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9600                if (r != null) {
9601                    final ActivityOptions activityOptions = r.pendingOptions;
9602                    r.pendingOptions = null;
9603                    return activityOptions;
9604                }
9605                return null;
9606            }
9607        } finally {
9608            Binder.restoreCallingIdentity(origId);
9609        }
9610    }
9611
9612    @Override
9613    public void setImmersive(IBinder token, boolean immersive) {
9614        synchronized(this) {
9615            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9616            if (r == null) {
9617                throw new IllegalArgumentException();
9618            }
9619            r.immersive = immersive;
9620
9621            // update associated state if we're frontmost
9622            if (r == mFocusedActivity) {
9623                if (DEBUG_IMMERSIVE) {
9624                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9625                }
9626                applyUpdateLockStateLocked(r);
9627            }
9628        }
9629    }
9630
9631    @Override
9632    public boolean isImmersive(IBinder token) {
9633        synchronized (this) {
9634            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9635            if (r == null) {
9636                throw new IllegalArgumentException();
9637            }
9638            return r.immersive;
9639        }
9640    }
9641
9642    public boolean isTopActivityImmersive() {
9643        enforceNotIsolatedCaller("startActivity");
9644        synchronized (this) {
9645            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9646            return (r != null) ? r.immersive : false;
9647        }
9648    }
9649
9650    @Override
9651    public boolean isTopOfTask(IBinder token) {
9652        synchronized (this) {
9653            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9654            if (r == null) {
9655                throw new IllegalArgumentException();
9656            }
9657            return r.task.getTopActivity() == r;
9658        }
9659    }
9660
9661    public final void enterSafeMode() {
9662        synchronized(this) {
9663            // It only makes sense to do this before the system is ready
9664            // and started launching other packages.
9665            if (!mSystemReady) {
9666                try {
9667                    AppGlobals.getPackageManager().enterSafeMode();
9668                } catch (RemoteException e) {
9669                }
9670            }
9671
9672            mSafeMode = true;
9673        }
9674    }
9675
9676    public final void showSafeModeOverlay() {
9677        View v = LayoutInflater.from(mContext).inflate(
9678                com.android.internal.R.layout.safe_mode, null);
9679        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9680        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9681        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9682        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9683        lp.gravity = Gravity.BOTTOM | Gravity.START;
9684        lp.format = v.getBackground().getOpacity();
9685        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9686                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9687        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9688        ((WindowManager)mContext.getSystemService(
9689                Context.WINDOW_SERVICE)).addView(v, lp);
9690    }
9691
9692    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9693        if (!(sender instanceof PendingIntentRecord)) {
9694            return;
9695        }
9696        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9697        synchronized (stats) {
9698            if (mBatteryStatsService.isOnBattery()) {
9699                mBatteryStatsService.enforceCallingPermission();
9700                PendingIntentRecord rec = (PendingIntentRecord)sender;
9701                int MY_UID = Binder.getCallingUid();
9702                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9703                BatteryStatsImpl.Uid.Pkg pkg =
9704                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9705                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9706                pkg.incWakeupsLocked();
9707            }
9708        }
9709    }
9710
9711    public boolean killPids(int[] pids, String pReason, boolean secure) {
9712        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9713            throw new SecurityException("killPids only available to the system");
9714        }
9715        String reason = (pReason == null) ? "Unknown" : pReason;
9716        // XXX Note: don't acquire main activity lock here, because the window
9717        // manager calls in with its locks held.
9718
9719        boolean killed = false;
9720        synchronized (mPidsSelfLocked) {
9721            int[] types = new int[pids.length];
9722            int worstType = 0;
9723            for (int i=0; i<pids.length; i++) {
9724                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9725                if (proc != null) {
9726                    int type = proc.setAdj;
9727                    types[i] = type;
9728                    if (type > worstType) {
9729                        worstType = type;
9730                    }
9731                }
9732            }
9733
9734            // If the worst oom_adj is somewhere in the cached proc LRU range,
9735            // then constrain it so we will kill all cached procs.
9736            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9737                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9738                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9739            }
9740
9741            // If this is not a secure call, don't let it kill processes that
9742            // are important.
9743            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9744                worstType = ProcessList.SERVICE_ADJ;
9745            }
9746
9747            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9748            for (int i=0; i<pids.length; i++) {
9749                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9750                if (proc == null) {
9751                    continue;
9752                }
9753                int adj = proc.setAdj;
9754                if (adj >= worstType && !proc.killedByAm) {
9755                    killUnneededProcessLocked(proc, reason);
9756                    killed = true;
9757                }
9758            }
9759        }
9760        return killed;
9761    }
9762
9763    @Override
9764    public void killUid(int uid, String reason) {
9765        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9766            throw new SecurityException("killUid only available to the system");
9767        }
9768        synchronized (this) {
9769            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9770                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9771                    reason != null ? reason : "kill uid");
9772        }
9773    }
9774
9775    @Override
9776    public boolean killProcessesBelowForeground(String reason) {
9777        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9778            throw new SecurityException("killProcessesBelowForeground() only available to system");
9779        }
9780
9781        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9782    }
9783
9784    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9785        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9786            throw new SecurityException("killProcessesBelowAdj() only available to system");
9787        }
9788
9789        boolean killed = false;
9790        synchronized (mPidsSelfLocked) {
9791            final int size = mPidsSelfLocked.size();
9792            for (int i = 0; i < size; i++) {
9793                final int pid = mPidsSelfLocked.keyAt(i);
9794                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9795                if (proc == null) continue;
9796
9797                final int adj = proc.setAdj;
9798                if (adj > belowAdj && !proc.killedByAm) {
9799                    killUnneededProcessLocked(proc, reason);
9800                    killed = true;
9801                }
9802            }
9803        }
9804        return killed;
9805    }
9806
9807    @Override
9808    public void hang(final IBinder who, boolean allowRestart) {
9809        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9810                != PackageManager.PERMISSION_GRANTED) {
9811            throw new SecurityException("Requires permission "
9812                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9813        }
9814
9815        final IBinder.DeathRecipient death = new DeathRecipient() {
9816            @Override
9817            public void binderDied() {
9818                synchronized (this) {
9819                    notifyAll();
9820                }
9821            }
9822        };
9823
9824        try {
9825            who.linkToDeath(death, 0);
9826        } catch (RemoteException e) {
9827            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9828            return;
9829        }
9830
9831        synchronized (this) {
9832            Watchdog.getInstance().setAllowRestart(allowRestart);
9833            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9834            synchronized (death) {
9835                while (who.isBinderAlive()) {
9836                    try {
9837                        death.wait();
9838                    } catch (InterruptedException e) {
9839                    }
9840                }
9841            }
9842            Watchdog.getInstance().setAllowRestart(true);
9843        }
9844    }
9845
9846    @Override
9847    public void restart() {
9848        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9849                != PackageManager.PERMISSION_GRANTED) {
9850            throw new SecurityException("Requires permission "
9851                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9852        }
9853
9854        Log.i(TAG, "Sending shutdown broadcast...");
9855
9856        BroadcastReceiver br = new BroadcastReceiver() {
9857            @Override public void onReceive(Context context, Intent intent) {
9858                // Now the broadcast is done, finish up the low-level shutdown.
9859                Log.i(TAG, "Shutting down activity manager...");
9860                shutdown(10000);
9861                Log.i(TAG, "Shutdown complete, restarting!");
9862                Process.killProcess(Process.myPid());
9863                System.exit(10);
9864            }
9865        };
9866
9867        // First send the high-level shut down broadcast.
9868        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9869        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9870        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9871        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9872        mContext.sendOrderedBroadcastAsUser(intent,
9873                UserHandle.ALL, null, br, mHandler, 0, null, null);
9874        */
9875        br.onReceive(mContext, intent);
9876    }
9877
9878    private long getLowRamTimeSinceIdle(long now) {
9879        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9880    }
9881
9882    @Override
9883    public void performIdleMaintenance() {
9884        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9885                != PackageManager.PERMISSION_GRANTED) {
9886            throw new SecurityException("Requires permission "
9887                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9888        }
9889
9890        synchronized (this) {
9891            final long now = SystemClock.uptimeMillis();
9892            final long timeSinceLastIdle = now - mLastIdleTime;
9893            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9894            mLastIdleTime = now;
9895            mLowRamTimeSinceLastIdle = 0;
9896            if (mLowRamStartTime != 0) {
9897                mLowRamStartTime = now;
9898            }
9899
9900            StringBuilder sb = new StringBuilder(128);
9901            sb.append("Idle maintenance over ");
9902            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9903            sb.append(" low RAM for ");
9904            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9905            Slog.i(TAG, sb.toString());
9906
9907            // If at least 1/3 of our time since the last idle period has been spent
9908            // with RAM low, then we want to kill processes.
9909            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9910
9911            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9912                ProcessRecord proc = mLruProcesses.get(i);
9913                if (proc.notCachedSinceIdle) {
9914                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9915                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9916                        if (doKilling && proc.initialIdlePss != 0
9917                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9918                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9919                                    + " from " + proc.initialIdlePss + ")");
9920                        }
9921                    }
9922                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9923                    proc.notCachedSinceIdle = true;
9924                    proc.initialIdlePss = 0;
9925                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9926                            isSleeping(), now);
9927                }
9928            }
9929
9930            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9931            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9932        }
9933    }
9934
9935    private void retrieveSettings() {
9936        final ContentResolver resolver = mContext.getContentResolver();
9937        String debugApp = Settings.Global.getString(
9938            resolver, Settings.Global.DEBUG_APP);
9939        boolean waitForDebugger = Settings.Global.getInt(
9940            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9941        boolean alwaysFinishActivities = Settings.Global.getInt(
9942            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9943        boolean forceRtl = Settings.Global.getInt(
9944                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9945        // Transfer any global setting for forcing RTL layout, into a System Property
9946        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9947
9948        Configuration configuration = new Configuration();
9949        Settings.System.getConfiguration(resolver, configuration);
9950        if (forceRtl) {
9951            // This will take care of setting the correct layout direction flags
9952            configuration.setLayoutDirection(configuration.locale);
9953        }
9954
9955        synchronized (this) {
9956            mDebugApp = mOrigDebugApp = debugApp;
9957            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9958            mAlwaysFinishActivities = alwaysFinishActivities;
9959            // This happens before any activities are started, so we can
9960            // change mConfiguration in-place.
9961            updateConfigurationLocked(configuration, null, false, true);
9962            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9963        }
9964    }
9965
9966    public boolean testIsSystemReady() {
9967        // no need to synchronize(this) just to read & return the value
9968        return mSystemReady;
9969    }
9970
9971    private static File getCalledPreBootReceiversFile() {
9972        File dataDir = Environment.getDataDirectory();
9973        File systemDir = new File(dataDir, "system");
9974        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
9975        return fname;
9976    }
9977
9978    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9979        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9980        File file = getCalledPreBootReceiversFile();
9981        FileInputStream fis = null;
9982        try {
9983            fis = new FileInputStream(file);
9984            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9985            int fvers = dis.readInt();
9986            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
9987                String vers = dis.readUTF();
9988                String codename = dis.readUTF();
9989                String build = dis.readUTF();
9990                if (android.os.Build.VERSION.RELEASE.equals(vers)
9991                        && android.os.Build.VERSION.CODENAME.equals(codename)
9992                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9993                    int num = dis.readInt();
9994                    while (num > 0) {
9995                        num--;
9996                        String pkg = dis.readUTF();
9997                        String cls = dis.readUTF();
9998                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9999                    }
10000                }
10001            }
10002        } catch (FileNotFoundException e) {
10003        } catch (IOException e) {
10004            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10005        } finally {
10006            if (fis != null) {
10007                try {
10008                    fis.close();
10009                } catch (IOException e) {
10010                }
10011            }
10012        }
10013        return lastDoneReceivers;
10014    }
10015
10016    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10017        File file = getCalledPreBootReceiversFile();
10018        FileOutputStream fos = null;
10019        DataOutputStream dos = null;
10020        try {
10021            fos = new FileOutputStream(file);
10022            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10023            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10024            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10025            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10026            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10027            dos.writeInt(list.size());
10028            for (int i=0; i<list.size(); i++) {
10029                dos.writeUTF(list.get(i).getPackageName());
10030                dos.writeUTF(list.get(i).getClassName());
10031            }
10032        } catch (IOException e) {
10033            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10034            file.delete();
10035        } finally {
10036            FileUtils.sync(fos);
10037            if (dos != null) {
10038                try {
10039                    dos.close();
10040                } catch (IOException e) {
10041                    // TODO Auto-generated catch block
10042                    e.printStackTrace();
10043                }
10044            }
10045        }
10046    }
10047
10048    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10049            ArrayList<ComponentName> doneReceivers, int userId) {
10050        boolean waitingUpdate = false;
10051        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10052        List<ResolveInfo> ris = null;
10053        try {
10054            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10055                    intent, null, 0, userId);
10056        } catch (RemoteException e) {
10057        }
10058        if (ris != null) {
10059            for (int i=ris.size()-1; i>=0; i--) {
10060                if ((ris.get(i).activityInfo.applicationInfo.flags
10061                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10062                    ris.remove(i);
10063                }
10064            }
10065            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10066
10067            // For User 0, load the version number. When delivering to a new user, deliver
10068            // to all receivers.
10069            if (userId == UserHandle.USER_OWNER) {
10070                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10071                for (int i=0; i<ris.size(); i++) {
10072                    ActivityInfo ai = ris.get(i).activityInfo;
10073                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10074                    if (lastDoneReceivers.contains(comp)) {
10075                        // We already did the pre boot receiver for this app with the current
10076                        // platform version, so don't do it again...
10077                        ris.remove(i);
10078                        i--;
10079                        // ...however, do keep it as one that has been done, so we don't
10080                        // forget about it when rewriting the file of last done receivers.
10081                        doneReceivers.add(comp);
10082                    }
10083                }
10084            }
10085
10086            // If primary user, send broadcast to all available users, else just to userId
10087            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10088                    : new int[] { userId };
10089            for (int i = 0; i < ris.size(); i++) {
10090                ActivityInfo ai = ris.get(i).activityInfo;
10091                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10092                doneReceivers.add(comp);
10093                intent.setComponent(comp);
10094                for (int j=0; j<users.length; j++) {
10095                    IIntentReceiver finisher = null;
10096                    // On last receiver and user, set up a completion callback
10097                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10098                        finisher = new IIntentReceiver.Stub() {
10099                            public void performReceive(Intent intent, int resultCode,
10100                                    String data, Bundle extras, boolean ordered,
10101                                    boolean sticky, int sendingUser) {
10102                                // The raw IIntentReceiver interface is called
10103                                // with the AM lock held, so redispatch to
10104                                // execute our code without the lock.
10105                                mHandler.post(onFinishCallback);
10106                            }
10107                        };
10108                    }
10109                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10110                            + " for user " + users[j]);
10111                    broadcastIntentLocked(null, null, intent, null, finisher,
10112                            0, null, null, null, AppOpsManager.OP_NONE,
10113                            true, false, MY_PID, Process.SYSTEM_UID,
10114                            users[j]);
10115                    if (finisher != null) {
10116                        waitingUpdate = true;
10117                    }
10118                }
10119            }
10120        }
10121
10122        return waitingUpdate;
10123    }
10124
10125    public void systemReady(final Runnable goingCallback) {
10126        synchronized(this) {
10127            if (mSystemReady) {
10128                // If we're done calling all the receivers, run the next "boot phase" passed in
10129                // by the SystemServer
10130                if (goingCallback != null) {
10131                    goingCallback.run();
10132                }
10133                return;
10134            }
10135
10136            // Make sure we have the current profile info, since it is needed for
10137            // security checks.
10138            updateCurrentProfileIdsLocked();
10139
10140            if (mRecentTasks == null) {
10141                mRecentTasks = mTaskPersister.restoreTasksLocked();
10142                if (!mRecentTasks.isEmpty()) {
10143                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10144                }
10145                mTaskPersister.startPersisting();
10146            }
10147
10148            // Check to see if there are any update receivers to run.
10149            if (!mDidUpdate) {
10150                if (mWaitingUpdate) {
10151                    return;
10152                }
10153                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10154                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10155                    public void run() {
10156                        synchronized (ActivityManagerService.this) {
10157                            mDidUpdate = true;
10158                        }
10159                        writeLastDonePreBootReceivers(doneReceivers);
10160                        showBootMessage(mContext.getText(
10161                                R.string.android_upgrading_complete),
10162                                false);
10163                        systemReady(goingCallback);
10164                    }
10165                }, doneReceivers, UserHandle.USER_OWNER);
10166
10167                if (mWaitingUpdate) {
10168                    return;
10169                }
10170                mDidUpdate = true;
10171            }
10172
10173            mAppOpsService.systemReady();
10174            mSystemReady = true;
10175        }
10176
10177        ArrayList<ProcessRecord> procsToKill = null;
10178        synchronized(mPidsSelfLocked) {
10179            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10180                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10181                if (!isAllowedWhileBooting(proc.info)){
10182                    if (procsToKill == null) {
10183                        procsToKill = new ArrayList<ProcessRecord>();
10184                    }
10185                    procsToKill.add(proc);
10186                }
10187            }
10188        }
10189
10190        synchronized(this) {
10191            if (procsToKill != null) {
10192                for (int i=procsToKill.size()-1; i>=0; i--) {
10193                    ProcessRecord proc = procsToKill.get(i);
10194                    Slog.i(TAG, "Removing system update proc: " + proc);
10195                    removeProcessLocked(proc, true, false, "system update done");
10196                }
10197            }
10198
10199            // Now that we have cleaned up any update processes, we
10200            // are ready to start launching real processes and know that
10201            // we won't trample on them any more.
10202            mProcessesReady = true;
10203        }
10204
10205        Slog.i(TAG, "System now ready");
10206        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10207            SystemClock.uptimeMillis());
10208
10209        synchronized(this) {
10210            // Make sure we have no pre-ready processes sitting around.
10211
10212            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10213                ResolveInfo ri = mContext.getPackageManager()
10214                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10215                                STOCK_PM_FLAGS);
10216                CharSequence errorMsg = null;
10217                if (ri != null) {
10218                    ActivityInfo ai = ri.activityInfo;
10219                    ApplicationInfo app = ai.applicationInfo;
10220                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10221                        mTopAction = Intent.ACTION_FACTORY_TEST;
10222                        mTopData = null;
10223                        mTopComponent = new ComponentName(app.packageName,
10224                                ai.name);
10225                    } else {
10226                        errorMsg = mContext.getResources().getText(
10227                                com.android.internal.R.string.factorytest_not_system);
10228                    }
10229                } else {
10230                    errorMsg = mContext.getResources().getText(
10231                            com.android.internal.R.string.factorytest_no_action);
10232                }
10233                if (errorMsg != null) {
10234                    mTopAction = null;
10235                    mTopData = null;
10236                    mTopComponent = null;
10237                    Message msg = Message.obtain();
10238                    msg.what = SHOW_FACTORY_ERROR_MSG;
10239                    msg.getData().putCharSequence("msg", errorMsg);
10240                    mHandler.sendMessage(msg);
10241                }
10242            }
10243        }
10244
10245        retrieveSettings();
10246
10247        synchronized (this) {
10248            readGrantedUriPermissionsLocked();
10249        }
10250
10251        if (goingCallback != null) goingCallback.run();
10252
10253        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10254                Integer.toString(mCurrentUserId), mCurrentUserId);
10255        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10256                Integer.toString(mCurrentUserId), mCurrentUserId);
10257        mSystemServiceManager.startUser(mCurrentUserId);
10258
10259        synchronized (this) {
10260            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10261                try {
10262                    List apps = AppGlobals.getPackageManager().
10263                        getPersistentApplications(STOCK_PM_FLAGS);
10264                    if (apps != null) {
10265                        int N = apps.size();
10266                        int i;
10267                        for (i=0; i<N; i++) {
10268                            ApplicationInfo info
10269                                = (ApplicationInfo)apps.get(i);
10270                            if (info != null &&
10271                                    !info.packageName.equals("android")) {
10272                                addAppLocked(info, false, null /* ABI override */);
10273                            }
10274                        }
10275                    }
10276                } catch (RemoteException ex) {
10277                    // pm is in same process, this will never happen.
10278                }
10279            }
10280
10281            // Start up initial activity.
10282            mBooting = true;
10283
10284            try {
10285                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10286                    Message msg = Message.obtain();
10287                    msg.what = SHOW_UID_ERROR_MSG;
10288                    mHandler.sendMessage(msg);
10289                }
10290            } catch (RemoteException e) {
10291            }
10292
10293            long ident = Binder.clearCallingIdentity();
10294            try {
10295                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10296                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10297                        | Intent.FLAG_RECEIVER_FOREGROUND);
10298                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10299                broadcastIntentLocked(null, null, intent,
10300                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10301                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10302                intent = new Intent(Intent.ACTION_USER_STARTING);
10303                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10304                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10305                broadcastIntentLocked(null, null, intent,
10306                        null, new IIntentReceiver.Stub() {
10307                            @Override
10308                            public void performReceive(Intent intent, int resultCode, String data,
10309                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10310                                    throws RemoteException {
10311                            }
10312                        }, 0, null, null,
10313                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10314                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10315            } catch (Throwable t) {
10316                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10317            } finally {
10318                Binder.restoreCallingIdentity(ident);
10319            }
10320            mStackSupervisor.resumeTopActivitiesLocked();
10321            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10322        }
10323    }
10324
10325    private boolean makeAppCrashingLocked(ProcessRecord app,
10326            String shortMsg, String longMsg, String stackTrace) {
10327        app.crashing = true;
10328        app.crashingReport = generateProcessError(app,
10329                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10330        startAppProblemLocked(app);
10331        app.stopFreezingAllLocked();
10332        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10333    }
10334
10335    private void makeAppNotRespondingLocked(ProcessRecord app,
10336            String activity, String shortMsg, String longMsg) {
10337        app.notResponding = true;
10338        app.notRespondingReport = generateProcessError(app,
10339                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10340                activity, shortMsg, longMsg, null);
10341        startAppProblemLocked(app);
10342        app.stopFreezingAllLocked();
10343    }
10344
10345    /**
10346     * Generate a process error record, suitable for attachment to a ProcessRecord.
10347     *
10348     * @param app The ProcessRecord in which the error occurred.
10349     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10350     *                      ActivityManager.AppErrorStateInfo
10351     * @param activity The activity associated with the crash, if known.
10352     * @param shortMsg Short message describing the crash.
10353     * @param longMsg Long message describing the crash.
10354     * @param stackTrace Full crash stack trace, may be null.
10355     *
10356     * @return Returns a fully-formed AppErrorStateInfo record.
10357     */
10358    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10359            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10360        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10361
10362        report.condition = condition;
10363        report.processName = app.processName;
10364        report.pid = app.pid;
10365        report.uid = app.info.uid;
10366        report.tag = activity;
10367        report.shortMsg = shortMsg;
10368        report.longMsg = longMsg;
10369        report.stackTrace = stackTrace;
10370
10371        return report;
10372    }
10373
10374    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10375        synchronized (this) {
10376            app.crashing = false;
10377            app.crashingReport = null;
10378            app.notResponding = false;
10379            app.notRespondingReport = null;
10380            if (app.anrDialog == fromDialog) {
10381                app.anrDialog = null;
10382            }
10383            if (app.waitDialog == fromDialog) {
10384                app.waitDialog = null;
10385            }
10386            if (app.pid > 0 && app.pid != MY_PID) {
10387                handleAppCrashLocked(app, null, null, null);
10388                killUnneededProcessLocked(app, "user request after error");
10389            }
10390        }
10391    }
10392
10393    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10394            String stackTrace) {
10395        long now = SystemClock.uptimeMillis();
10396
10397        Long crashTime;
10398        if (!app.isolated) {
10399            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10400        } else {
10401            crashTime = null;
10402        }
10403        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10404            // This process loses!
10405            Slog.w(TAG, "Process " + app.info.processName
10406                    + " has crashed too many times: killing!");
10407            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10408                    app.userId, app.info.processName, app.uid);
10409            mStackSupervisor.handleAppCrashLocked(app);
10410            if (!app.persistent) {
10411                // We don't want to start this process again until the user
10412                // explicitly does so...  but for persistent process, we really
10413                // need to keep it running.  If a persistent process is actually
10414                // repeatedly crashing, then badness for everyone.
10415                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10416                        app.info.processName);
10417                if (!app.isolated) {
10418                    // XXX We don't have a way to mark isolated processes
10419                    // as bad, since they don't have a peristent identity.
10420                    mBadProcesses.put(app.info.processName, app.uid,
10421                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10422                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10423                }
10424                app.bad = true;
10425                app.removed = true;
10426                // Don't let services in this process be restarted and potentially
10427                // annoy the user repeatedly.  Unless it is persistent, since those
10428                // processes run critical code.
10429                removeProcessLocked(app, false, false, "crash");
10430                mStackSupervisor.resumeTopActivitiesLocked();
10431                return false;
10432            }
10433            mStackSupervisor.resumeTopActivitiesLocked();
10434        } else {
10435            mStackSupervisor.finishTopRunningActivityLocked(app);
10436        }
10437
10438        // Bump up the crash count of any services currently running in the proc.
10439        for (int i=app.services.size()-1; i>=0; i--) {
10440            // Any services running in the application need to be placed
10441            // back in the pending list.
10442            ServiceRecord sr = app.services.valueAt(i);
10443            sr.crashCount++;
10444        }
10445
10446        // If the crashing process is what we consider to be the "home process" and it has been
10447        // replaced by a third-party app, clear the package preferred activities from packages
10448        // with a home activity running in the process to prevent a repeatedly crashing app
10449        // from blocking the user to manually clear the list.
10450        final ArrayList<ActivityRecord> activities = app.activities;
10451        if (app == mHomeProcess && activities.size() > 0
10452                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10453            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10454                final ActivityRecord r = activities.get(activityNdx);
10455                if (r.isHomeActivity()) {
10456                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10457                    try {
10458                        ActivityThread.getPackageManager()
10459                                .clearPackagePreferredActivities(r.packageName);
10460                    } catch (RemoteException c) {
10461                        // pm is in same process, this will never happen.
10462                    }
10463                }
10464            }
10465        }
10466
10467        if (!app.isolated) {
10468            // XXX Can't keep track of crash times for isolated processes,
10469            // because they don't have a perisistent identity.
10470            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10471        }
10472
10473        return true;
10474    }
10475
10476    void startAppProblemLocked(ProcessRecord app) {
10477        if (app.userId == mCurrentUserId) {
10478            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10479                    mContext, app.info.packageName, app.info.flags);
10480        } else {
10481            // If this app is not running under the current user, then we
10482            // can't give it a report button because that would require
10483            // launching the report UI under a different user.
10484            app.errorReportReceiver = null;
10485        }
10486        skipCurrentReceiverLocked(app);
10487    }
10488
10489    void skipCurrentReceiverLocked(ProcessRecord app) {
10490        for (BroadcastQueue queue : mBroadcastQueues) {
10491            queue.skipCurrentReceiverLocked(app);
10492        }
10493    }
10494
10495    /**
10496     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10497     * The application process will exit immediately after this call returns.
10498     * @param app object of the crashing app, null for the system server
10499     * @param crashInfo describing the exception
10500     */
10501    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10502        ProcessRecord r = findAppProcess(app, "Crash");
10503        final String processName = app == null ? "system_server"
10504                : (r == null ? "unknown" : r.processName);
10505
10506        handleApplicationCrashInner("crash", r, processName, crashInfo);
10507    }
10508
10509    /* Native crash reporting uses this inner version because it needs to be somewhat
10510     * decoupled from the AM-managed cleanup lifecycle
10511     */
10512    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10513            ApplicationErrorReport.CrashInfo crashInfo) {
10514        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10515                UserHandle.getUserId(Binder.getCallingUid()), processName,
10516                r == null ? -1 : r.info.flags,
10517                crashInfo.exceptionClassName,
10518                crashInfo.exceptionMessage,
10519                crashInfo.throwFileName,
10520                crashInfo.throwLineNumber);
10521
10522        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10523
10524        crashApplication(r, crashInfo);
10525    }
10526
10527    public void handleApplicationStrictModeViolation(
10528            IBinder app,
10529            int violationMask,
10530            StrictMode.ViolationInfo info) {
10531        ProcessRecord r = findAppProcess(app, "StrictMode");
10532        if (r == null) {
10533            return;
10534        }
10535
10536        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10537            Integer stackFingerprint = info.hashCode();
10538            boolean logIt = true;
10539            synchronized (mAlreadyLoggedViolatedStacks) {
10540                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10541                    logIt = false;
10542                    // TODO: sub-sample into EventLog for these, with
10543                    // the info.durationMillis?  Then we'd get
10544                    // the relative pain numbers, without logging all
10545                    // the stack traces repeatedly.  We'd want to do
10546                    // likewise in the client code, which also does
10547                    // dup suppression, before the Binder call.
10548                } else {
10549                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10550                        mAlreadyLoggedViolatedStacks.clear();
10551                    }
10552                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10553                }
10554            }
10555            if (logIt) {
10556                logStrictModeViolationToDropBox(r, info);
10557            }
10558        }
10559
10560        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10561            AppErrorResult result = new AppErrorResult();
10562            synchronized (this) {
10563                final long origId = Binder.clearCallingIdentity();
10564
10565                Message msg = Message.obtain();
10566                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10567                HashMap<String, Object> data = new HashMap<String, Object>();
10568                data.put("result", result);
10569                data.put("app", r);
10570                data.put("violationMask", violationMask);
10571                data.put("info", info);
10572                msg.obj = data;
10573                mHandler.sendMessage(msg);
10574
10575                Binder.restoreCallingIdentity(origId);
10576            }
10577            int res = result.get();
10578            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10579        }
10580    }
10581
10582    // Depending on the policy in effect, there could be a bunch of
10583    // these in quick succession so we try to batch these together to
10584    // minimize disk writes, number of dropbox entries, and maximize
10585    // compression, by having more fewer, larger records.
10586    private void logStrictModeViolationToDropBox(
10587            ProcessRecord process,
10588            StrictMode.ViolationInfo info) {
10589        if (info == null) {
10590            return;
10591        }
10592        final boolean isSystemApp = process == null ||
10593                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10594                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10595        final String processName = process == null ? "unknown" : process.processName;
10596        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10597        final DropBoxManager dbox = (DropBoxManager)
10598                mContext.getSystemService(Context.DROPBOX_SERVICE);
10599
10600        // Exit early if the dropbox isn't configured to accept this report type.
10601        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10602
10603        boolean bufferWasEmpty;
10604        boolean needsFlush;
10605        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10606        synchronized (sb) {
10607            bufferWasEmpty = sb.length() == 0;
10608            appendDropBoxProcessHeaders(process, processName, sb);
10609            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10610            sb.append("System-App: ").append(isSystemApp).append("\n");
10611            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10612            if (info.violationNumThisLoop != 0) {
10613                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10614            }
10615            if (info.numAnimationsRunning != 0) {
10616                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10617            }
10618            if (info.broadcastIntentAction != null) {
10619                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10620            }
10621            if (info.durationMillis != -1) {
10622                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10623            }
10624            if (info.numInstances != -1) {
10625                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10626            }
10627            if (info.tags != null) {
10628                for (String tag : info.tags) {
10629                    sb.append("Span-Tag: ").append(tag).append("\n");
10630                }
10631            }
10632            sb.append("\n");
10633            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10634                sb.append(info.crashInfo.stackTrace);
10635            }
10636            sb.append("\n");
10637
10638            // Only buffer up to ~64k.  Various logging bits truncate
10639            // things at 128k.
10640            needsFlush = (sb.length() > 64 * 1024);
10641        }
10642
10643        // Flush immediately if the buffer's grown too large, or this
10644        // is a non-system app.  Non-system apps are isolated with a
10645        // different tag & policy and not batched.
10646        //
10647        // Batching is useful during internal testing with
10648        // StrictMode settings turned up high.  Without batching,
10649        // thousands of separate files could be created on boot.
10650        if (!isSystemApp || needsFlush) {
10651            new Thread("Error dump: " + dropboxTag) {
10652                @Override
10653                public void run() {
10654                    String report;
10655                    synchronized (sb) {
10656                        report = sb.toString();
10657                        sb.delete(0, sb.length());
10658                        sb.trimToSize();
10659                    }
10660                    if (report.length() != 0) {
10661                        dbox.addText(dropboxTag, report);
10662                    }
10663                }
10664            }.start();
10665            return;
10666        }
10667
10668        // System app batching:
10669        if (!bufferWasEmpty) {
10670            // An existing dropbox-writing thread is outstanding, so
10671            // we don't need to start it up.  The existing thread will
10672            // catch the buffer appends we just did.
10673            return;
10674        }
10675
10676        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10677        // (After this point, we shouldn't access AMS internal data structures.)
10678        new Thread("Error dump: " + dropboxTag) {
10679            @Override
10680            public void run() {
10681                // 5 second sleep to let stacks arrive and be batched together
10682                try {
10683                    Thread.sleep(5000);  // 5 seconds
10684                } catch (InterruptedException e) {}
10685
10686                String errorReport;
10687                synchronized (mStrictModeBuffer) {
10688                    errorReport = mStrictModeBuffer.toString();
10689                    if (errorReport.length() == 0) {
10690                        return;
10691                    }
10692                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10693                    mStrictModeBuffer.trimToSize();
10694                }
10695                dbox.addText(dropboxTag, errorReport);
10696            }
10697        }.start();
10698    }
10699
10700    /**
10701     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10702     * @param app object of the crashing app, null for the system server
10703     * @param tag reported by the caller
10704     * @param crashInfo describing the context of the error
10705     * @return true if the process should exit immediately (WTF is fatal)
10706     */
10707    public boolean handleApplicationWtf(IBinder app, String tag,
10708            ApplicationErrorReport.CrashInfo crashInfo) {
10709        ProcessRecord r = findAppProcess(app, "WTF");
10710        final String processName = app == null ? "system_server"
10711                : (r == null ? "unknown" : r.processName);
10712
10713        EventLog.writeEvent(EventLogTags.AM_WTF,
10714                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10715                processName,
10716                r == null ? -1 : r.info.flags,
10717                tag, crashInfo.exceptionMessage);
10718
10719        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10720
10721        if (r != null && r.pid != Process.myPid() &&
10722                Settings.Global.getInt(mContext.getContentResolver(),
10723                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10724            crashApplication(r, crashInfo);
10725            return true;
10726        } else {
10727            return false;
10728        }
10729    }
10730
10731    /**
10732     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10733     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10734     */
10735    private ProcessRecord findAppProcess(IBinder app, String reason) {
10736        if (app == null) {
10737            return null;
10738        }
10739
10740        synchronized (this) {
10741            final int NP = mProcessNames.getMap().size();
10742            for (int ip=0; ip<NP; ip++) {
10743                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10744                final int NA = apps.size();
10745                for (int ia=0; ia<NA; ia++) {
10746                    ProcessRecord p = apps.valueAt(ia);
10747                    if (p.thread != null && p.thread.asBinder() == app) {
10748                        return p;
10749                    }
10750                }
10751            }
10752
10753            Slog.w(TAG, "Can't find mystery application for " + reason
10754                    + " from pid=" + Binder.getCallingPid()
10755                    + " uid=" + Binder.getCallingUid() + ": " + app);
10756            return null;
10757        }
10758    }
10759
10760    /**
10761     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10762     * to append various headers to the dropbox log text.
10763     */
10764    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10765            StringBuilder sb) {
10766        // Watchdog thread ends up invoking this function (with
10767        // a null ProcessRecord) to add the stack file to dropbox.
10768        // Do not acquire a lock on this (am) in such cases, as it
10769        // could cause a potential deadlock, if and when watchdog
10770        // is invoked due to unavailability of lock on am and it
10771        // would prevent watchdog from killing system_server.
10772        if (process == null) {
10773            sb.append("Process: ").append(processName).append("\n");
10774            return;
10775        }
10776        // Note: ProcessRecord 'process' is guarded by the service
10777        // instance.  (notably process.pkgList, which could otherwise change
10778        // concurrently during execution of this method)
10779        synchronized (this) {
10780            sb.append("Process: ").append(processName).append("\n");
10781            int flags = process.info.flags;
10782            IPackageManager pm = AppGlobals.getPackageManager();
10783            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10784            for (int ip=0; ip<process.pkgList.size(); ip++) {
10785                String pkg = process.pkgList.keyAt(ip);
10786                sb.append("Package: ").append(pkg);
10787                try {
10788                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10789                    if (pi != null) {
10790                        sb.append(" v").append(pi.versionCode);
10791                        if (pi.versionName != null) {
10792                            sb.append(" (").append(pi.versionName).append(")");
10793                        }
10794                    }
10795                } catch (RemoteException e) {
10796                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10797                }
10798                sb.append("\n");
10799            }
10800        }
10801    }
10802
10803    private static String processClass(ProcessRecord process) {
10804        if (process == null || process.pid == MY_PID) {
10805            return "system_server";
10806        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10807            return "system_app";
10808        } else {
10809            return "data_app";
10810        }
10811    }
10812
10813    /**
10814     * Write a description of an error (crash, WTF, ANR) to the drop box.
10815     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10816     * @param process which caused the error, null means the system server
10817     * @param activity which triggered the error, null if unknown
10818     * @param parent activity related to the error, null if unknown
10819     * @param subject line related to the error, null if absent
10820     * @param report in long form describing the error, null if absent
10821     * @param logFile to include in the report, null if none
10822     * @param crashInfo giving an application stack trace, null if absent
10823     */
10824    public void addErrorToDropBox(String eventType,
10825            ProcessRecord process, String processName, ActivityRecord activity,
10826            ActivityRecord parent, String subject,
10827            final String report, final File logFile,
10828            final ApplicationErrorReport.CrashInfo crashInfo) {
10829        // NOTE -- this must never acquire the ActivityManagerService lock,
10830        // otherwise the watchdog may be prevented from resetting the system.
10831
10832        final String dropboxTag = processClass(process) + "_" + eventType;
10833        final DropBoxManager dbox = (DropBoxManager)
10834                mContext.getSystemService(Context.DROPBOX_SERVICE);
10835
10836        // Exit early if the dropbox isn't configured to accept this report type.
10837        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10838
10839        final StringBuilder sb = new StringBuilder(1024);
10840        appendDropBoxProcessHeaders(process, processName, sb);
10841        if (activity != null) {
10842            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10843        }
10844        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10845            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10846        }
10847        if (parent != null && parent != activity) {
10848            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10849        }
10850        if (subject != null) {
10851            sb.append("Subject: ").append(subject).append("\n");
10852        }
10853        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10854        if (Debug.isDebuggerConnected()) {
10855            sb.append("Debugger: Connected\n");
10856        }
10857        sb.append("\n");
10858
10859        // Do the rest in a worker thread to avoid blocking the caller on I/O
10860        // (After this point, we shouldn't access AMS internal data structures.)
10861        Thread worker = new Thread("Error dump: " + dropboxTag) {
10862            @Override
10863            public void run() {
10864                if (report != null) {
10865                    sb.append(report);
10866                }
10867                if (logFile != null) {
10868                    try {
10869                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10870                                    "\n\n[[TRUNCATED]]"));
10871                    } catch (IOException e) {
10872                        Slog.e(TAG, "Error reading " + logFile, e);
10873                    }
10874                }
10875                if (crashInfo != null && crashInfo.stackTrace != null) {
10876                    sb.append(crashInfo.stackTrace);
10877                }
10878
10879                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10880                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10881                if (lines > 0) {
10882                    sb.append("\n");
10883
10884                    // Merge several logcat streams, and take the last N lines
10885                    InputStreamReader input = null;
10886                    try {
10887                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10888                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10889                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10890
10891                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10892                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10893                        input = new InputStreamReader(logcat.getInputStream());
10894
10895                        int num;
10896                        char[] buf = new char[8192];
10897                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10898                    } catch (IOException e) {
10899                        Slog.e(TAG, "Error running logcat", e);
10900                    } finally {
10901                        if (input != null) try { input.close(); } catch (IOException e) {}
10902                    }
10903                }
10904
10905                dbox.addText(dropboxTag, sb.toString());
10906            }
10907        };
10908
10909        if (process == null) {
10910            // If process is null, we are being called from some internal code
10911            // and may be about to die -- run this synchronously.
10912            worker.run();
10913        } else {
10914            worker.start();
10915        }
10916    }
10917
10918    /**
10919     * Bring up the "unexpected error" dialog box for a crashing app.
10920     * Deal with edge cases (intercepts from instrumented applications,
10921     * ActivityController, error intent receivers, that sort of thing).
10922     * @param r the application crashing
10923     * @param crashInfo describing the failure
10924     */
10925    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10926        long timeMillis = System.currentTimeMillis();
10927        String shortMsg = crashInfo.exceptionClassName;
10928        String longMsg = crashInfo.exceptionMessage;
10929        String stackTrace = crashInfo.stackTrace;
10930        if (shortMsg != null && longMsg != null) {
10931            longMsg = shortMsg + ": " + longMsg;
10932        } else if (shortMsg != null) {
10933            longMsg = shortMsg;
10934        }
10935
10936        AppErrorResult result = new AppErrorResult();
10937        synchronized (this) {
10938            if (mController != null) {
10939                try {
10940                    String name = r != null ? r.processName : null;
10941                    int pid = r != null ? r.pid : Binder.getCallingPid();
10942                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10943                    if (!mController.appCrashed(name, pid,
10944                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10945                        Slog.w(TAG, "Force-killing crashed app " + name
10946                                + " at watcher's request");
10947                        Process.killProcess(pid);
10948                        if (r != null) {
10949                            Process.killProcessGroup(uid, pid);
10950                        }
10951                        return;
10952                    }
10953                } catch (RemoteException e) {
10954                    mController = null;
10955                    Watchdog.getInstance().setActivityController(null);
10956                }
10957            }
10958
10959            final long origId = Binder.clearCallingIdentity();
10960
10961            // If this process is running instrumentation, finish it.
10962            if (r != null && r.instrumentationClass != null) {
10963                Slog.w(TAG, "Error in app " + r.processName
10964                      + " running instrumentation " + r.instrumentationClass + ":");
10965                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10966                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10967                Bundle info = new Bundle();
10968                info.putString("shortMsg", shortMsg);
10969                info.putString("longMsg", longMsg);
10970                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10971                Binder.restoreCallingIdentity(origId);
10972                return;
10973            }
10974
10975            // If we can't identify the process or it's already exceeded its crash quota,
10976            // quit right away without showing a crash dialog.
10977            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10978                Binder.restoreCallingIdentity(origId);
10979                return;
10980            }
10981
10982            Message msg = Message.obtain();
10983            msg.what = SHOW_ERROR_MSG;
10984            HashMap data = new HashMap();
10985            data.put("result", result);
10986            data.put("app", r);
10987            msg.obj = data;
10988            mHandler.sendMessage(msg);
10989
10990            Binder.restoreCallingIdentity(origId);
10991        }
10992
10993        int res = result.get();
10994
10995        Intent appErrorIntent = null;
10996        synchronized (this) {
10997            if (r != null && !r.isolated) {
10998                // XXX Can't keep track of crash time for isolated processes,
10999                // since they don't have a persistent identity.
11000                mProcessCrashTimes.put(r.info.processName, r.uid,
11001                        SystemClock.uptimeMillis());
11002            }
11003            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11004                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11005            }
11006        }
11007
11008        if (appErrorIntent != null) {
11009            try {
11010                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11011            } catch (ActivityNotFoundException e) {
11012                Slog.w(TAG, "bug report receiver dissappeared", e);
11013            }
11014        }
11015    }
11016
11017    Intent createAppErrorIntentLocked(ProcessRecord r,
11018            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11019        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11020        if (report == null) {
11021            return null;
11022        }
11023        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11024        result.setComponent(r.errorReportReceiver);
11025        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11026        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11027        return result;
11028    }
11029
11030    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11031            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11032        if (r.errorReportReceiver == null) {
11033            return null;
11034        }
11035
11036        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11037            return null;
11038        }
11039
11040        ApplicationErrorReport report = new ApplicationErrorReport();
11041        report.packageName = r.info.packageName;
11042        report.installerPackageName = r.errorReportReceiver.getPackageName();
11043        report.processName = r.processName;
11044        report.time = timeMillis;
11045        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11046
11047        if (r.crashing || r.forceCrashReport) {
11048            report.type = ApplicationErrorReport.TYPE_CRASH;
11049            report.crashInfo = crashInfo;
11050        } else if (r.notResponding) {
11051            report.type = ApplicationErrorReport.TYPE_ANR;
11052            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11053
11054            report.anrInfo.activity = r.notRespondingReport.tag;
11055            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11056            report.anrInfo.info = r.notRespondingReport.longMsg;
11057        }
11058
11059        return report;
11060    }
11061
11062    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11063        enforceNotIsolatedCaller("getProcessesInErrorState");
11064        // assume our apps are happy - lazy create the list
11065        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11066
11067        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11068                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11069        int userId = UserHandle.getUserId(Binder.getCallingUid());
11070
11071        synchronized (this) {
11072
11073            // iterate across all processes
11074            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11075                ProcessRecord app = mLruProcesses.get(i);
11076                if (!allUsers && app.userId != userId) {
11077                    continue;
11078                }
11079                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11080                    // This one's in trouble, so we'll generate a report for it
11081                    // crashes are higher priority (in case there's a crash *and* an anr)
11082                    ActivityManager.ProcessErrorStateInfo report = null;
11083                    if (app.crashing) {
11084                        report = app.crashingReport;
11085                    } else if (app.notResponding) {
11086                        report = app.notRespondingReport;
11087                    }
11088
11089                    if (report != null) {
11090                        if (errList == null) {
11091                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11092                        }
11093                        errList.add(report);
11094                    } else {
11095                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11096                                " crashing = " + app.crashing +
11097                                " notResponding = " + app.notResponding);
11098                    }
11099                }
11100            }
11101        }
11102
11103        return errList;
11104    }
11105
11106    static int procStateToImportance(int procState, int memAdj,
11107            ActivityManager.RunningAppProcessInfo currApp) {
11108        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11109        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11110            currApp.lru = memAdj;
11111        } else {
11112            currApp.lru = 0;
11113        }
11114        return imp;
11115    }
11116
11117    private void fillInProcMemInfo(ProcessRecord app,
11118            ActivityManager.RunningAppProcessInfo outInfo) {
11119        outInfo.pid = app.pid;
11120        outInfo.uid = app.info.uid;
11121        if (mHeavyWeightProcess == app) {
11122            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11123        }
11124        if (app.persistent) {
11125            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11126        }
11127        if (app.activities.size() > 0) {
11128            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11129        }
11130        outInfo.lastTrimLevel = app.trimMemoryLevel;
11131        int adj = app.curAdj;
11132        int procState = app.curProcState;
11133        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11134        outInfo.importanceReasonCode = app.adjTypeCode;
11135        outInfo.processState = app.curProcState;
11136    }
11137
11138    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11139        enforceNotIsolatedCaller("getRunningAppProcesses");
11140        // Lazy instantiation of list
11141        List<ActivityManager.RunningAppProcessInfo> runList = null;
11142        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11143                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11144        int userId = UserHandle.getUserId(Binder.getCallingUid());
11145        synchronized (this) {
11146            // Iterate across all processes
11147            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11148                ProcessRecord app = mLruProcesses.get(i);
11149                if (!allUsers && app.userId != userId) {
11150                    continue;
11151                }
11152                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11153                    // Generate process state info for running application
11154                    ActivityManager.RunningAppProcessInfo currApp =
11155                        new ActivityManager.RunningAppProcessInfo(app.processName,
11156                                app.pid, app.getPackageList());
11157                    fillInProcMemInfo(app, currApp);
11158                    if (app.adjSource instanceof ProcessRecord) {
11159                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11160                        currApp.importanceReasonImportance =
11161                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11162                                        app.adjSourceProcState);
11163                    } else if (app.adjSource instanceof ActivityRecord) {
11164                        ActivityRecord r = (ActivityRecord)app.adjSource;
11165                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11166                    }
11167                    if (app.adjTarget instanceof ComponentName) {
11168                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11169                    }
11170                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11171                    //        + " lru=" + currApp.lru);
11172                    if (runList == null) {
11173                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11174                    }
11175                    runList.add(currApp);
11176                }
11177            }
11178        }
11179        return runList;
11180    }
11181
11182    public List<ApplicationInfo> getRunningExternalApplications() {
11183        enforceNotIsolatedCaller("getRunningExternalApplications");
11184        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11185        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11186        if (runningApps != null && runningApps.size() > 0) {
11187            Set<String> extList = new HashSet<String>();
11188            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11189                if (app.pkgList != null) {
11190                    for (String pkg : app.pkgList) {
11191                        extList.add(pkg);
11192                    }
11193                }
11194            }
11195            IPackageManager pm = AppGlobals.getPackageManager();
11196            for (String pkg : extList) {
11197                try {
11198                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11199                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11200                        retList.add(info);
11201                    }
11202                } catch (RemoteException e) {
11203                }
11204            }
11205        }
11206        return retList;
11207    }
11208
11209    @Override
11210    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11211        enforceNotIsolatedCaller("getMyMemoryState");
11212        synchronized (this) {
11213            ProcessRecord proc;
11214            synchronized (mPidsSelfLocked) {
11215                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11216            }
11217            fillInProcMemInfo(proc, outInfo);
11218        }
11219    }
11220
11221    @Override
11222    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11223        if (checkCallingPermission(android.Manifest.permission.DUMP)
11224                != PackageManager.PERMISSION_GRANTED) {
11225            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11226                    + Binder.getCallingPid()
11227                    + ", uid=" + Binder.getCallingUid()
11228                    + " without permission "
11229                    + android.Manifest.permission.DUMP);
11230            return;
11231        }
11232
11233        boolean dumpAll = false;
11234        boolean dumpClient = false;
11235        String dumpPackage = null;
11236
11237        int opti = 0;
11238        while (opti < args.length) {
11239            String opt = args[opti];
11240            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11241                break;
11242            }
11243            opti++;
11244            if ("-a".equals(opt)) {
11245                dumpAll = true;
11246            } else if ("-c".equals(opt)) {
11247                dumpClient = true;
11248            } else if ("-h".equals(opt)) {
11249                pw.println("Activity manager dump options:");
11250                pw.println("  [-a] [-c] [-h] [cmd] ...");
11251                pw.println("  cmd may be one of:");
11252                pw.println("    a[ctivities]: activity stack state");
11253                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11254                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11255                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11256                pw.println("    o[om]: out of memory management");
11257                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11258                pw.println("    provider [COMP_SPEC]: provider client-side state");
11259                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11260                pw.println("    service [COMP_SPEC]: service client-side state");
11261                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11262                pw.println("    all: dump all activities");
11263                pw.println("    top: dump the top activity");
11264                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11265                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11266                pw.println("    a partial substring in a component name, a");
11267                pw.println("    hex object identifier.");
11268                pw.println("  -a: include all available server state.");
11269                pw.println("  -c: include client state.");
11270                return;
11271            } else {
11272                pw.println("Unknown argument: " + opt + "; use -h for help");
11273            }
11274        }
11275
11276        long origId = Binder.clearCallingIdentity();
11277        boolean more = false;
11278        // Is the caller requesting to dump a particular piece of data?
11279        if (opti < args.length) {
11280            String cmd = args[opti];
11281            opti++;
11282            if ("activities".equals(cmd) || "a".equals(cmd)) {
11283                synchronized (this) {
11284                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11285                }
11286            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11287                String[] newArgs;
11288                String name;
11289                if (opti >= args.length) {
11290                    name = null;
11291                    newArgs = EMPTY_STRING_ARRAY;
11292                } else {
11293                    name = args[opti];
11294                    opti++;
11295                    newArgs = new String[args.length - opti];
11296                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11297                            args.length - opti);
11298                }
11299                synchronized (this) {
11300                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11301                }
11302            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11303                String[] newArgs;
11304                String name;
11305                if (opti >= args.length) {
11306                    name = null;
11307                    newArgs = EMPTY_STRING_ARRAY;
11308                } else {
11309                    name = args[opti];
11310                    opti++;
11311                    newArgs = new String[args.length - opti];
11312                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11313                            args.length - opti);
11314                }
11315                synchronized (this) {
11316                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11317                }
11318            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11319                String[] newArgs;
11320                String name;
11321                if (opti >= args.length) {
11322                    name = null;
11323                    newArgs = EMPTY_STRING_ARRAY;
11324                } else {
11325                    name = args[opti];
11326                    opti++;
11327                    newArgs = new String[args.length - opti];
11328                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11329                            args.length - opti);
11330                }
11331                synchronized (this) {
11332                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11333                }
11334            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11335                synchronized (this) {
11336                    dumpOomLocked(fd, pw, args, opti, true);
11337                }
11338            } else if ("provider".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, args.length - opti);
11349                }
11350                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11351                    pw.println("No providers match: " + name);
11352                    pw.println("Use -h for help.");
11353                }
11354            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11355                synchronized (this) {
11356                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11357                }
11358            } else if ("service".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,
11369                            args.length - opti);
11370                }
11371                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11372                    pw.println("No services match: " + name);
11373                    pw.println("Use -h for help.");
11374                }
11375            } else if ("package".equals(cmd)) {
11376                String[] newArgs;
11377                if (opti >= args.length) {
11378                    pw.println("package: no package name specified");
11379                    pw.println("Use -h for help.");
11380                } else {
11381                    dumpPackage = args[opti];
11382                    opti++;
11383                    newArgs = new String[args.length - opti];
11384                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11385                            args.length - opti);
11386                    args = newArgs;
11387                    opti = 0;
11388                    more = true;
11389                }
11390            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11391                synchronized (this) {
11392                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11393                }
11394            } else {
11395                // Dumping a single activity?
11396                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11397                    pw.println("Bad activity command, or no activities match: " + cmd);
11398                    pw.println("Use -h for help.");
11399                }
11400            }
11401            if (!more) {
11402                Binder.restoreCallingIdentity(origId);
11403                return;
11404            }
11405        }
11406
11407        // No piece of data specified, dump everything.
11408        synchronized (this) {
11409            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11410            pw.println();
11411            if (dumpAll) {
11412                pw.println("-------------------------------------------------------------------------------");
11413            }
11414            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11415            pw.println();
11416            if (dumpAll) {
11417                pw.println("-------------------------------------------------------------------------------");
11418            }
11419            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11420            pw.println();
11421            if (dumpAll) {
11422                pw.println("-------------------------------------------------------------------------------");
11423            }
11424            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11425            pw.println();
11426            if (dumpAll) {
11427                pw.println("-------------------------------------------------------------------------------");
11428            }
11429            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11430            pw.println();
11431            if (dumpAll) {
11432                pw.println("-------------------------------------------------------------------------------");
11433            }
11434            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11435        }
11436        Binder.restoreCallingIdentity(origId);
11437    }
11438
11439    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11440            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11441        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11442
11443        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11444                dumpPackage);
11445        boolean needSep = printedAnything;
11446
11447        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11448                dumpPackage, needSep, "  mFocusedActivity: ");
11449        if (printed) {
11450            printedAnything = true;
11451            needSep = false;
11452        }
11453
11454        if (dumpPackage == null) {
11455            if (needSep) {
11456                pw.println();
11457            }
11458            needSep = true;
11459            printedAnything = true;
11460            mStackSupervisor.dump(pw, "  ");
11461        }
11462
11463        if (mRecentTasks.size() > 0) {
11464            boolean printedHeader = false;
11465
11466            final int N = mRecentTasks.size();
11467            for (int i=0; i<N; i++) {
11468                TaskRecord tr = mRecentTasks.get(i);
11469                if (dumpPackage != null) {
11470                    if (tr.realActivity == null ||
11471                            !dumpPackage.equals(tr.realActivity)) {
11472                        continue;
11473                    }
11474                }
11475                if (!printedHeader) {
11476                    if (needSep) {
11477                        pw.println();
11478                    }
11479                    pw.println("  Recent tasks:");
11480                    printedHeader = true;
11481                    printedAnything = true;
11482                }
11483                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11484                        pw.println(tr);
11485                if (dumpAll) {
11486                    mRecentTasks.get(i).dump(pw, "    ");
11487                }
11488            }
11489        }
11490
11491        if (!printedAnything) {
11492            pw.println("  (nothing)");
11493        }
11494    }
11495
11496    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11497            int opti, boolean dumpAll, String dumpPackage) {
11498        boolean needSep = false;
11499        boolean printedAnything = false;
11500        int numPers = 0;
11501
11502        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11503
11504        if (dumpAll) {
11505            final int NP = mProcessNames.getMap().size();
11506            for (int ip=0; ip<NP; ip++) {
11507                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11508                final int NA = procs.size();
11509                for (int ia=0; ia<NA; ia++) {
11510                    ProcessRecord r = procs.valueAt(ia);
11511                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11512                        continue;
11513                    }
11514                    if (!needSep) {
11515                        pw.println("  All known processes:");
11516                        needSep = true;
11517                        printedAnything = true;
11518                    }
11519                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11520                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11521                        pw.print(" "); pw.println(r);
11522                    r.dump(pw, "    ");
11523                    if (r.persistent) {
11524                        numPers++;
11525                    }
11526                }
11527            }
11528        }
11529
11530        if (mIsolatedProcesses.size() > 0) {
11531            boolean printed = false;
11532            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11533                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11534                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11535                    continue;
11536                }
11537                if (!printed) {
11538                    if (needSep) {
11539                        pw.println();
11540                    }
11541                    pw.println("  Isolated process list (sorted by uid):");
11542                    printedAnything = true;
11543                    printed = true;
11544                    needSep = true;
11545                }
11546                pw.println(String.format("%sIsolated #%2d: %s",
11547                        "    ", i, r.toString()));
11548            }
11549        }
11550
11551        if (mLruProcesses.size() > 0) {
11552            if (needSep) {
11553                pw.println();
11554            }
11555            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11556                    pw.print(" total, non-act at ");
11557                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11558                    pw.print(", non-svc at ");
11559                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11560                    pw.println("):");
11561            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11562            needSep = true;
11563            printedAnything = true;
11564        }
11565
11566        if (dumpAll || dumpPackage != null) {
11567            synchronized (mPidsSelfLocked) {
11568                boolean printed = false;
11569                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11570                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11571                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11572                        continue;
11573                    }
11574                    if (!printed) {
11575                        if (needSep) pw.println();
11576                        needSep = true;
11577                        pw.println("  PID mappings:");
11578                        printed = true;
11579                        printedAnything = true;
11580                    }
11581                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11582                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11583                }
11584            }
11585        }
11586
11587        if (mForegroundProcesses.size() > 0) {
11588            synchronized (mPidsSelfLocked) {
11589                boolean printed = false;
11590                for (int i=0; i<mForegroundProcesses.size(); i++) {
11591                    ProcessRecord r = mPidsSelfLocked.get(
11592                            mForegroundProcesses.valueAt(i).pid);
11593                    if (dumpPackage != null && (r == null
11594                            || !r.pkgList.containsKey(dumpPackage))) {
11595                        continue;
11596                    }
11597                    if (!printed) {
11598                        if (needSep) pw.println();
11599                        needSep = true;
11600                        pw.println("  Foreground Processes:");
11601                        printed = true;
11602                        printedAnything = true;
11603                    }
11604                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11605                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11606                }
11607            }
11608        }
11609
11610        if (mPersistentStartingProcesses.size() > 0) {
11611            if (needSep) pw.println();
11612            needSep = true;
11613            printedAnything = true;
11614            pw.println("  Persisent processes that are starting:");
11615            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11616                    "Starting Norm", "Restarting PERS", dumpPackage);
11617        }
11618
11619        if (mRemovedProcesses.size() > 0) {
11620            if (needSep) pw.println();
11621            needSep = true;
11622            printedAnything = true;
11623            pw.println("  Processes that are being removed:");
11624            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11625                    "Removed Norm", "Removed PERS", dumpPackage);
11626        }
11627
11628        if (mProcessesOnHold.size() > 0) {
11629            if (needSep) pw.println();
11630            needSep = true;
11631            printedAnything = true;
11632            pw.println("  Processes that are on old until the system is ready:");
11633            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11634                    "OnHold Norm", "OnHold PERS", dumpPackage);
11635        }
11636
11637        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11638
11639        if (mProcessCrashTimes.getMap().size() > 0) {
11640            boolean printed = false;
11641            long now = SystemClock.uptimeMillis();
11642            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11643            final int NP = pmap.size();
11644            for (int ip=0; ip<NP; ip++) {
11645                String pname = pmap.keyAt(ip);
11646                SparseArray<Long> uids = pmap.valueAt(ip);
11647                final int N = uids.size();
11648                for (int i=0; i<N; i++) {
11649                    int puid = uids.keyAt(i);
11650                    ProcessRecord r = mProcessNames.get(pname, puid);
11651                    if (dumpPackage != null && (r == null
11652                            || !r.pkgList.containsKey(dumpPackage))) {
11653                        continue;
11654                    }
11655                    if (!printed) {
11656                        if (needSep) pw.println();
11657                        needSep = true;
11658                        pw.println("  Time since processes crashed:");
11659                        printed = true;
11660                        printedAnything = true;
11661                    }
11662                    pw.print("    Process "); pw.print(pname);
11663                            pw.print(" uid "); pw.print(puid);
11664                            pw.print(": last crashed ");
11665                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11666                            pw.println(" ago");
11667                }
11668            }
11669        }
11670
11671        if (mBadProcesses.getMap().size() > 0) {
11672            boolean printed = false;
11673            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11674            final int NP = pmap.size();
11675            for (int ip=0; ip<NP; ip++) {
11676                String pname = pmap.keyAt(ip);
11677                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11678                final int N = uids.size();
11679                for (int i=0; i<N; i++) {
11680                    int puid = uids.keyAt(i);
11681                    ProcessRecord r = mProcessNames.get(pname, puid);
11682                    if (dumpPackage != null && (r == null
11683                            || !r.pkgList.containsKey(dumpPackage))) {
11684                        continue;
11685                    }
11686                    if (!printed) {
11687                        if (needSep) pw.println();
11688                        needSep = true;
11689                        pw.println("  Bad processes:");
11690                        printedAnything = true;
11691                    }
11692                    BadProcessInfo info = uids.valueAt(i);
11693                    pw.print("    Bad process "); pw.print(pname);
11694                            pw.print(" uid "); pw.print(puid);
11695                            pw.print(": crashed at time "); pw.println(info.time);
11696                    if (info.shortMsg != null) {
11697                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11698                    }
11699                    if (info.longMsg != null) {
11700                        pw.print("      Long msg: "); pw.println(info.longMsg);
11701                    }
11702                    if (info.stack != null) {
11703                        pw.println("      Stack:");
11704                        int lastPos = 0;
11705                        for (int pos=0; pos<info.stack.length(); pos++) {
11706                            if (info.stack.charAt(pos) == '\n') {
11707                                pw.print("        ");
11708                                pw.write(info.stack, lastPos, pos-lastPos);
11709                                pw.println();
11710                                lastPos = pos+1;
11711                            }
11712                        }
11713                        if (lastPos < info.stack.length()) {
11714                            pw.print("        ");
11715                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11716                            pw.println();
11717                        }
11718                    }
11719                }
11720            }
11721        }
11722
11723        if (dumpPackage == null) {
11724            pw.println();
11725            needSep = false;
11726            pw.println("  mStartedUsers:");
11727            for (int i=0; i<mStartedUsers.size(); i++) {
11728                UserStartedState uss = mStartedUsers.valueAt(i);
11729                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11730                        pw.print(": "); uss.dump("", pw);
11731            }
11732            pw.print("  mStartedUserArray: [");
11733            for (int i=0; i<mStartedUserArray.length; i++) {
11734                if (i > 0) pw.print(", ");
11735                pw.print(mStartedUserArray[i]);
11736            }
11737            pw.println("]");
11738            pw.print("  mUserLru: [");
11739            for (int i=0; i<mUserLru.size(); i++) {
11740                if (i > 0) pw.print(", ");
11741                pw.print(mUserLru.get(i));
11742            }
11743            pw.println("]");
11744            if (dumpAll) {
11745                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11746            }
11747            synchronized (mUserProfileGroupIdsSelfLocked) {
11748                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11749                    pw.println("  mUserProfileGroupIds:");
11750                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11751                        pw.print("    User #");
11752                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11753                        pw.print(" -> profile #");
11754                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11755                    }
11756                }
11757            }
11758        }
11759        if (mHomeProcess != null && (dumpPackage == null
11760                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11761            if (needSep) {
11762                pw.println();
11763                needSep = false;
11764            }
11765            pw.println("  mHomeProcess: " + mHomeProcess);
11766        }
11767        if (mPreviousProcess != null && (dumpPackage == null
11768                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11769            if (needSep) {
11770                pw.println();
11771                needSep = false;
11772            }
11773            pw.println("  mPreviousProcess: " + mPreviousProcess);
11774        }
11775        if (dumpAll) {
11776            StringBuilder sb = new StringBuilder(128);
11777            sb.append("  mPreviousProcessVisibleTime: ");
11778            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11779            pw.println(sb);
11780        }
11781        if (mHeavyWeightProcess != null && (dumpPackage == null
11782                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11783            if (needSep) {
11784                pw.println();
11785                needSep = false;
11786            }
11787            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11788        }
11789        if (dumpPackage == null) {
11790            pw.println("  mConfiguration: " + mConfiguration);
11791        }
11792        if (dumpAll) {
11793            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11794            if (mCompatModePackages.getPackages().size() > 0) {
11795                boolean printed = false;
11796                for (Map.Entry<String, Integer> entry
11797                        : mCompatModePackages.getPackages().entrySet()) {
11798                    String pkg = entry.getKey();
11799                    int mode = entry.getValue();
11800                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11801                        continue;
11802                    }
11803                    if (!printed) {
11804                        pw.println("  mScreenCompatPackages:");
11805                        printed = true;
11806                    }
11807                    pw.print("    "); pw.print(pkg); pw.print(": ");
11808                            pw.print(mode); pw.println();
11809                }
11810            }
11811        }
11812        if (dumpPackage == null) {
11813            if (mSleeping || mWentToSleep || mLockScreenShown) {
11814                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11815                        + " mLockScreenShown " + mLockScreenShown);
11816            }
11817            if (mShuttingDown || mRunningVoice) {
11818                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11819            }
11820        }
11821        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11822                || mOrigWaitForDebugger) {
11823            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11824                    || dumpPackage.equals(mOrigDebugApp)) {
11825                if (needSep) {
11826                    pw.println();
11827                    needSep = false;
11828                }
11829                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11830                        + " mDebugTransient=" + mDebugTransient
11831                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11832            }
11833        }
11834        if (mOpenGlTraceApp != null) {
11835            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11836                if (needSep) {
11837                    pw.println();
11838                    needSep = false;
11839                }
11840                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11841            }
11842        }
11843        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11844                || mProfileFd != null) {
11845            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11846                if (needSep) {
11847                    pw.println();
11848                    needSep = false;
11849                }
11850                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11851                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11852                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11853                        + mAutoStopProfiler);
11854            }
11855        }
11856        if (dumpPackage == null) {
11857            if (mAlwaysFinishActivities || mController != null) {
11858                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11859                        + " mController=" + mController);
11860            }
11861            if (dumpAll) {
11862                pw.println("  Total persistent processes: " + numPers);
11863                pw.println("  mProcessesReady=" + mProcessesReady
11864                        + " mSystemReady=" + mSystemReady);
11865                pw.println("  mBooting=" + mBooting
11866                        + " mBooted=" + mBooted
11867                        + " mFactoryTest=" + mFactoryTest);
11868                pw.print("  mLastPowerCheckRealtime=");
11869                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11870                        pw.println("");
11871                pw.print("  mLastPowerCheckUptime=");
11872                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11873                        pw.println("");
11874                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11875                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11876                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11877                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11878                        + " (" + mLruProcesses.size() + " total)"
11879                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11880                        + " mNumServiceProcs=" + mNumServiceProcs
11881                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11882                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11883                        + " mLastMemoryLevel" + mLastMemoryLevel
11884                        + " mLastNumProcesses" + mLastNumProcesses);
11885                long now = SystemClock.uptimeMillis();
11886                pw.print("  mLastIdleTime=");
11887                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11888                        pw.print(" mLowRamSinceLastIdle=");
11889                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11890                        pw.println();
11891            }
11892        }
11893
11894        if (!printedAnything) {
11895            pw.println("  (nothing)");
11896        }
11897    }
11898
11899    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11900            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11901        if (mProcessesToGc.size() > 0) {
11902            boolean printed = false;
11903            long now = SystemClock.uptimeMillis();
11904            for (int i=0; i<mProcessesToGc.size(); i++) {
11905                ProcessRecord proc = mProcessesToGc.get(i);
11906                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11907                    continue;
11908                }
11909                if (!printed) {
11910                    if (needSep) pw.println();
11911                    needSep = true;
11912                    pw.println("  Processes that are waiting to GC:");
11913                    printed = true;
11914                }
11915                pw.print("    Process "); pw.println(proc);
11916                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11917                        pw.print(", last gced=");
11918                        pw.print(now-proc.lastRequestedGc);
11919                        pw.print(" ms ago, last lowMem=");
11920                        pw.print(now-proc.lastLowMemory);
11921                        pw.println(" ms ago");
11922
11923            }
11924        }
11925        return needSep;
11926    }
11927
11928    void printOomLevel(PrintWriter pw, String name, int adj) {
11929        pw.print("    ");
11930        if (adj >= 0) {
11931            pw.print(' ');
11932            if (adj < 10) pw.print(' ');
11933        } else {
11934            if (adj > -10) pw.print(' ');
11935        }
11936        pw.print(adj);
11937        pw.print(": ");
11938        pw.print(name);
11939        pw.print(" (");
11940        pw.print(mProcessList.getMemLevel(adj)/1024);
11941        pw.println(" kB)");
11942    }
11943
11944    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11945            int opti, boolean dumpAll) {
11946        boolean needSep = false;
11947
11948        if (mLruProcesses.size() > 0) {
11949            if (needSep) pw.println();
11950            needSep = true;
11951            pw.println("  OOM levels:");
11952            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11953            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11954            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11955            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11956            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11957            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11958            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11959            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11960            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11961            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11962            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11963            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11964            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11965
11966            if (needSep) pw.println();
11967            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11968                    pw.print(" total, non-act at ");
11969                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11970                    pw.print(", non-svc at ");
11971                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11972                    pw.println("):");
11973            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11974            needSep = true;
11975        }
11976
11977        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11978
11979        pw.println();
11980        pw.println("  mHomeProcess: " + mHomeProcess);
11981        pw.println("  mPreviousProcess: " + mPreviousProcess);
11982        if (mHeavyWeightProcess != null) {
11983            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11984        }
11985
11986        return true;
11987    }
11988
11989    /**
11990     * There are three ways to call this:
11991     *  - no provider specified: dump all the providers
11992     *  - a flattened component name that matched an existing provider was specified as the
11993     *    first arg: dump that one provider
11994     *  - the first arg isn't the flattened component name of an existing provider:
11995     *    dump all providers whose component contains the first arg as a substring
11996     */
11997    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11998            int opti, boolean dumpAll) {
11999        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12000    }
12001
12002    static class ItemMatcher {
12003        ArrayList<ComponentName> components;
12004        ArrayList<String> strings;
12005        ArrayList<Integer> objects;
12006        boolean all;
12007
12008        ItemMatcher() {
12009            all = true;
12010        }
12011
12012        void build(String name) {
12013            ComponentName componentName = ComponentName.unflattenFromString(name);
12014            if (componentName != null) {
12015                if (components == null) {
12016                    components = new ArrayList<ComponentName>();
12017                }
12018                components.add(componentName);
12019                all = false;
12020            } else {
12021                int objectId = 0;
12022                // Not a '/' separated full component name; maybe an object ID?
12023                try {
12024                    objectId = Integer.parseInt(name, 16);
12025                    if (objects == null) {
12026                        objects = new ArrayList<Integer>();
12027                    }
12028                    objects.add(objectId);
12029                    all = false;
12030                } catch (RuntimeException e) {
12031                    // Not an integer; just do string match.
12032                    if (strings == null) {
12033                        strings = new ArrayList<String>();
12034                    }
12035                    strings.add(name);
12036                    all = false;
12037                }
12038            }
12039        }
12040
12041        int build(String[] args, int opti) {
12042            for (; opti<args.length; opti++) {
12043                String name = args[opti];
12044                if ("--".equals(name)) {
12045                    return opti+1;
12046                }
12047                build(name);
12048            }
12049            return opti;
12050        }
12051
12052        boolean match(Object object, ComponentName comp) {
12053            if (all) {
12054                return true;
12055            }
12056            if (components != null) {
12057                for (int i=0; i<components.size(); i++) {
12058                    if (components.get(i).equals(comp)) {
12059                        return true;
12060                    }
12061                }
12062            }
12063            if (objects != null) {
12064                for (int i=0; i<objects.size(); i++) {
12065                    if (System.identityHashCode(object) == objects.get(i)) {
12066                        return true;
12067                    }
12068                }
12069            }
12070            if (strings != null) {
12071                String flat = comp.flattenToString();
12072                for (int i=0; i<strings.size(); i++) {
12073                    if (flat.contains(strings.get(i))) {
12074                        return true;
12075                    }
12076                }
12077            }
12078            return false;
12079        }
12080    }
12081
12082    /**
12083     * There are three things that cmd can be:
12084     *  - a flattened component name that matches an existing activity
12085     *  - the cmd arg isn't the flattened component name of an existing activity:
12086     *    dump all activity whose component contains the cmd as a substring
12087     *  - A hex number of the ActivityRecord object instance.
12088     */
12089    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12090            int opti, boolean dumpAll) {
12091        ArrayList<ActivityRecord> activities;
12092
12093        synchronized (this) {
12094            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12095        }
12096
12097        if (activities.size() <= 0) {
12098            return false;
12099        }
12100
12101        String[] newArgs = new String[args.length - opti];
12102        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12103
12104        TaskRecord lastTask = null;
12105        boolean needSep = false;
12106        for (int i=activities.size()-1; i>=0; i--) {
12107            ActivityRecord r = activities.get(i);
12108            if (needSep) {
12109                pw.println();
12110            }
12111            needSep = true;
12112            synchronized (this) {
12113                if (lastTask != r.task) {
12114                    lastTask = r.task;
12115                    pw.print("TASK "); pw.print(lastTask.affinity);
12116                            pw.print(" id="); pw.println(lastTask.taskId);
12117                    if (dumpAll) {
12118                        lastTask.dump(pw, "  ");
12119                    }
12120                }
12121            }
12122            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12123        }
12124        return true;
12125    }
12126
12127    /**
12128     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12129     * there is a thread associated with the activity.
12130     */
12131    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12132            final ActivityRecord r, String[] args, boolean dumpAll) {
12133        String innerPrefix = prefix + "  ";
12134        synchronized (this) {
12135            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12136                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12137                    pw.print(" pid=");
12138                    if (r.app != null) pw.println(r.app.pid);
12139                    else pw.println("(not running)");
12140            if (dumpAll) {
12141                r.dump(pw, innerPrefix);
12142            }
12143        }
12144        if (r.app != null && r.app.thread != null) {
12145            // flush anything that is already in the PrintWriter since the thread is going
12146            // to write to the file descriptor directly
12147            pw.flush();
12148            try {
12149                TransferPipe tp = new TransferPipe();
12150                try {
12151                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12152                            r.appToken, innerPrefix, args);
12153                    tp.go(fd);
12154                } finally {
12155                    tp.kill();
12156                }
12157            } catch (IOException e) {
12158                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12159            } catch (RemoteException e) {
12160                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12161            }
12162        }
12163    }
12164
12165    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12166            int opti, boolean dumpAll, String dumpPackage) {
12167        boolean needSep = false;
12168        boolean onlyHistory = false;
12169        boolean printedAnything = false;
12170
12171        if ("history".equals(dumpPackage)) {
12172            if (opti < args.length && "-s".equals(args[opti])) {
12173                dumpAll = false;
12174            }
12175            onlyHistory = true;
12176            dumpPackage = null;
12177        }
12178
12179        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12180        if (!onlyHistory && dumpAll) {
12181            if (mRegisteredReceivers.size() > 0) {
12182                boolean printed = false;
12183                Iterator it = mRegisteredReceivers.values().iterator();
12184                while (it.hasNext()) {
12185                    ReceiverList r = (ReceiverList)it.next();
12186                    if (dumpPackage != null && (r.app == null ||
12187                            !dumpPackage.equals(r.app.info.packageName))) {
12188                        continue;
12189                    }
12190                    if (!printed) {
12191                        pw.println("  Registered Receivers:");
12192                        needSep = true;
12193                        printed = true;
12194                        printedAnything = true;
12195                    }
12196                    pw.print("  * "); pw.println(r);
12197                    r.dump(pw, "    ");
12198                }
12199            }
12200
12201            if (mReceiverResolver.dump(pw, needSep ?
12202                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12203                    "    ", dumpPackage, false)) {
12204                needSep = true;
12205                printedAnything = true;
12206            }
12207        }
12208
12209        for (BroadcastQueue q : mBroadcastQueues) {
12210            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12211            printedAnything |= needSep;
12212        }
12213
12214        needSep = true;
12215
12216        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12217            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12218                if (needSep) {
12219                    pw.println();
12220                }
12221                needSep = true;
12222                printedAnything = true;
12223                pw.print("  Sticky broadcasts for user ");
12224                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12225                StringBuilder sb = new StringBuilder(128);
12226                for (Map.Entry<String, ArrayList<Intent>> ent
12227                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12228                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12229                    if (dumpAll) {
12230                        pw.println(":");
12231                        ArrayList<Intent> intents = ent.getValue();
12232                        final int N = intents.size();
12233                        for (int i=0; i<N; i++) {
12234                            sb.setLength(0);
12235                            sb.append("    Intent: ");
12236                            intents.get(i).toShortString(sb, false, true, false, false);
12237                            pw.println(sb.toString());
12238                            Bundle bundle = intents.get(i).getExtras();
12239                            if (bundle != null) {
12240                                pw.print("      ");
12241                                pw.println(bundle.toString());
12242                            }
12243                        }
12244                    } else {
12245                        pw.println("");
12246                    }
12247                }
12248            }
12249        }
12250
12251        if (!onlyHistory && dumpAll) {
12252            pw.println();
12253            for (BroadcastQueue queue : mBroadcastQueues) {
12254                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12255                        + queue.mBroadcastsScheduled);
12256            }
12257            pw.println("  mHandler:");
12258            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12259            needSep = true;
12260            printedAnything = true;
12261        }
12262
12263        if (!printedAnything) {
12264            pw.println("  (nothing)");
12265        }
12266    }
12267
12268    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12269            int opti, boolean dumpAll, String dumpPackage) {
12270        boolean needSep;
12271        boolean printedAnything = false;
12272
12273        ItemMatcher matcher = new ItemMatcher();
12274        matcher.build(args, opti);
12275
12276        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12277
12278        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12279        printedAnything |= needSep;
12280
12281        if (mLaunchingProviders.size() > 0) {
12282            boolean printed = false;
12283            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12284                ContentProviderRecord r = mLaunchingProviders.get(i);
12285                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12286                    continue;
12287                }
12288                if (!printed) {
12289                    if (needSep) pw.println();
12290                    needSep = true;
12291                    pw.println("  Launching content providers:");
12292                    printed = true;
12293                    printedAnything = true;
12294                }
12295                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12296                        pw.println(r);
12297            }
12298        }
12299
12300        if (mGrantedUriPermissions.size() > 0) {
12301            boolean printed = false;
12302            int dumpUid = -2;
12303            if (dumpPackage != null) {
12304                try {
12305                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12306                } catch (NameNotFoundException e) {
12307                    dumpUid = -1;
12308                }
12309            }
12310            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12311                int uid = mGrantedUriPermissions.keyAt(i);
12312                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12313                    continue;
12314                }
12315                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12316                if (!printed) {
12317                    if (needSep) pw.println();
12318                    needSep = true;
12319                    pw.println("  Granted Uri Permissions:");
12320                    printed = true;
12321                    printedAnything = true;
12322                }
12323                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12324                for (UriPermission perm : perms.values()) {
12325                    pw.print("    "); pw.println(perm);
12326                    if (dumpAll) {
12327                        perm.dump(pw, "      ");
12328                    }
12329                }
12330            }
12331        }
12332
12333        if (!printedAnything) {
12334            pw.println("  (nothing)");
12335        }
12336    }
12337
12338    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12339            int opti, boolean dumpAll, String dumpPackage) {
12340        boolean printed = false;
12341
12342        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12343
12344        if (mIntentSenderRecords.size() > 0) {
12345            Iterator<WeakReference<PendingIntentRecord>> it
12346                    = mIntentSenderRecords.values().iterator();
12347            while (it.hasNext()) {
12348                WeakReference<PendingIntentRecord> ref = it.next();
12349                PendingIntentRecord rec = ref != null ? ref.get(): null;
12350                if (dumpPackage != null && (rec == null
12351                        || !dumpPackage.equals(rec.key.packageName))) {
12352                    continue;
12353                }
12354                printed = true;
12355                if (rec != null) {
12356                    pw.print("  * "); pw.println(rec);
12357                    if (dumpAll) {
12358                        rec.dump(pw, "    ");
12359                    }
12360                } else {
12361                    pw.print("  * "); pw.println(ref);
12362                }
12363            }
12364        }
12365
12366        if (!printed) {
12367            pw.println("  (nothing)");
12368        }
12369    }
12370
12371    private static final int dumpProcessList(PrintWriter pw,
12372            ActivityManagerService service, List list,
12373            String prefix, String normalLabel, String persistentLabel,
12374            String dumpPackage) {
12375        int numPers = 0;
12376        final int N = list.size()-1;
12377        for (int i=N; i>=0; i--) {
12378            ProcessRecord r = (ProcessRecord)list.get(i);
12379            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12380                continue;
12381            }
12382            pw.println(String.format("%s%s #%2d: %s",
12383                    prefix, (r.persistent ? persistentLabel : normalLabel),
12384                    i, r.toString()));
12385            if (r.persistent) {
12386                numPers++;
12387            }
12388        }
12389        return numPers;
12390    }
12391
12392    private static final boolean dumpProcessOomList(PrintWriter pw,
12393            ActivityManagerService service, List<ProcessRecord> origList,
12394            String prefix, String normalLabel, String persistentLabel,
12395            boolean inclDetails, String dumpPackage) {
12396
12397        ArrayList<Pair<ProcessRecord, Integer>> list
12398                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12399        for (int i=0; i<origList.size(); i++) {
12400            ProcessRecord r = origList.get(i);
12401            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12402                continue;
12403            }
12404            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12405        }
12406
12407        if (list.size() <= 0) {
12408            return false;
12409        }
12410
12411        Comparator<Pair<ProcessRecord, Integer>> comparator
12412                = new Comparator<Pair<ProcessRecord, Integer>>() {
12413            @Override
12414            public int compare(Pair<ProcessRecord, Integer> object1,
12415                    Pair<ProcessRecord, Integer> object2) {
12416                if (object1.first.setAdj != object2.first.setAdj) {
12417                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12418                }
12419                if (object1.second.intValue() != object2.second.intValue()) {
12420                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12421                }
12422                return 0;
12423            }
12424        };
12425
12426        Collections.sort(list, comparator);
12427
12428        final long curRealtime = SystemClock.elapsedRealtime();
12429        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12430        final long curUptime = SystemClock.uptimeMillis();
12431        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12432
12433        for (int i=list.size()-1; i>=0; i--) {
12434            ProcessRecord r = list.get(i).first;
12435            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12436            char schedGroup;
12437            switch (r.setSchedGroup) {
12438                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12439                    schedGroup = 'B';
12440                    break;
12441                case Process.THREAD_GROUP_DEFAULT:
12442                    schedGroup = 'F';
12443                    break;
12444                default:
12445                    schedGroup = '?';
12446                    break;
12447            }
12448            char foreground;
12449            if (r.foregroundActivities) {
12450                foreground = 'A';
12451            } else if (r.foregroundServices) {
12452                foreground = 'S';
12453            } else {
12454                foreground = ' ';
12455            }
12456            String procState = ProcessList.makeProcStateString(r.curProcState);
12457            pw.print(prefix);
12458            pw.print(r.persistent ? persistentLabel : normalLabel);
12459            pw.print(" #");
12460            int num = (origList.size()-1)-list.get(i).second;
12461            if (num < 10) pw.print(' ');
12462            pw.print(num);
12463            pw.print(": ");
12464            pw.print(oomAdj);
12465            pw.print(' ');
12466            pw.print(schedGroup);
12467            pw.print('/');
12468            pw.print(foreground);
12469            pw.print('/');
12470            pw.print(procState);
12471            pw.print(" trm:");
12472            if (r.trimMemoryLevel < 10) pw.print(' ');
12473            pw.print(r.trimMemoryLevel);
12474            pw.print(' ');
12475            pw.print(r.toShortString());
12476            pw.print(" (");
12477            pw.print(r.adjType);
12478            pw.println(')');
12479            if (r.adjSource != null || r.adjTarget != null) {
12480                pw.print(prefix);
12481                pw.print("    ");
12482                if (r.adjTarget instanceof ComponentName) {
12483                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12484                } else if (r.adjTarget != null) {
12485                    pw.print(r.adjTarget.toString());
12486                } else {
12487                    pw.print("{null}");
12488                }
12489                pw.print("<=");
12490                if (r.adjSource instanceof ProcessRecord) {
12491                    pw.print("Proc{");
12492                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12493                    pw.println("}");
12494                } else if (r.adjSource != null) {
12495                    pw.println(r.adjSource.toString());
12496                } else {
12497                    pw.println("{null}");
12498                }
12499            }
12500            if (inclDetails) {
12501                pw.print(prefix);
12502                pw.print("    ");
12503                pw.print("oom: max="); pw.print(r.maxAdj);
12504                pw.print(" curRaw="); pw.print(r.curRawAdj);
12505                pw.print(" setRaw="); pw.print(r.setRawAdj);
12506                pw.print(" cur="); pw.print(r.curAdj);
12507                pw.print(" set="); pw.println(r.setAdj);
12508                pw.print(prefix);
12509                pw.print("    ");
12510                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12511                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12512                pw.print(" lastPss="); pw.print(r.lastPss);
12513                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12514                pw.print(prefix);
12515                pw.print("    ");
12516                pw.print("cached="); pw.print(r.cached);
12517                pw.print(" empty="); pw.print(r.empty);
12518                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12519
12520                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12521                    if (r.lastWakeTime != 0) {
12522                        long wtime;
12523                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12524                        synchronized (stats) {
12525                            wtime = stats.getProcessWakeTime(r.info.uid,
12526                                    r.pid, curRealtime);
12527                        }
12528                        long timeUsed = wtime - r.lastWakeTime;
12529                        pw.print(prefix);
12530                        pw.print("    ");
12531                        pw.print("keep awake over ");
12532                        TimeUtils.formatDuration(realtimeSince, pw);
12533                        pw.print(" used ");
12534                        TimeUtils.formatDuration(timeUsed, pw);
12535                        pw.print(" (");
12536                        pw.print((timeUsed*100)/realtimeSince);
12537                        pw.println("%)");
12538                    }
12539                    if (r.lastCpuTime != 0) {
12540                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12541                        pw.print(prefix);
12542                        pw.print("    ");
12543                        pw.print("run cpu over ");
12544                        TimeUtils.formatDuration(uptimeSince, pw);
12545                        pw.print(" used ");
12546                        TimeUtils.formatDuration(timeUsed, pw);
12547                        pw.print(" (");
12548                        pw.print((timeUsed*100)/uptimeSince);
12549                        pw.println("%)");
12550                    }
12551                }
12552            }
12553        }
12554        return true;
12555    }
12556
12557    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12558        ArrayList<ProcessRecord> procs;
12559        synchronized (this) {
12560            if (args != null && args.length > start
12561                    && args[start].charAt(0) != '-') {
12562                procs = new ArrayList<ProcessRecord>();
12563                int pid = -1;
12564                try {
12565                    pid = Integer.parseInt(args[start]);
12566                } catch (NumberFormatException e) {
12567                }
12568                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12569                    ProcessRecord proc = mLruProcesses.get(i);
12570                    if (proc.pid == pid) {
12571                        procs.add(proc);
12572                    } else if (proc.processName.equals(args[start])) {
12573                        procs.add(proc);
12574                    }
12575                }
12576                if (procs.size() <= 0) {
12577                    return null;
12578                }
12579            } else {
12580                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12581            }
12582        }
12583        return procs;
12584    }
12585
12586    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12587            PrintWriter pw, String[] args) {
12588        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12589        if (procs == null) {
12590            pw.println("No process found for: " + args[0]);
12591            return;
12592        }
12593
12594        long uptime = SystemClock.uptimeMillis();
12595        long realtime = SystemClock.elapsedRealtime();
12596        pw.println("Applications Graphics Acceleration Info:");
12597        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12598
12599        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12600            ProcessRecord r = procs.get(i);
12601            if (r.thread != null) {
12602                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12603                pw.flush();
12604                try {
12605                    TransferPipe tp = new TransferPipe();
12606                    try {
12607                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12608                        tp.go(fd);
12609                    } finally {
12610                        tp.kill();
12611                    }
12612                } catch (IOException e) {
12613                    pw.println("Failure while dumping the app: " + r);
12614                    pw.flush();
12615                } catch (RemoteException e) {
12616                    pw.println("Got a RemoteException while dumping the app " + r);
12617                    pw.flush();
12618                }
12619            }
12620        }
12621    }
12622
12623    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12624        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12625        if (procs == null) {
12626            pw.println("No process found for: " + args[0]);
12627            return;
12628        }
12629
12630        pw.println("Applications Database Info:");
12631
12632        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12633            ProcessRecord r = procs.get(i);
12634            if (r.thread != null) {
12635                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12636                pw.flush();
12637                try {
12638                    TransferPipe tp = new TransferPipe();
12639                    try {
12640                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12641                        tp.go(fd);
12642                    } finally {
12643                        tp.kill();
12644                    }
12645                } catch (IOException e) {
12646                    pw.println("Failure while dumping the app: " + r);
12647                    pw.flush();
12648                } catch (RemoteException e) {
12649                    pw.println("Got a RemoteException while dumping the app " + r);
12650                    pw.flush();
12651                }
12652            }
12653        }
12654    }
12655
12656    final static class MemItem {
12657        final boolean isProc;
12658        final String label;
12659        final String shortLabel;
12660        final long pss;
12661        final int id;
12662        final boolean hasActivities;
12663        ArrayList<MemItem> subitems;
12664
12665        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12666                boolean _hasActivities) {
12667            isProc = true;
12668            label = _label;
12669            shortLabel = _shortLabel;
12670            pss = _pss;
12671            id = _id;
12672            hasActivities = _hasActivities;
12673        }
12674
12675        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12676            isProc = false;
12677            label = _label;
12678            shortLabel = _shortLabel;
12679            pss = _pss;
12680            id = _id;
12681            hasActivities = false;
12682        }
12683    }
12684
12685    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12686            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12687        if (sort && !isCompact) {
12688            Collections.sort(items, new Comparator<MemItem>() {
12689                @Override
12690                public int compare(MemItem lhs, MemItem rhs) {
12691                    if (lhs.pss < rhs.pss) {
12692                        return 1;
12693                    } else if (lhs.pss > rhs.pss) {
12694                        return -1;
12695                    }
12696                    return 0;
12697                }
12698            });
12699        }
12700
12701        for (int i=0; i<items.size(); i++) {
12702            MemItem mi = items.get(i);
12703            if (!isCompact) {
12704                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12705            } else if (mi.isProc) {
12706                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12707                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12708                pw.println(mi.hasActivities ? ",a" : ",e");
12709            } else {
12710                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12711                pw.println(mi.pss);
12712            }
12713            if (mi.subitems != null) {
12714                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12715                        true, isCompact);
12716            }
12717        }
12718    }
12719
12720    // These are in KB.
12721    static final long[] DUMP_MEM_BUCKETS = new long[] {
12722        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12723        120*1024, 160*1024, 200*1024,
12724        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12725        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12726    };
12727
12728    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12729            boolean stackLike) {
12730        int start = label.lastIndexOf('.');
12731        if (start >= 0) start++;
12732        else start = 0;
12733        int end = label.length();
12734        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12735            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12736                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12737                out.append(bucket);
12738                out.append(stackLike ? "MB." : "MB ");
12739                out.append(label, start, end);
12740                return;
12741            }
12742        }
12743        out.append(memKB/1024);
12744        out.append(stackLike ? "MB." : "MB ");
12745        out.append(label, start, end);
12746    }
12747
12748    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12749            ProcessList.NATIVE_ADJ,
12750            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12751            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12752            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12753            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12754            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12755    };
12756    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12757            "Native",
12758            "System", "Persistent", "Foreground",
12759            "Visible", "Perceptible",
12760            "Heavy Weight", "Backup",
12761            "A Services", "Home",
12762            "Previous", "B Services", "Cached"
12763    };
12764    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12765            "native",
12766            "sys", "pers", "fore",
12767            "vis", "percept",
12768            "heavy", "backup",
12769            "servicea", "home",
12770            "prev", "serviceb", "cached"
12771    };
12772
12773    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12774            long realtime, boolean isCheckinRequest, boolean isCompact) {
12775        if (isCheckinRequest || isCompact) {
12776            // short checkin version
12777            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12778        } else {
12779            pw.println("Applications Memory Usage (kB):");
12780            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12781        }
12782    }
12783
12784    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12785            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12786        boolean dumpDetails = false;
12787        boolean dumpFullDetails = false;
12788        boolean dumpDalvik = false;
12789        boolean oomOnly = false;
12790        boolean isCompact = false;
12791        boolean localOnly = false;
12792
12793        int opti = 0;
12794        while (opti < args.length) {
12795            String opt = args[opti];
12796            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12797                break;
12798            }
12799            opti++;
12800            if ("-a".equals(opt)) {
12801                dumpDetails = true;
12802                dumpFullDetails = true;
12803                dumpDalvik = true;
12804            } else if ("-d".equals(opt)) {
12805                dumpDalvik = true;
12806            } else if ("-c".equals(opt)) {
12807                isCompact = true;
12808            } else if ("--oom".equals(opt)) {
12809                oomOnly = true;
12810            } else if ("--local".equals(opt)) {
12811                localOnly = true;
12812            } else if ("-h".equals(opt)) {
12813                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12814                pw.println("  -a: include all available information for each process.");
12815                pw.println("  -d: include dalvik details when dumping process details.");
12816                pw.println("  -c: dump in a compact machine-parseable representation.");
12817                pw.println("  --oom: only show processes organized by oom adj.");
12818                pw.println("  --local: only collect details locally, don't call process.");
12819                pw.println("If [process] is specified it can be the name or ");
12820                pw.println("pid of a specific process to dump.");
12821                return;
12822            } else {
12823                pw.println("Unknown argument: " + opt + "; use -h for help");
12824            }
12825        }
12826
12827        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12828        long uptime = SystemClock.uptimeMillis();
12829        long realtime = SystemClock.elapsedRealtime();
12830        final long[] tmpLong = new long[1];
12831
12832        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12833        if (procs == null) {
12834            // No Java processes.  Maybe they want to print a native process.
12835            if (args != null && args.length > opti
12836                    && args[opti].charAt(0) != '-') {
12837                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12838                        = new ArrayList<ProcessCpuTracker.Stats>();
12839                updateCpuStatsNow();
12840                int findPid = -1;
12841                try {
12842                    findPid = Integer.parseInt(args[opti]);
12843                } catch (NumberFormatException e) {
12844                }
12845                synchronized (mProcessCpuThread) {
12846                    final int N = mProcessCpuTracker.countStats();
12847                    for (int i=0; i<N; i++) {
12848                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12849                        if (st.pid == findPid || (st.baseName != null
12850                                && st.baseName.equals(args[opti]))) {
12851                            nativeProcs.add(st);
12852                        }
12853                    }
12854                }
12855                if (nativeProcs.size() > 0) {
12856                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12857                            isCompact);
12858                    Debug.MemoryInfo mi = null;
12859                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12860                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12861                        final int pid = r.pid;
12862                        if (!isCheckinRequest && dumpDetails) {
12863                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12864                        }
12865                        if (mi == null) {
12866                            mi = new Debug.MemoryInfo();
12867                        }
12868                        if (dumpDetails || (!brief && !oomOnly)) {
12869                            Debug.getMemoryInfo(pid, mi);
12870                        } else {
12871                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12872                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12873                        }
12874                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12875                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12876                        if (isCheckinRequest) {
12877                            pw.println();
12878                        }
12879                    }
12880                    return;
12881                }
12882            }
12883            pw.println("No process found for: " + args[opti]);
12884            return;
12885        }
12886
12887        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12888            dumpDetails = true;
12889        }
12890
12891        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12892
12893        String[] innerArgs = new String[args.length-opti];
12894        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12895
12896        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12897        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12898        long nativePss=0, dalvikPss=0, otherPss=0;
12899        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12900
12901        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12902        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12903                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12904
12905        long totalPss = 0;
12906        long cachedPss = 0;
12907
12908        Debug.MemoryInfo mi = null;
12909        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12910            final ProcessRecord r = procs.get(i);
12911            final IApplicationThread thread;
12912            final int pid;
12913            final int oomAdj;
12914            final boolean hasActivities;
12915            synchronized (this) {
12916                thread = r.thread;
12917                pid = r.pid;
12918                oomAdj = r.getSetAdjWithServices();
12919                hasActivities = r.activities.size() > 0;
12920            }
12921            if (thread != null) {
12922                if (!isCheckinRequest && dumpDetails) {
12923                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12924                }
12925                if (mi == null) {
12926                    mi = new Debug.MemoryInfo();
12927                }
12928                if (dumpDetails || (!brief && !oomOnly)) {
12929                    Debug.getMemoryInfo(pid, mi);
12930                } else {
12931                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12932                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12933                }
12934                if (dumpDetails) {
12935                    if (localOnly) {
12936                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12937                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12938                        if (isCheckinRequest) {
12939                            pw.println();
12940                        }
12941                    } else {
12942                        try {
12943                            pw.flush();
12944                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12945                                    dumpDalvik, innerArgs);
12946                        } catch (RemoteException e) {
12947                            if (!isCheckinRequest) {
12948                                pw.println("Got RemoteException!");
12949                                pw.flush();
12950                            }
12951                        }
12952                    }
12953                }
12954
12955                final long myTotalPss = mi.getTotalPss();
12956                final long myTotalUss = mi.getTotalUss();
12957
12958                synchronized (this) {
12959                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12960                        // Record this for posterity if the process has been stable.
12961                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12962                    }
12963                }
12964
12965                if (!isCheckinRequest && mi != null) {
12966                    totalPss += myTotalPss;
12967                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12968                            (hasActivities ? " / activities)" : ")"),
12969                            r.processName, myTotalPss, pid, hasActivities);
12970                    procMems.add(pssItem);
12971                    procMemsMap.put(pid, pssItem);
12972
12973                    nativePss += mi.nativePss;
12974                    dalvikPss += mi.dalvikPss;
12975                    otherPss += mi.otherPss;
12976                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12977                        long mem = mi.getOtherPss(j);
12978                        miscPss[j] += mem;
12979                        otherPss -= mem;
12980                    }
12981
12982                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12983                        cachedPss += myTotalPss;
12984                    }
12985
12986                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12987                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12988                                || oomIndex == (oomPss.length-1)) {
12989                            oomPss[oomIndex] += myTotalPss;
12990                            if (oomProcs[oomIndex] == null) {
12991                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12992                            }
12993                            oomProcs[oomIndex].add(pssItem);
12994                            break;
12995                        }
12996                    }
12997                }
12998            }
12999        }
13000
13001        long nativeProcTotalPss = 0;
13002
13003        if (!isCheckinRequest && procs.size() > 1) {
13004            // If we are showing aggregations, also look for native processes to
13005            // include so that our aggregations are more accurate.
13006            updateCpuStatsNow();
13007            synchronized (mProcessCpuThread) {
13008                final int N = mProcessCpuTracker.countStats();
13009                for (int i=0; i<N; i++) {
13010                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13011                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13012                        if (mi == null) {
13013                            mi = new Debug.MemoryInfo();
13014                        }
13015                        if (!brief && !oomOnly) {
13016                            Debug.getMemoryInfo(st.pid, mi);
13017                        } else {
13018                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13019                            mi.nativePrivateDirty = (int)tmpLong[0];
13020                        }
13021
13022                        final long myTotalPss = mi.getTotalPss();
13023                        totalPss += myTotalPss;
13024                        nativeProcTotalPss += myTotalPss;
13025
13026                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13027                                st.name, myTotalPss, st.pid, false);
13028                        procMems.add(pssItem);
13029
13030                        nativePss += mi.nativePss;
13031                        dalvikPss += mi.dalvikPss;
13032                        otherPss += mi.otherPss;
13033                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13034                            long mem = mi.getOtherPss(j);
13035                            miscPss[j] += mem;
13036                            otherPss -= mem;
13037                        }
13038                        oomPss[0] += myTotalPss;
13039                        if (oomProcs[0] == null) {
13040                            oomProcs[0] = new ArrayList<MemItem>();
13041                        }
13042                        oomProcs[0].add(pssItem);
13043                    }
13044                }
13045            }
13046
13047            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13048
13049            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13050            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13051            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13052            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13053                String label = Debug.MemoryInfo.getOtherLabel(j);
13054                catMems.add(new MemItem(label, label, miscPss[j], j));
13055            }
13056
13057            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13058            for (int j=0; j<oomPss.length; j++) {
13059                if (oomPss[j] != 0) {
13060                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13061                            : DUMP_MEM_OOM_LABEL[j];
13062                    MemItem item = new MemItem(label, label, oomPss[j],
13063                            DUMP_MEM_OOM_ADJ[j]);
13064                    item.subitems = oomProcs[j];
13065                    oomMems.add(item);
13066                }
13067            }
13068
13069            if (!brief && !oomOnly && !isCompact) {
13070                pw.println();
13071                pw.println("Total PSS by process:");
13072                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13073                pw.println();
13074            }
13075            if (!isCompact) {
13076                pw.println("Total PSS by OOM adjustment:");
13077            }
13078            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13079            if (!brief && !oomOnly) {
13080                PrintWriter out = categoryPw != null ? categoryPw : pw;
13081                if (!isCompact) {
13082                    out.println();
13083                    out.println("Total PSS by category:");
13084                }
13085                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13086            }
13087            if (!isCompact) {
13088                pw.println();
13089            }
13090            MemInfoReader memInfo = new MemInfoReader();
13091            memInfo.readMemInfo();
13092            if (nativeProcTotalPss > 0) {
13093                synchronized (this) {
13094                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13095                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13096                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13097                            nativeProcTotalPss);
13098                }
13099            }
13100            if (!brief) {
13101                if (!isCompact) {
13102                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13103                    pw.print(" kB (status ");
13104                    switch (mLastMemoryLevel) {
13105                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13106                            pw.println("normal)");
13107                            break;
13108                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13109                            pw.println("moderate)");
13110                            break;
13111                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13112                            pw.println("low)");
13113                            break;
13114                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13115                            pw.println("critical)");
13116                            break;
13117                        default:
13118                            pw.print(mLastMemoryLevel);
13119                            pw.println(")");
13120                            break;
13121                    }
13122                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13123                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13124                            pw.print(cachedPss); pw.print(" cached pss + ");
13125                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13126                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13127                } else {
13128                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13129                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13130                            + memInfo.getFreeSizeKb()); pw.print(",");
13131                    pw.println(totalPss - cachedPss);
13132                }
13133            }
13134            if (!isCompact) {
13135                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13136                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13137                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13138                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13139                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13140                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13141                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13142                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13143                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13144                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13145                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13146            }
13147            if (!brief) {
13148                if (memInfo.getZramTotalSizeKb() != 0) {
13149                    if (!isCompact) {
13150                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13151                                pw.print(" kB physical used for ");
13152                                pw.print(memInfo.getSwapTotalSizeKb()
13153                                        - memInfo.getSwapFreeSizeKb());
13154                                pw.print(" kB in swap (");
13155                                pw.print(memInfo.getSwapTotalSizeKb());
13156                                pw.println(" kB total swap)");
13157                    } else {
13158                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13159                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13160                                pw.println(memInfo.getSwapFreeSizeKb());
13161                    }
13162                }
13163                final int[] SINGLE_LONG_FORMAT = new int[] {
13164                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13165                };
13166                long[] longOut = new long[1];
13167                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13168                        SINGLE_LONG_FORMAT, null, longOut, null);
13169                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13170                longOut[0] = 0;
13171                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13172                        SINGLE_LONG_FORMAT, null, longOut, null);
13173                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13174                longOut[0] = 0;
13175                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13176                        SINGLE_LONG_FORMAT, null, longOut, null);
13177                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13178                longOut[0] = 0;
13179                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13180                        SINGLE_LONG_FORMAT, null, longOut, null);
13181                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13182                if (!isCompact) {
13183                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13184                        pw.print("      KSM: "); pw.print(sharing);
13185                                pw.print(" kB saved from shared ");
13186                                pw.print(shared); pw.println(" kB");
13187                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13188                                pw.print(voltile); pw.println(" kB volatile");
13189                    }
13190                    pw.print("   Tuning: ");
13191                    pw.print(ActivityManager.staticGetMemoryClass());
13192                    pw.print(" (large ");
13193                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13194                    pw.print("), oom ");
13195                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13196                    pw.print(" kB");
13197                    pw.print(", restore limit ");
13198                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13199                    pw.print(" kB");
13200                    if (ActivityManager.isLowRamDeviceStatic()) {
13201                        pw.print(" (low-ram)");
13202                    }
13203                    if (ActivityManager.isHighEndGfx()) {
13204                        pw.print(" (high-end-gfx)");
13205                    }
13206                    pw.println();
13207                } else {
13208                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13209                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13210                    pw.println(voltile);
13211                    pw.print("tuning,");
13212                    pw.print(ActivityManager.staticGetMemoryClass());
13213                    pw.print(',');
13214                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13215                    pw.print(',');
13216                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13217                    if (ActivityManager.isLowRamDeviceStatic()) {
13218                        pw.print(",low-ram");
13219                    }
13220                    if (ActivityManager.isHighEndGfx()) {
13221                        pw.print(",high-end-gfx");
13222                    }
13223                    pw.println();
13224                }
13225            }
13226        }
13227    }
13228
13229    /**
13230     * Searches array of arguments for the specified string
13231     * @param args array of argument strings
13232     * @param value value to search for
13233     * @return true if the value is contained in the array
13234     */
13235    private static boolean scanArgs(String[] args, String value) {
13236        if (args != null) {
13237            for (String arg : args) {
13238                if (value.equals(arg)) {
13239                    return true;
13240                }
13241            }
13242        }
13243        return false;
13244    }
13245
13246    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13247            ContentProviderRecord cpr, boolean always) {
13248        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13249
13250        if (!inLaunching || always) {
13251            synchronized (cpr) {
13252                cpr.launchingApp = null;
13253                cpr.notifyAll();
13254            }
13255            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13256            String names[] = cpr.info.authority.split(";");
13257            for (int j = 0; j < names.length; j++) {
13258                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13259            }
13260        }
13261
13262        for (int i=0; i<cpr.connections.size(); i++) {
13263            ContentProviderConnection conn = cpr.connections.get(i);
13264            if (conn.waiting) {
13265                // If this connection is waiting for the provider, then we don't
13266                // need to mess with its process unless we are always removing
13267                // or for some reason the provider is not currently launching.
13268                if (inLaunching && !always) {
13269                    continue;
13270                }
13271            }
13272            ProcessRecord capp = conn.client;
13273            conn.dead = true;
13274            if (conn.stableCount > 0) {
13275                if (!capp.persistent && capp.thread != null
13276                        && capp.pid != 0
13277                        && capp.pid != MY_PID) {
13278                    killUnneededProcessLocked(capp, "depends on provider "
13279                            + cpr.name.flattenToShortString()
13280                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13281                }
13282            } else if (capp.thread != null && conn.provider.provider != null) {
13283                try {
13284                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13285                } catch (RemoteException e) {
13286                }
13287                // In the protocol here, we don't expect the client to correctly
13288                // clean up this connection, we'll just remove it.
13289                cpr.connections.remove(i);
13290                conn.client.conProviders.remove(conn);
13291            }
13292        }
13293
13294        if (inLaunching && always) {
13295            mLaunchingProviders.remove(cpr);
13296        }
13297        return inLaunching;
13298    }
13299
13300    /**
13301     * Main code for cleaning up a process when it has gone away.  This is
13302     * called both as a result of the process dying, or directly when stopping
13303     * a process when running in single process mode.
13304     */
13305    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13306            boolean restarting, boolean allowRestart, int index) {
13307        if (index >= 0) {
13308            removeLruProcessLocked(app);
13309            ProcessList.remove(app.pid);
13310        }
13311
13312        mProcessesToGc.remove(app);
13313        mPendingPssProcesses.remove(app);
13314
13315        // Dismiss any open dialogs.
13316        if (app.crashDialog != null && !app.forceCrashReport) {
13317            app.crashDialog.dismiss();
13318            app.crashDialog = null;
13319        }
13320        if (app.anrDialog != null) {
13321            app.anrDialog.dismiss();
13322            app.anrDialog = null;
13323        }
13324        if (app.waitDialog != null) {
13325            app.waitDialog.dismiss();
13326            app.waitDialog = null;
13327        }
13328
13329        app.crashing = false;
13330        app.notResponding = false;
13331
13332        app.resetPackageList(mProcessStats);
13333        app.unlinkDeathRecipient();
13334        app.makeInactive(mProcessStats);
13335        app.waitingToKill = null;
13336        app.forcingToForeground = null;
13337        updateProcessForegroundLocked(app, false, false);
13338        app.foregroundActivities = false;
13339        app.hasShownUi = false;
13340        app.treatLikeActivity = false;
13341        app.hasAboveClient = false;
13342        app.hasClientActivities = false;
13343
13344        mServices.killServicesLocked(app, allowRestart);
13345
13346        boolean restart = false;
13347
13348        // Remove published content providers.
13349        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13350            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13351            final boolean always = app.bad || !allowRestart;
13352            if (removeDyingProviderLocked(app, cpr, always) || always) {
13353                // We left the provider in the launching list, need to
13354                // restart it.
13355                restart = true;
13356            }
13357
13358            cpr.provider = null;
13359            cpr.proc = null;
13360        }
13361        app.pubProviders.clear();
13362
13363        // Take care of any launching providers waiting for this process.
13364        if (checkAppInLaunchingProvidersLocked(app, false)) {
13365            restart = true;
13366        }
13367
13368        // Unregister from connected content providers.
13369        if (!app.conProviders.isEmpty()) {
13370            for (int i=0; i<app.conProviders.size(); i++) {
13371                ContentProviderConnection conn = app.conProviders.get(i);
13372                conn.provider.connections.remove(conn);
13373            }
13374            app.conProviders.clear();
13375        }
13376
13377        // At this point there may be remaining entries in mLaunchingProviders
13378        // where we were the only one waiting, so they are no longer of use.
13379        // Look for these and clean up if found.
13380        // XXX Commented out for now.  Trying to figure out a way to reproduce
13381        // the actual situation to identify what is actually going on.
13382        if (false) {
13383            for (int i=0; i<mLaunchingProviders.size(); i++) {
13384                ContentProviderRecord cpr = (ContentProviderRecord)
13385                        mLaunchingProviders.get(i);
13386                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13387                    synchronized (cpr) {
13388                        cpr.launchingApp = null;
13389                        cpr.notifyAll();
13390                    }
13391                }
13392            }
13393        }
13394
13395        skipCurrentReceiverLocked(app);
13396
13397        // Unregister any receivers.
13398        for (int i=app.receivers.size()-1; i>=0; i--) {
13399            removeReceiverLocked(app.receivers.valueAt(i));
13400        }
13401        app.receivers.clear();
13402
13403        // If the app is undergoing backup, tell the backup manager about it
13404        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13405            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13406                    + mBackupTarget.appInfo + " died during backup");
13407            try {
13408                IBackupManager bm = IBackupManager.Stub.asInterface(
13409                        ServiceManager.getService(Context.BACKUP_SERVICE));
13410                bm.agentDisconnected(app.info.packageName);
13411            } catch (RemoteException e) {
13412                // can't happen; backup manager is local
13413            }
13414        }
13415
13416        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13417            ProcessChangeItem item = mPendingProcessChanges.get(i);
13418            if (item.pid == app.pid) {
13419                mPendingProcessChanges.remove(i);
13420                mAvailProcessChanges.add(item);
13421            }
13422        }
13423        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13424
13425        // If the caller is restarting this app, then leave it in its
13426        // current lists and let the caller take care of it.
13427        if (restarting) {
13428            return;
13429        }
13430
13431        if (!app.persistent || app.isolated) {
13432            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13433                    "Removing non-persistent process during cleanup: " + app);
13434            mProcessNames.remove(app.processName, app.uid);
13435            mIsolatedProcesses.remove(app.uid);
13436            if (mHeavyWeightProcess == app) {
13437                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13438                        mHeavyWeightProcess.userId, 0));
13439                mHeavyWeightProcess = null;
13440            }
13441        } else if (!app.removed) {
13442            // This app is persistent, so we need to keep its record around.
13443            // If it is not already on the pending app list, add it there
13444            // and start a new process for it.
13445            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13446                mPersistentStartingProcesses.add(app);
13447                restart = true;
13448            }
13449        }
13450        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13451                "Clean-up removing on hold: " + app);
13452        mProcessesOnHold.remove(app);
13453
13454        if (app == mHomeProcess) {
13455            mHomeProcess = null;
13456        }
13457        if (app == mPreviousProcess) {
13458            mPreviousProcess = null;
13459        }
13460
13461        if (restart && !app.isolated) {
13462            // We have components that still need to be running in the
13463            // process, so re-launch it.
13464            mProcessNames.put(app.processName, app.uid, app);
13465            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13466        } else if (app.pid > 0 && app.pid != MY_PID) {
13467            // Goodbye!
13468            boolean removed;
13469            synchronized (mPidsSelfLocked) {
13470                mPidsSelfLocked.remove(app.pid);
13471                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13472            }
13473            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13474            if (app.isolated) {
13475                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13476            }
13477            app.setPid(0);
13478        }
13479    }
13480
13481    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13482        // Look through the content providers we are waiting to have launched,
13483        // and if any run in this process then either schedule a restart of
13484        // the process or kill the client waiting for it if this process has
13485        // gone bad.
13486        int NL = mLaunchingProviders.size();
13487        boolean restart = false;
13488        for (int i=0; i<NL; i++) {
13489            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13490            if (cpr.launchingApp == app) {
13491                if (!alwaysBad && !app.bad) {
13492                    restart = true;
13493                } else {
13494                    removeDyingProviderLocked(app, cpr, true);
13495                    // cpr should have been removed from mLaunchingProviders
13496                    NL = mLaunchingProviders.size();
13497                    i--;
13498                }
13499            }
13500        }
13501        return restart;
13502    }
13503
13504    // =========================================================
13505    // SERVICES
13506    // =========================================================
13507
13508    @Override
13509    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13510            int flags) {
13511        enforceNotIsolatedCaller("getServices");
13512        synchronized (this) {
13513            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13514        }
13515    }
13516
13517    @Override
13518    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13519        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13520        synchronized (this) {
13521            return mServices.getRunningServiceControlPanelLocked(name);
13522        }
13523    }
13524
13525    @Override
13526    public ComponentName startService(IApplicationThread caller, Intent service,
13527            String resolvedType, int userId) {
13528        enforceNotIsolatedCaller("startService");
13529        // Refuse possible leaked file descriptors
13530        if (service != null && service.hasFileDescriptors() == true) {
13531            throw new IllegalArgumentException("File descriptors passed in Intent");
13532        }
13533
13534        if (DEBUG_SERVICE)
13535            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13536        synchronized(this) {
13537            final int callingPid = Binder.getCallingPid();
13538            final int callingUid = Binder.getCallingUid();
13539            final long origId = Binder.clearCallingIdentity();
13540            ComponentName res = mServices.startServiceLocked(caller, service,
13541                    resolvedType, callingPid, callingUid, userId);
13542            Binder.restoreCallingIdentity(origId);
13543            return res;
13544        }
13545    }
13546
13547    ComponentName startServiceInPackage(int uid,
13548            Intent service, String resolvedType, int userId) {
13549        synchronized(this) {
13550            if (DEBUG_SERVICE)
13551                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13552            final long origId = Binder.clearCallingIdentity();
13553            ComponentName res = mServices.startServiceLocked(null, service,
13554                    resolvedType, -1, uid, userId);
13555            Binder.restoreCallingIdentity(origId);
13556            return res;
13557        }
13558    }
13559
13560    @Override
13561    public int stopService(IApplicationThread caller, Intent service,
13562            String resolvedType, int userId) {
13563        enforceNotIsolatedCaller("stopService");
13564        // Refuse possible leaked file descriptors
13565        if (service != null && service.hasFileDescriptors() == true) {
13566            throw new IllegalArgumentException("File descriptors passed in Intent");
13567        }
13568
13569        synchronized(this) {
13570            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13571        }
13572    }
13573
13574    @Override
13575    public IBinder peekService(Intent service, String resolvedType) {
13576        enforceNotIsolatedCaller("peekService");
13577        // Refuse possible leaked file descriptors
13578        if (service != null && service.hasFileDescriptors() == true) {
13579            throw new IllegalArgumentException("File descriptors passed in Intent");
13580        }
13581        synchronized(this) {
13582            return mServices.peekServiceLocked(service, resolvedType);
13583        }
13584    }
13585
13586    @Override
13587    public boolean stopServiceToken(ComponentName className, IBinder token,
13588            int startId) {
13589        synchronized(this) {
13590            return mServices.stopServiceTokenLocked(className, token, startId);
13591        }
13592    }
13593
13594    @Override
13595    public void setServiceForeground(ComponentName className, IBinder token,
13596            int id, Notification notification, boolean removeNotification) {
13597        synchronized(this) {
13598            mServices.setServiceForegroundLocked(className, token, id, notification,
13599                    removeNotification);
13600        }
13601    }
13602
13603    @Override
13604    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13605            boolean requireFull, String name, String callerPackage) {
13606        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13607                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13608    }
13609
13610    int unsafeConvertIncomingUser(int userId) {
13611        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13612                ? mCurrentUserId : userId;
13613    }
13614
13615    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13616            int allowMode, String name, String callerPackage) {
13617        final int callingUserId = UserHandle.getUserId(callingUid);
13618        if (callingUserId == userId) {
13619            return userId;
13620        }
13621
13622        // Note that we may be accessing mCurrentUserId outside of a lock...
13623        // shouldn't be a big deal, if this is being called outside
13624        // of a locked context there is intrinsically a race with
13625        // the value the caller will receive and someone else changing it.
13626        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13627        // we will switch to the calling user if access to the current user fails.
13628        int targetUserId = unsafeConvertIncomingUser(userId);
13629
13630        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13631            final boolean allow;
13632            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13633                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13634                // If the caller has this permission, they always pass go.  And collect $200.
13635                allow = true;
13636            } else if (allowMode == ALLOW_FULL_ONLY) {
13637                // We require full access, sucks to be you.
13638                allow = false;
13639            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13640                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13641                // If the caller does not have either permission, they are always doomed.
13642                allow = false;
13643            } else if (allowMode == ALLOW_NON_FULL) {
13644                // We are blanket allowing non-full access, you lucky caller!
13645                allow = true;
13646            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13647                // We may or may not allow this depending on whether the two users are
13648                // in the same profile.
13649                synchronized (mUserProfileGroupIdsSelfLocked) {
13650                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13651                            UserInfo.NO_PROFILE_GROUP_ID);
13652                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13653                            UserInfo.NO_PROFILE_GROUP_ID);
13654                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13655                            && callingProfile == targetProfile;
13656                }
13657            } else {
13658                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13659            }
13660            if (!allow) {
13661                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13662                    // In this case, they would like to just execute as their
13663                    // owner user instead of failing.
13664                    targetUserId = callingUserId;
13665                } else {
13666                    StringBuilder builder = new StringBuilder(128);
13667                    builder.append("Permission Denial: ");
13668                    builder.append(name);
13669                    if (callerPackage != null) {
13670                        builder.append(" from ");
13671                        builder.append(callerPackage);
13672                    }
13673                    builder.append(" asks to run as user ");
13674                    builder.append(userId);
13675                    builder.append(" but is calling from user ");
13676                    builder.append(UserHandle.getUserId(callingUid));
13677                    builder.append("; this requires ");
13678                    builder.append(INTERACT_ACROSS_USERS_FULL);
13679                    if (allowMode != ALLOW_FULL_ONLY) {
13680                        builder.append(" or ");
13681                        builder.append(INTERACT_ACROSS_USERS);
13682                    }
13683                    String msg = builder.toString();
13684                    Slog.w(TAG, msg);
13685                    throw new SecurityException(msg);
13686                }
13687            }
13688        }
13689        if (!allowAll && targetUserId < 0) {
13690            throw new IllegalArgumentException(
13691                    "Call does not support special user #" + targetUserId);
13692        }
13693        return targetUserId;
13694    }
13695
13696    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13697            String className, int flags) {
13698        boolean result = false;
13699        // For apps that don't have pre-defined UIDs, check for permission
13700        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13701            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13702                if (ActivityManager.checkUidPermission(
13703                        INTERACT_ACROSS_USERS,
13704                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13705                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13706                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13707                            + " requests FLAG_SINGLE_USER, but app does not hold "
13708                            + INTERACT_ACROSS_USERS;
13709                    Slog.w(TAG, msg);
13710                    throw new SecurityException(msg);
13711                }
13712                // Permission passed
13713                result = true;
13714            }
13715        } else if ("system".equals(componentProcessName)) {
13716            result = true;
13717        } else {
13718            // App with pre-defined UID, check if it's a persistent app
13719            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13720        }
13721        if (DEBUG_MU) {
13722            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13723                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13724        }
13725        return result;
13726    }
13727
13728    /**
13729     * Checks to see if the caller is in the same app as the singleton
13730     * component, or the component is in a special app. It allows special apps
13731     * to export singleton components but prevents exporting singleton
13732     * components for regular apps.
13733     */
13734    boolean isValidSingletonCall(int callingUid, int componentUid) {
13735        int componentAppId = UserHandle.getAppId(componentUid);
13736        return UserHandle.isSameApp(callingUid, componentUid)
13737                || componentAppId == Process.SYSTEM_UID
13738                || componentAppId == Process.PHONE_UID
13739                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13740                        == PackageManager.PERMISSION_GRANTED;
13741    }
13742
13743    public int bindService(IApplicationThread caller, IBinder token,
13744            Intent service, String resolvedType,
13745            IServiceConnection connection, int flags, int userId) {
13746        enforceNotIsolatedCaller("bindService");
13747        // Refuse possible leaked file descriptors
13748        if (service != null && service.hasFileDescriptors() == true) {
13749            throw new IllegalArgumentException("File descriptors passed in Intent");
13750        }
13751
13752        synchronized(this) {
13753            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13754                    connection, flags, userId);
13755        }
13756    }
13757
13758    public boolean unbindService(IServiceConnection connection) {
13759        synchronized (this) {
13760            return mServices.unbindServiceLocked(connection);
13761        }
13762    }
13763
13764    public void publishService(IBinder token, Intent intent, IBinder service) {
13765        // Refuse possible leaked file descriptors
13766        if (intent != null && intent.hasFileDescriptors() == true) {
13767            throw new IllegalArgumentException("File descriptors passed in Intent");
13768        }
13769
13770        synchronized(this) {
13771            if (!(token instanceof ServiceRecord)) {
13772                throw new IllegalArgumentException("Invalid service token");
13773            }
13774            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13775        }
13776    }
13777
13778    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13779        // Refuse possible leaked file descriptors
13780        if (intent != null && intent.hasFileDescriptors() == true) {
13781            throw new IllegalArgumentException("File descriptors passed in Intent");
13782        }
13783
13784        synchronized(this) {
13785            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13786        }
13787    }
13788
13789    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13790        synchronized(this) {
13791            if (!(token instanceof ServiceRecord)) {
13792                throw new IllegalArgumentException("Invalid service token");
13793            }
13794            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13795        }
13796    }
13797
13798    // =========================================================
13799    // BACKUP AND RESTORE
13800    // =========================================================
13801
13802    // Cause the target app to be launched if necessary and its backup agent
13803    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13804    // activity manager to announce its creation.
13805    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13806        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13807        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13808
13809        synchronized(this) {
13810            // !!! TODO: currently no check here that we're already bound
13811            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13812            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13813            synchronized (stats) {
13814                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13815            }
13816
13817            // Backup agent is now in use, its package can't be stopped.
13818            try {
13819                AppGlobals.getPackageManager().setPackageStoppedState(
13820                        app.packageName, false, UserHandle.getUserId(app.uid));
13821            } catch (RemoteException e) {
13822            } catch (IllegalArgumentException e) {
13823                Slog.w(TAG, "Failed trying to unstop package "
13824                        + app.packageName + ": " + e);
13825            }
13826
13827            BackupRecord r = new BackupRecord(ss, app, backupMode);
13828            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13829                    ? new ComponentName(app.packageName, app.backupAgentName)
13830                    : new ComponentName("android", "FullBackupAgent");
13831            // startProcessLocked() returns existing proc's record if it's already running
13832            ProcessRecord proc = startProcessLocked(app.processName, app,
13833                    false, 0, "backup", hostingName, false, false, false);
13834            if (proc == null) {
13835                Slog.e(TAG, "Unable to start backup agent process " + r);
13836                return false;
13837            }
13838
13839            r.app = proc;
13840            mBackupTarget = r;
13841            mBackupAppName = app.packageName;
13842
13843            // Try not to kill the process during backup
13844            updateOomAdjLocked(proc);
13845
13846            // If the process is already attached, schedule the creation of the backup agent now.
13847            // If it is not yet live, this will be done when it attaches to the framework.
13848            if (proc.thread != null) {
13849                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13850                try {
13851                    proc.thread.scheduleCreateBackupAgent(app,
13852                            compatibilityInfoForPackageLocked(app), backupMode);
13853                } catch (RemoteException e) {
13854                    // Will time out on the backup manager side
13855                }
13856            } else {
13857                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13858            }
13859            // Invariants: at this point, the target app process exists and the application
13860            // is either already running or in the process of coming up.  mBackupTarget and
13861            // mBackupAppName describe the app, so that when it binds back to the AM we
13862            // know that it's scheduled for a backup-agent operation.
13863        }
13864
13865        return true;
13866    }
13867
13868    @Override
13869    public void clearPendingBackup() {
13870        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13871        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13872
13873        synchronized (this) {
13874            mBackupTarget = null;
13875            mBackupAppName = null;
13876        }
13877    }
13878
13879    // A backup agent has just come up
13880    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13881        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13882                + " = " + agent);
13883
13884        synchronized(this) {
13885            if (!agentPackageName.equals(mBackupAppName)) {
13886                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13887                return;
13888            }
13889        }
13890
13891        long oldIdent = Binder.clearCallingIdentity();
13892        try {
13893            IBackupManager bm = IBackupManager.Stub.asInterface(
13894                    ServiceManager.getService(Context.BACKUP_SERVICE));
13895            bm.agentConnected(agentPackageName, agent);
13896        } catch (RemoteException e) {
13897            // can't happen; the backup manager service is local
13898        } catch (Exception e) {
13899            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13900            e.printStackTrace();
13901        } finally {
13902            Binder.restoreCallingIdentity(oldIdent);
13903        }
13904    }
13905
13906    // done with this agent
13907    public void unbindBackupAgent(ApplicationInfo appInfo) {
13908        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13909        if (appInfo == null) {
13910            Slog.w(TAG, "unbind backup agent for null app");
13911            return;
13912        }
13913
13914        synchronized(this) {
13915            try {
13916                if (mBackupAppName == null) {
13917                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13918                    return;
13919                }
13920
13921                if (!mBackupAppName.equals(appInfo.packageName)) {
13922                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13923                    return;
13924                }
13925
13926                // Not backing this app up any more; reset its OOM adjustment
13927                final ProcessRecord proc = mBackupTarget.app;
13928                updateOomAdjLocked(proc);
13929
13930                // If the app crashed during backup, 'thread' will be null here
13931                if (proc.thread != null) {
13932                    try {
13933                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13934                                compatibilityInfoForPackageLocked(appInfo));
13935                    } catch (Exception e) {
13936                        Slog.e(TAG, "Exception when unbinding backup agent:");
13937                        e.printStackTrace();
13938                    }
13939                }
13940            } finally {
13941                mBackupTarget = null;
13942                mBackupAppName = null;
13943            }
13944        }
13945    }
13946    // =========================================================
13947    // BROADCASTS
13948    // =========================================================
13949
13950    private final List getStickiesLocked(String action, IntentFilter filter,
13951            List cur, int userId) {
13952        final ContentResolver resolver = mContext.getContentResolver();
13953        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13954        if (stickies == null) {
13955            return cur;
13956        }
13957        final ArrayList<Intent> list = stickies.get(action);
13958        if (list == null) {
13959            return cur;
13960        }
13961        int N = list.size();
13962        for (int i=0; i<N; i++) {
13963            Intent intent = list.get(i);
13964            if (filter.match(resolver, intent, true, TAG) >= 0) {
13965                if (cur == null) {
13966                    cur = new ArrayList<Intent>();
13967                }
13968                cur.add(intent);
13969            }
13970        }
13971        return cur;
13972    }
13973
13974    boolean isPendingBroadcastProcessLocked(int pid) {
13975        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13976                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13977    }
13978
13979    void skipPendingBroadcastLocked(int pid) {
13980            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13981            for (BroadcastQueue queue : mBroadcastQueues) {
13982                queue.skipPendingBroadcastLocked(pid);
13983            }
13984    }
13985
13986    // The app just attached; send any pending broadcasts that it should receive
13987    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13988        boolean didSomething = false;
13989        for (BroadcastQueue queue : mBroadcastQueues) {
13990            didSomething |= queue.sendPendingBroadcastsLocked(app);
13991        }
13992        return didSomething;
13993    }
13994
13995    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13996            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13997        enforceNotIsolatedCaller("registerReceiver");
13998        int callingUid;
13999        int callingPid;
14000        synchronized(this) {
14001            ProcessRecord callerApp = null;
14002            if (caller != null) {
14003                callerApp = getRecordForAppLocked(caller);
14004                if (callerApp == null) {
14005                    throw new SecurityException(
14006                            "Unable to find app for caller " + caller
14007                            + " (pid=" + Binder.getCallingPid()
14008                            + ") when registering receiver " + receiver);
14009                }
14010                if (callerApp.info.uid != Process.SYSTEM_UID &&
14011                        !callerApp.pkgList.containsKey(callerPackage) &&
14012                        !"android".equals(callerPackage)) {
14013                    throw new SecurityException("Given caller package " + callerPackage
14014                            + " is not running in process " + callerApp);
14015                }
14016                callingUid = callerApp.info.uid;
14017                callingPid = callerApp.pid;
14018            } else {
14019                callerPackage = null;
14020                callingUid = Binder.getCallingUid();
14021                callingPid = Binder.getCallingPid();
14022            }
14023
14024            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14025                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14026
14027            List allSticky = null;
14028
14029            // Look for any matching sticky broadcasts...
14030            Iterator actions = filter.actionsIterator();
14031            if (actions != null) {
14032                while (actions.hasNext()) {
14033                    String action = (String)actions.next();
14034                    allSticky = getStickiesLocked(action, filter, allSticky,
14035                            UserHandle.USER_ALL);
14036                    allSticky = getStickiesLocked(action, filter, allSticky,
14037                            UserHandle.getUserId(callingUid));
14038                }
14039            } else {
14040                allSticky = getStickiesLocked(null, filter, allSticky,
14041                        UserHandle.USER_ALL);
14042                allSticky = getStickiesLocked(null, filter, allSticky,
14043                        UserHandle.getUserId(callingUid));
14044            }
14045
14046            // The first sticky in the list is returned directly back to
14047            // the client.
14048            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14049
14050            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14051                    + ": " + sticky);
14052
14053            if (receiver == null) {
14054                return sticky;
14055            }
14056
14057            ReceiverList rl
14058                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14059            if (rl == null) {
14060                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14061                        userId, receiver);
14062                if (rl.app != null) {
14063                    rl.app.receivers.add(rl);
14064                } else {
14065                    try {
14066                        receiver.asBinder().linkToDeath(rl, 0);
14067                    } catch (RemoteException e) {
14068                        return sticky;
14069                    }
14070                    rl.linkedToDeath = true;
14071                }
14072                mRegisteredReceivers.put(receiver.asBinder(), rl);
14073            } else if (rl.uid != callingUid) {
14074                throw new IllegalArgumentException(
14075                        "Receiver requested to register for uid " + callingUid
14076                        + " was previously registered for uid " + rl.uid);
14077            } else if (rl.pid != callingPid) {
14078                throw new IllegalArgumentException(
14079                        "Receiver requested to register for pid " + callingPid
14080                        + " was previously registered for pid " + rl.pid);
14081            } else if (rl.userId != userId) {
14082                throw new IllegalArgumentException(
14083                        "Receiver requested to register for user " + userId
14084                        + " was previously registered for user " + rl.userId);
14085            }
14086            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14087                    permission, callingUid, userId);
14088            rl.add(bf);
14089            if (!bf.debugCheck()) {
14090                Slog.w(TAG, "==> For Dynamic broadast");
14091            }
14092            mReceiverResolver.addFilter(bf);
14093
14094            // Enqueue broadcasts for all existing stickies that match
14095            // this filter.
14096            if (allSticky != null) {
14097                ArrayList receivers = new ArrayList();
14098                receivers.add(bf);
14099
14100                int N = allSticky.size();
14101                for (int i=0; i<N; i++) {
14102                    Intent intent = (Intent)allSticky.get(i);
14103                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14104                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14105                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14106                            null, null, false, true, true, -1);
14107                    queue.enqueueParallelBroadcastLocked(r);
14108                    queue.scheduleBroadcastsLocked();
14109                }
14110            }
14111
14112            return sticky;
14113        }
14114    }
14115
14116    public void unregisterReceiver(IIntentReceiver receiver) {
14117        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14118
14119        final long origId = Binder.clearCallingIdentity();
14120        try {
14121            boolean doTrim = false;
14122
14123            synchronized(this) {
14124                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14125                if (rl != null) {
14126                    if (rl.curBroadcast != null) {
14127                        BroadcastRecord r = rl.curBroadcast;
14128                        final boolean doNext = finishReceiverLocked(
14129                                receiver.asBinder(), r.resultCode, r.resultData,
14130                                r.resultExtras, r.resultAbort);
14131                        if (doNext) {
14132                            doTrim = true;
14133                            r.queue.processNextBroadcast(false);
14134                        }
14135                    }
14136
14137                    if (rl.app != null) {
14138                        rl.app.receivers.remove(rl);
14139                    }
14140                    removeReceiverLocked(rl);
14141                    if (rl.linkedToDeath) {
14142                        rl.linkedToDeath = false;
14143                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14144                    }
14145                }
14146            }
14147
14148            // If we actually concluded any broadcasts, we might now be able
14149            // to trim the recipients' apps from our working set
14150            if (doTrim) {
14151                trimApplications();
14152                return;
14153            }
14154
14155        } finally {
14156            Binder.restoreCallingIdentity(origId);
14157        }
14158    }
14159
14160    void removeReceiverLocked(ReceiverList rl) {
14161        mRegisteredReceivers.remove(rl.receiver.asBinder());
14162        int N = rl.size();
14163        for (int i=0; i<N; i++) {
14164            mReceiverResolver.removeFilter(rl.get(i));
14165        }
14166    }
14167
14168    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14169        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14170            ProcessRecord r = mLruProcesses.get(i);
14171            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14172                try {
14173                    r.thread.dispatchPackageBroadcast(cmd, packages);
14174                } catch (RemoteException ex) {
14175                }
14176            }
14177        }
14178    }
14179
14180    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14181            int[] users) {
14182        List<ResolveInfo> receivers = null;
14183        try {
14184            HashSet<ComponentName> singleUserReceivers = null;
14185            boolean scannedFirstReceivers = false;
14186            for (int user : users) {
14187                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14188                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14189                if (user != 0 && newReceivers != null) {
14190                    // If this is not the primary user, we need to check for
14191                    // any receivers that should be filtered out.
14192                    for (int i=0; i<newReceivers.size(); i++) {
14193                        ResolveInfo ri = newReceivers.get(i);
14194                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14195                            newReceivers.remove(i);
14196                            i--;
14197                        }
14198                    }
14199                }
14200                if (newReceivers != null && newReceivers.size() == 0) {
14201                    newReceivers = null;
14202                }
14203                if (receivers == null) {
14204                    receivers = newReceivers;
14205                } else if (newReceivers != null) {
14206                    // We need to concatenate the additional receivers
14207                    // found with what we have do far.  This would be easy,
14208                    // but we also need to de-dup any receivers that are
14209                    // singleUser.
14210                    if (!scannedFirstReceivers) {
14211                        // Collect any single user receivers we had already retrieved.
14212                        scannedFirstReceivers = true;
14213                        for (int i=0; i<receivers.size(); i++) {
14214                            ResolveInfo ri = receivers.get(i);
14215                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14216                                ComponentName cn = new ComponentName(
14217                                        ri.activityInfo.packageName, ri.activityInfo.name);
14218                                if (singleUserReceivers == null) {
14219                                    singleUserReceivers = new HashSet<ComponentName>();
14220                                }
14221                                singleUserReceivers.add(cn);
14222                            }
14223                        }
14224                    }
14225                    // Add the new results to the existing results, tracking
14226                    // and de-dupping single user receivers.
14227                    for (int i=0; i<newReceivers.size(); i++) {
14228                        ResolveInfo ri = newReceivers.get(i);
14229                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14230                            ComponentName cn = new ComponentName(
14231                                    ri.activityInfo.packageName, ri.activityInfo.name);
14232                            if (singleUserReceivers == null) {
14233                                singleUserReceivers = new HashSet<ComponentName>();
14234                            }
14235                            if (!singleUserReceivers.contains(cn)) {
14236                                singleUserReceivers.add(cn);
14237                                receivers.add(ri);
14238                            }
14239                        } else {
14240                            receivers.add(ri);
14241                        }
14242                    }
14243                }
14244            }
14245        } catch (RemoteException ex) {
14246            // pm is in same process, this will never happen.
14247        }
14248        return receivers;
14249    }
14250
14251    private final int broadcastIntentLocked(ProcessRecord callerApp,
14252            String callerPackage, Intent intent, String resolvedType,
14253            IIntentReceiver resultTo, int resultCode, String resultData,
14254            Bundle map, String requiredPermission, int appOp,
14255            boolean ordered, boolean sticky, int callingPid, int callingUid,
14256            int userId) {
14257        intent = new Intent(intent);
14258
14259        // By default broadcasts do not go to stopped apps.
14260        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14261
14262        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14263            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14264            + " ordered=" + ordered + " userid=" + userId);
14265        if ((resultTo != null) && !ordered) {
14266            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14267        }
14268
14269        userId = handleIncomingUser(callingPid, callingUid, userId,
14270                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14271
14272        // Make sure that the user who is receiving this broadcast is started.
14273        // If not, we will just skip it.
14274
14275
14276        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14277            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14278                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14279                Slog.w(TAG, "Skipping broadcast of " + intent
14280                        + ": user " + userId + " is stopped");
14281                return ActivityManager.BROADCAST_SUCCESS;
14282            }
14283        }
14284
14285        /*
14286         * Prevent non-system code (defined here to be non-persistent
14287         * processes) from sending protected broadcasts.
14288         */
14289        int callingAppId = UserHandle.getAppId(callingUid);
14290        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14291            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14292            || callingAppId == Process.NFC_UID || callingUid == 0) {
14293            // Always okay.
14294        } else if (callerApp == null || !callerApp.persistent) {
14295            try {
14296                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14297                        intent.getAction())) {
14298                    String msg = "Permission Denial: not allowed to send broadcast "
14299                            + intent.getAction() + " from pid="
14300                            + callingPid + ", uid=" + callingUid;
14301                    Slog.w(TAG, msg);
14302                    throw new SecurityException(msg);
14303                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14304                    // Special case for compatibility: we don't want apps to send this,
14305                    // but historically it has not been protected and apps may be using it
14306                    // to poke their own app widget.  So, instead of making it protected,
14307                    // just limit it to the caller.
14308                    if (callerApp == null) {
14309                        String msg = "Permission Denial: not allowed to send broadcast "
14310                                + intent.getAction() + " from unknown caller.";
14311                        Slog.w(TAG, msg);
14312                        throw new SecurityException(msg);
14313                    } else if (intent.getComponent() != null) {
14314                        // They are good enough to send to an explicit component...  verify
14315                        // it is being sent to the calling app.
14316                        if (!intent.getComponent().getPackageName().equals(
14317                                callerApp.info.packageName)) {
14318                            String msg = "Permission Denial: not allowed to send broadcast "
14319                                    + intent.getAction() + " to "
14320                                    + intent.getComponent().getPackageName() + " from "
14321                                    + callerApp.info.packageName;
14322                            Slog.w(TAG, msg);
14323                            throw new SecurityException(msg);
14324                        }
14325                    } else {
14326                        // Limit broadcast to their own package.
14327                        intent.setPackage(callerApp.info.packageName);
14328                    }
14329                }
14330            } catch (RemoteException e) {
14331                Slog.w(TAG, "Remote exception", e);
14332                return ActivityManager.BROADCAST_SUCCESS;
14333            }
14334        }
14335
14336        // Handle special intents: if this broadcast is from the package
14337        // manager about a package being removed, we need to remove all of
14338        // its activities from the history stack.
14339        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14340                intent.getAction());
14341        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14342                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14343                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14344                || uidRemoved) {
14345            if (checkComponentPermission(
14346                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14347                    callingPid, callingUid, -1, true)
14348                    == PackageManager.PERMISSION_GRANTED) {
14349                if (uidRemoved) {
14350                    final Bundle intentExtras = intent.getExtras();
14351                    final int uid = intentExtras != null
14352                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14353                    if (uid >= 0) {
14354                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14355                        synchronized (bs) {
14356                            bs.removeUidStatsLocked(uid);
14357                        }
14358                        mAppOpsService.uidRemoved(uid);
14359                    }
14360                } else {
14361                    // If resources are unavailable just force stop all
14362                    // those packages and flush the attribute cache as well.
14363                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14364                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14365                        if (list != null && (list.length > 0)) {
14366                            for (String pkg : list) {
14367                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14368                                        "storage unmount");
14369                            }
14370                            sendPackageBroadcastLocked(
14371                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14372                        }
14373                    } else {
14374                        Uri data = intent.getData();
14375                        String ssp;
14376                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14377                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14378                                    intent.getAction());
14379                            boolean fullUninstall = removed &&
14380                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14381                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14382                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14383                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14384                                        false, fullUninstall, userId,
14385                                        removed ? "pkg removed" : "pkg changed");
14386                            }
14387                            if (removed) {
14388                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14389                                        new String[] {ssp}, userId);
14390                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14391                                    mAppOpsService.packageRemoved(
14392                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14393
14394                                    // Remove all permissions granted from/to this package
14395                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14396                                }
14397                            }
14398                        }
14399                    }
14400                }
14401            } else {
14402                String msg = "Permission Denial: " + intent.getAction()
14403                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14404                        + ", uid=" + callingUid + ")"
14405                        + " requires "
14406                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14407                Slog.w(TAG, msg);
14408                throw new SecurityException(msg);
14409            }
14410
14411        // Special case for adding a package: by default turn on compatibility
14412        // mode.
14413        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14414            Uri data = intent.getData();
14415            String ssp;
14416            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14417                mCompatModePackages.handlePackageAddedLocked(ssp,
14418                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14419            }
14420        }
14421
14422        /*
14423         * If this is the time zone changed action, queue up a message that will reset the timezone
14424         * of all currently running processes. This message will get queued up before the broadcast
14425         * happens.
14426         */
14427        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14428            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14429        }
14430
14431        /*
14432         * If the user set the time, let all running processes know.
14433         */
14434        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14435            final int is24Hour = intent.getBooleanExtra(
14436                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14437            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14438        }
14439
14440        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14441            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14442        }
14443
14444        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14445            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14446            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14447        }
14448
14449        // Add to the sticky list if requested.
14450        if (sticky) {
14451            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14452                    callingPid, callingUid)
14453                    != PackageManager.PERMISSION_GRANTED) {
14454                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14455                        + callingPid + ", uid=" + callingUid
14456                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14457                Slog.w(TAG, msg);
14458                throw new SecurityException(msg);
14459            }
14460            if (requiredPermission != null) {
14461                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14462                        + " and enforce permission " + requiredPermission);
14463                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14464            }
14465            if (intent.getComponent() != null) {
14466                throw new SecurityException(
14467                        "Sticky broadcasts can't target a specific component");
14468            }
14469            // We use userId directly here, since the "all" target is maintained
14470            // as a separate set of sticky broadcasts.
14471            if (userId != UserHandle.USER_ALL) {
14472                // But first, if this is not a broadcast to all users, then
14473                // make sure it doesn't conflict with an existing broadcast to
14474                // all users.
14475                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14476                        UserHandle.USER_ALL);
14477                if (stickies != null) {
14478                    ArrayList<Intent> list = stickies.get(intent.getAction());
14479                    if (list != null) {
14480                        int N = list.size();
14481                        int i;
14482                        for (i=0; i<N; i++) {
14483                            if (intent.filterEquals(list.get(i))) {
14484                                throw new IllegalArgumentException(
14485                                        "Sticky broadcast " + intent + " for user "
14486                                        + userId + " conflicts with existing global broadcast");
14487                            }
14488                        }
14489                    }
14490                }
14491            }
14492            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14493            if (stickies == null) {
14494                stickies = new ArrayMap<String, ArrayList<Intent>>();
14495                mStickyBroadcasts.put(userId, stickies);
14496            }
14497            ArrayList<Intent> list = stickies.get(intent.getAction());
14498            if (list == null) {
14499                list = new ArrayList<Intent>();
14500                stickies.put(intent.getAction(), list);
14501            }
14502            int N = list.size();
14503            int i;
14504            for (i=0; i<N; i++) {
14505                if (intent.filterEquals(list.get(i))) {
14506                    // This sticky already exists, replace it.
14507                    list.set(i, new Intent(intent));
14508                    break;
14509                }
14510            }
14511            if (i >= N) {
14512                list.add(new Intent(intent));
14513            }
14514        }
14515
14516        int[] users;
14517        if (userId == UserHandle.USER_ALL) {
14518            // Caller wants broadcast to go to all started users.
14519            users = mStartedUserArray;
14520        } else {
14521            // Caller wants broadcast to go to one specific user.
14522            users = new int[] {userId};
14523        }
14524
14525        // Figure out who all will receive this broadcast.
14526        List receivers = null;
14527        List<BroadcastFilter> registeredReceivers = null;
14528        // Need to resolve the intent to interested receivers...
14529        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14530                 == 0) {
14531            receivers = collectReceiverComponents(intent, resolvedType, users);
14532        }
14533        if (intent.getComponent() == null) {
14534            registeredReceivers = mReceiverResolver.queryIntent(intent,
14535                    resolvedType, false, userId);
14536        }
14537
14538        final boolean replacePending =
14539                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14540
14541        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14542                + " replacePending=" + replacePending);
14543
14544        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14545        if (!ordered && NR > 0) {
14546            // If we are not serializing this broadcast, then send the
14547            // registered receivers separately so they don't wait for the
14548            // components to be launched.
14549            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14550            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14551                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14552                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14553                    ordered, sticky, false, userId);
14554            if (DEBUG_BROADCAST) Slog.v(
14555                    TAG, "Enqueueing parallel broadcast " + r);
14556            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14557            if (!replaced) {
14558                queue.enqueueParallelBroadcastLocked(r);
14559                queue.scheduleBroadcastsLocked();
14560            }
14561            registeredReceivers = null;
14562            NR = 0;
14563        }
14564
14565        // Merge into one list.
14566        int ir = 0;
14567        if (receivers != null) {
14568            // A special case for PACKAGE_ADDED: do not allow the package
14569            // being added to see this broadcast.  This prevents them from
14570            // using this as a back door to get run as soon as they are
14571            // installed.  Maybe in the future we want to have a special install
14572            // broadcast or such for apps, but we'd like to deliberately make
14573            // this decision.
14574            String skipPackages[] = null;
14575            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14576                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14577                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14578                Uri data = intent.getData();
14579                if (data != null) {
14580                    String pkgName = data.getSchemeSpecificPart();
14581                    if (pkgName != null) {
14582                        skipPackages = new String[] { pkgName };
14583                    }
14584                }
14585            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14586                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14587            }
14588            if (skipPackages != null && (skipPackages.length > 0)) {
14589                for (String skipPackage : skipPackages) {
14590                    if (skipPackage != null) {
14591                        int NT = receivers.size();
14592                        for (int it=0; it<NT; it++) {
14593                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14594                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14595                                receivers.remove(it);
14596                                it--;
14597                                NT--;
14598                            }
14599                        }
14600                    }
14601                }
14602            }
14603
14604            int NT = receivers != null ? receivers.size() : 0;
14605            int it = 0;
14606            ResolveInfo curt = null;
14607            BroadcastFilter curr = null;
14608            while (it < NT && ir < NR) {
14609                if (curt == null) {
14610                    curt = (ResolveInfo)receivers.get(it);
14611                }
14612                if (curr == null) {
14613                    curr = registeredReceivers.get(ir);
14614                }
14615                if (curr.getPriority() >= curt.priority) {
14616                    // Insert this broadcast record into the final list.
14617                    receivers.add(it, curr);
14618                    ir++;
14619                    curr = null;
14620                    it++;
14621                    NT++;
14622                } else {
14623                    // Skip to the next ResolveInfo in the final list.
14624                    it++;
14625                    curt = null;
14626                }
14627            }
14628        }
14629        while (ir < NR) {
14630            if (receivers == null) {
14631                receivers = new ArrayList();
14632            }
14633            receivers.add(registeredReceivers.get(ir));
14634            ir++;
14635        }
14636
14637        if ((receivers != null && receivers.size() > 0)
14638                || resultTo != null) {
14639            BroadcastQueue queue = broadcastQueueForIntent(intent);
14640            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14641                    callerPackage, callingPid, callingUid, resolvedType,
14642                    requiredPermission, appOp, receivers, resultTo, resultCode,
14643                    resultData, map, ordered, sticky, false, userId);
14644            if (DEBUG_BROADCAST) Slog.v(
14645                    TAG, "Enqueueing ordered broadcast " + r
14646                    + ": prev had " + queue.mOrderedBroadcasts.size());
14647            if (DEBUG_BROADCAST) {
14648                int seq = r.intent.getIntExtra("seq", -1);
14649                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14650            }
14651            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14652            if (!replaced) {
14653                queue.enqueueOrderedBroadcastLocked(r);
14654                queue.scheduleBroadcastsLocked();
14655            }
14656        }
14657
14658        return ActivityManager.BROADCAST_SUCCESS;
14659    }
14660
14661    final Intent verifyBroadcastLocked(Intent intent) {
14662        // Refuse possible leaked file descriptors
14663        if (intent != null && intent.hasFileDescriptors() == true) {
14664            throw new IllegalArgumentException("File descriptors passed in Intent");
14665        }
14666
14667        int flags = intent.getFlags();
14668
14669        if (!mProcessesReady) {
14670            // if the caller really truly claims to know what they're doing, go
14671            // ahead and allow the broadcast without launching any receivers
14672            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14673                intent = new Intent(intent);
14674                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14675            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14676                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14677                        + " before boot completion");
14678                throw new IllegalStateException("Cannot broadcast before boot completed");
14679            }
14680        }
14681
14682        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14683            throw new IllegalArgumentException(
14684                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14685        }
14686
14687        return intent;
14688    }
14689
14690    public final int broadcastIntent(IApplicationThread caller,
14691            Intent intent, String resolvedType, IIntentReceiver resultTo,
14692            int resultCode, String resultData, Bundle map,
14693            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14694        enforceNotIsolatedCaller("broadcastIntent");
14695        synchronized(this) {
14696            intent = verifyBroadcastLocked(intent);
14697
14698            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14699            final int callingPid = Binder.getCallingPid();
14700            final int callingUid = Binder.getCallingUid();
14701            final long origId = Binder.clearCallingIdentity();
14702            int res = broadcastIntentLocked(callerApp,
14703                    callerApp != null ? callerApp.info.packageName : null,
14704                    intent, resolvedType, resultTo,
14705                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14706                    callingPid, callingUid, userId);
14707            Binder.restoreCallingIdentity(origId);
14708            return res;
14709        }
14710    }
14711
14712    int broadcastIntentInPackage(String packageName, int uid,
14713            Intent intent, String resolvedType, IIntentReceiver resultTo,
14714            int resultCode, String resultData, Bundle map,
14715            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14716        synchronized(this) {
14717            intent = verifyBroadcastLocked(intent);
14718
14719            final long origId = Binder.clearCallingIdentity();
14720            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14721                    resultTo, resultCode, resultData, map, requiredPermission,
14722                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14723            Binder.restoreCallingIdentity(origId);
14724            return res;
14725        }
14726    }
14727
14728    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14729        // Refuse possible leaked file descriptors
14730        if (intent != null && intent.hasFileDescriptors() == true) {
14731            throw new IllegalArgumentException("File descriptors passed in Intent");
14732        }
14733
14734        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14735                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14736
14737        synchronized(this) {
14738            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14739                    != PackageManager.PERMISSION_GRANTED) {
14740                String msg = "Permission Denial: unbroadcastIntent() from pid="
14741                        + Binder.getCallingPid()
14742                        + ", uid=" + Binder.getCallingUid()
14743                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14744                Slog.w(TAG, msg);
14745                throw new SecurityException(msg);
14746            }
14747            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14748            if (stickies != null) {
14749                ArrayList<Intent> list = stickies.get(intent.getAction());
14750                if (list != null) {
14751                    int N = list.size();
14752                    int i;
14753                    for (i=0; i<N; i++) {
14754                        if (intent.filterEquals(list.get(i))) {
14755                            list.remove(i);
14756                            break;
14757                        }
14758                    }
14759                    if (list.size() <= 0) {
14760                        stickies.remove(intent.getAction());
14761                    }
14762                }
14763                if (stickies.size() <= 0) {
14764                    mStickyBroadcasts.remove(userId);
14765                }
14766            }
14767        }
14768    }
14769
14770    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14771            String resultData, Bundle resultExtras, boolean resultAbort) {
14772        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14773        if (r == null) {
14774            Slog.w(TAG, "finishReceiver called but not found on queue");
14775            return false;
14776        }
14777
14778        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14779    }
14780
14781    void backgroundServicesFinishedLocked(int userId) {
14782        for (BroadcastQueue queue : mBroadcastQueues) {
14783            queue.backgroundServicesFinishedLocked(userId);
14784        }
14785    }
14786
14787    public void finishReceiver(IBinder who, int resultCode, String resultData,
14788            Bundle resultExtras, boolean resultAbort) {
14789        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14790
14791        // Refuse possible leaked file descriptors
14792        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14793            throw new IllegalArgumentException("File descriptors passed in Bundle");
14794        }
14795
14796        final long origId = Binder.clearCallingIdentity();
14797        try {
14798            boolean doNext = false;
14799            BroadcastRecord r;
14800
14801            synchronized(this) {
14802                r = broadcastRecordForReceiverLocked(who);
14803                if (r != null) {
14804                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14805                        resultData, resultExtras, resultAbort, true);
14806                }
14807            }
14808
14809            if (doNext) {
14810                r.queue.processNextBroadcast(false);
14811            }
14812            trimApplications();
14813        } finally {
14814            Binder.restoreCallingIdentity(origId);
14815        }
14816    }
14817
14818    // =========================================================
14819    // INSTRUMENTATION
14820    // =========================================================
14821
14822    public boolean startInstrumentation(ComponentName className,
14823            String profileFile, int flags, Bundle arguments,
14824            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14825            int userId, String abiOverride) {
14826        enforceNotIsolatedCaller("startInstrumentation");
14827        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14828                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14829        // Refuse possible leaked file descriptors
14830        if (arguments != null && arguments.hasFileDescriptors()) {
14831            throw new IllegalArgumentException("File descriptors passed in Bundle");
14832        }
14833
14834        synchronized(this) {
14835            InstrumentationInfo ii = null;
14836            ApplicationInfo ai = null;
14837            try {
14838                ii = mContext.getPackageManager().getInstrumentationInfo(
14839                    className, STOCK_PM_FLAGS);
14840                ai = AppGlobals.getPackageManager().getApplicationInfo(
14841                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14842            } catch (PackageManager.NameNotFoundException e) {
14843            } catch (RemoteException e) {
14844            }
14845            if (ii == null) {
14846                reportStartInstrumentationFailure(watcher, className,
14847                        "Unable to find instrumentation info for: " + className);
14848                return false;
14849            }
14850            if (ai == null) {
14851                reportStartInstrumentationFailure(watcher, className,
14852                        "Unable to find instrumentation target package: " + ii.targetPackage);
14853                return false;
14854            }
14855
14856            int match = mContext.getPackageManager().checkSignatures(
14857                    ii.targetPackage, ii.packageName);
14858            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14859                String msg = "Permission Denial: starting instrumentation "
14860                        + className + " from pid="
14861                        + Binder.getCallingPid()
14862                        + ", uid=" + Binder.getCallingPid()
14863                        + " not allowed because package " + ii.packageName
14864                        + " does not have a signature matching the target "
14865                        + ii.targetPackage;
14866                reportStartInstrumentationFailure(watcher, className, msg);
14867                throw new SecurityException(msg);
14868            }
14869
14870            final long origId = Binder.clearCallingIdentity();
14871            // Instrumentation can kill and relaunch even persistent processes
14872            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14873                    "start instr");
14874            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14875            app.instrumentationClass = className;
14876            app.instrumentationInfo = ai;
14877            app.instrumentationProfileFile = profileFile;
14878            app.instrumentationArguments = arguments;
14879            app.instrumentationWatcher = watcher;
14880            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14881            app.instrumentationResultClass = className;
14882            Binder.restoreCallingIdentity(origId);
14883        }
14884
14885        return true;
14886    }
14887
14888    /**
14889     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14890     * error to the logs, but if somebody is watching, send the report there too.  This enables
14891     * the "am" command to report errors with more information.
14892     *
14893     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14894     * @param cn The component name of the instrumentation.
14895     * @param report The error report.
14896     */
14897    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14898            ComponentName cn, String report) {
14899        Slog.w(TAG, report);
14900        try {
14901            if (watcher != null) {
14902                Bundle results = new Bundle();
14903                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14904                results.putString("Error", report);
14905                watcher.instrumentationStatus(cn, -1, results);
14906            }
14907        } catch (RemoteException e) {
14908            Slog.w(TAG, e);
14909        }
14910    }
14911
14912    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14913        if (app.instrumentationWatcher != null) {
14914            try {
14915                // NOTE:  IInstrumentationWatcher *must* be oneway here
14916                app.instrumentationWatcher.instrumentationFinished(
14917                    app.instrumentationClass,
14918                    resultCode,
14919                    results);
14920            } catch (RemoteException e) {
14921            }
14922        }
14923        if (app.instrumentationUiAutomationConnection != null) {
14924            try {
14925                app.instrumentationUiAutomationConnection.shutdown();
14926            } catch (RemoteException re) {
14927                /* ignore */
14928            }
14929            // Only a UiAutomation can set this flag and now that
14930            // it is finished we make sure it is reset to its default.
14931            mUserIsMonkey = false;
14932        }
14933        app.instrumentationWatcher = null;
14934        app.instrumentationUiAutomationConnection = null;
14935        app.instrumentationClass = null;
14936        app.instrumentationInfo = null;
14937        app.instrumentationProfileFile = null;
14938        app.instrumentationArguments = null;
14939
14940        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14941                "finished inst");
14942    }
14943
14944    public void finishInstrumentation(IApplicationThread target,
14945            int resultCode, Bundle results) {
14946        int userId = UserHandle.getCallingUserId();
14947        // Refuse possible leaked file descriptors
14948        if (results != null && results.hasFileDescriptors()) {
14949            throw new IllegalArgumentException("File descriptors passed in Intent");
14950        }
14951
14952        synchronized(this) {
14953            ProcessRecord app = getRecordForAppLocked(target);
14954            if (app == null) {
14955                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14956                return;
14957            }
14958            final long origId = Binder.clearCallingIdentity();
14959            finishInstrumentationLocked(app, resultCode, results);
14960            Binder.restoreCallingIdentity(origId);
14961        }
14962    }
14963
14964    // =========================================================
14965    // CONFIGURATION
14966    // =========================================================
14967
14968    public ConfigurationInfo getDeviceConfigurationInfo() {
14969        ConfigurationInfo config = new ConfigurationInfo();
14970        synchronized (this) {
14971            config.reqTouchScreen = mConfiguration.touchscreen;
14972            config.reqKeyboardType = mConfiguration.keyboard;
14973            config.reqNavigation = mConfiguration.navigation;
14974            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14975                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14976                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14977            }
14978            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14979                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14980                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14981            }
14982            config.reqGlEsVersion = GL_ES_VERSION;
14983        }
14984        return config;
14985    }
14986
14987    ActivityStack getFocusedStack() {
14988        return mStackSupervisor.getFocusedStack();
14989    }
14990
14991    public Configuration getConfiguration() {
14992        Configuration ci;
14993        synchronized(this) {
14994            ci = new Configuration(mConfiguration);
14995        }
14996        return ci;
14997    }
14998
14999    public void updatePersistentConfiguration(Configuration values) {
15000        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15001                "updateConfiguration()");
15002        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15003                "updateConfiguration()");
15004        if (values == null) {
15005            throw new NullPointerException("Configuration must not be null");
15006        }
15007
15008        synchronized(this) {
15009            final long origId = Binder.clearCallingIdentity();
15010            updateConfigurationLocked(values, null, true, false);
15011            Binder.restoreCallingIdentity(origId);
15012        }
15013    }
15014
15015    public void updateConfiguration(Configuration values) {
15016        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15017                "updateConfiguration()");
15018
15019        synchronized(this) {
15020            if (values == null && mWindowManager != null) {
15021                // sentinel: fetch the current configuration from the window manager
15022                values = mWindowManager.computeNewConfiguration();
15023            }
15024
15025            if (mWindowManager != null) {
15026                mProcessList.applyDisplaySize(mWindowManager);
15027            }
15028
15029            final long origId = Binder.clearCallingIdentity();
15030            if (values != null) {
15031                Settings.System.clearConfiguration(values);
15032            }
15033            updateConfigurationLocked(values, null, false, false);
15034            Binder.restoreCallingIdentity(origId);
15035        }
15036    }
15037
15038    /**
15039     * Do either or both things: (1) change the current configuration, and (2)
15040     * make sure the given activity is running with the (now) current
15041     * configuration.  Returns true if the activity has been left running, or
15042     * false if <var>starting</var> is being destroyed to match the new
15043     * configuration.
15044     * @param persistent TODO
15045     */
15046    boolean updateConfigurationLocked(Configuration values,
15047            ActivityRecord starting, boolean persistent, boolean initLocale) {
15048        int changes = 0;
15049
15050        if (values != null) {
15051            Configuration newConfig = new Configuration(mConfiguration);
15052            changes = newConfig.updateFrom(values);
15053            if (changes != 0) {
15054                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15055                    Slog.i(TAG, "Updating configuration to: " + values);
15056                }
15057
15058                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15059
15060                if (values.locale != null && !initLocale) {
15061                    saveLocaleLocked(values.locale,
15062                                     !values.locale.equals(mConfiguration.locale),
15063                                     values.userSetLocale);
15064                }
15065
15066                mConfigurationSeq++;
15067                if (mConfigurationSeq <= 0) {
15068                    mConfigurationSeq = 1;
15069                }
15070                newConfig.seq = mConfigurationSeq;
15071                mConfiguration = newConfig;
15072                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15073                //mUsageStatsService.noteStartConfig(newConfig);
15074
15075                final Configuration configCopy = new Configuration(mConfiguration);
15076
15077                // TODO: If our config changes, should we auto dismiss any currently
15078                // showing dialogs?
15079                mShowDialogs = shouldShowDialogs(newConfig);
15080
15081                AttributeCache ac = AttributeCache.instance();
15082                if (ac != null) {
15083                    ac.updateConfiguration(configCopy);
15084                }
15085
15086                // Make sure all resources in our process are updated
15087                // right now, so that anyone who is going to retrieve
15088                // resource values after we return will be sure to get
15089                // the new ones.  This is especially important during
15090                // boot, where the first config change needs to guarantee
15091                // all resources have that config before following boot
15092                // code is executed.
15093                mSystemThread.applyConfigurationToResources(configCopy);
15094
15095                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15096                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15097                    msg.obj = new Configuration(configCopy);
15098                    mHandler.sendMessage(msg);
15099                }
15100
15101                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15102                    ProcessRecord app = mLruProcesses.get(i);
15103                    try {
15104                        if (app.thread != null) {
15105                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15106                                    + app.processName + " new config " + mConfiguration);
15107                            app.thread.scheduleConfigurationChanged(configCopy);
15108                        }
15109                    } catch (Exception e) {
15110                    }
15111                }
15112                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15113                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15114                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15115                        | Intent.FLAG_RECEIVER_FOREGROUND);
15116                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15117                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15118                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15119                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15120                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15121                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15122                    broadcastIntentLocked(null, null, intent,
15123                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15124                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15125                }
15126            }
15127        }
15128
15129        boolean kept = true;
15130        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15131        // mainStack is null during startup.
15132        if (mainStack != null) {
15133            if (changes != 0 && starting == null) {
15134                // If the configuration changed, and the caller is not already
15135                // in the process of starting an activity, then find the top
15136                // activity to check if its configuration needs to change.
15137                starting = mainStack.topRunningActivityLocked(null);
15138            }
15139
15140            if (starting != null) {
15141                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15142                // And we need to make sure at this point that all other activities
15143                // are made visible with the correct configuration.
15144                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15145            }
15146        }
15147
15148        if (values != null && mWindowManager != null) {
15149            mWindowManager.setNewConfiguration(mConfiguration);
15150        }
15151
15152        return kept;
15153    }
15154
15155    /**
15156     * Decide based on the configuration whether we should shouw the ANR,
15157     * crash, etc dialogs.  The idea is that if there is no affordnace to
15158     * press the on-screen buttons, we shouldn't show the dialog.
15159     *
15160     * A thought: SystemUI might also want to get told about this, the Power
15161     * dialog / global actions also might want different behaviors.
15162     */
15163    private static final boolean shouldShowDialogs(Configuration config) {
15164        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15165                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15166    }
15167
15168    /**
15169     * Save the locale.  You must be inside a synchronized (this) block.
15170     */
15171    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15172        if(isDiff) {
15173            SystemProperties.set("user.language", l.getLanguage());
15174            SystemProperties.set("user.region", l.getCountry());
15175        }
15176
15177        if(isPersist) {
15178            SystemProperties.set("persist.sys.language", l.getLanguage());
15179            SystemProperties.set("persist.sys.country", l.getCountry());
15180            SystemProperties.set("persist.sys.localevar", l.getVariant());
15181        }
15182    }
15183
15184    @Override
15185    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15186        ActivityRecord srec = ActivityRecord.forToken(token);
15187        return srec != null && srec.task.affinity != null &&
15188                srec.task.affinity.equals(destAffinity);
15189    }
15190
15191    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15192            Intent resultData) {
15193
15194        synchronized (this) {
15195            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15196            if (stack != null) {
15197                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15198            }
15199            return false;
15200        }
15201    }
15202
15203    public int getLaunchedFromUid(IBinder activityToken) {
15204        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15205        if (srec == null) {
15206            return -1;
15207        }
15208        return srec.launchedFromUid;
15209    }
15210
15211    public String getLaunchedFromPackage(IBinder activityToken) {
15212        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15213        if (srec == null) {
15214            return null;
15215        }
15216        return srec.launchedFromPackage;
15217    }
15218
15219    // =========================================================
15220    // LIFETIME MANAGEMENT
15221    // =========================================================
15222
15223    // Returns which broadcast queue the app is the current [or imminent] receiver
15224    // on, or 'null' if the app is not an active broadcast recipient.
15225    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15226        BroadcastRecord r = app.curReceiver;
15227        if (r != null) {
15228            return r.queue;
15229        }
15230
15231        // It's not the current receiver, but it might be starting up to become one
15232        synchronized (this) {
15233            for (BroadcastQueue queue : mBroadcastQueues) {
15234                r = queue.mPendingBroadcast;
15235                if (r != null && r.curApp == app) {
15236                    // found it; report which queue it's in
15237                    return queue;
15238                }
15239            }
15240        }
15241
15242        return null;
15243    }
15244
15245    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15246            boolean doingAll, long now) {
15247        if (mAdjSeq == app.adjSeq) {
15248            // This adjustment has already been computed.
15249            return app.curRawAdj;
15250        }
15251
15252        if (app.thread == null) {
15253            app.adjSeq = mAdjSeq;
15254            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15255            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15256            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15257        }
15258
15259        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15260        app.adjSource = null;
15261        app.adjTarget = null;
15262        app.empty = false;
15263        app.cached = false;
15264
15265        final int activitiesSize = app.activities.size();
15266
15267        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15268            // The max adjustment doesn't allow this app to be anything
15269            // below foreground, so it is not worth doing work for it.
15270            app.adjType = "fixed";
15271            app.adjSeq = mAdjSeq;
15272            app.curRawAdj = app.maxAdj;
15273            app.foregroundActivities = false;
15274            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15275            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15276            // System processes can do UI, and when they do we want to have
15277            // them trim their memory after the user leaves the UI.  To
15278            // facilitate this, here we need to determine whether or not it
15279            // is currently showing UI.
15280            app.systemNoUi = true;
15281            if (app == TOP_APP) {
15282                app.systemNoUi = false;
15283            } else if (activitiesSize > 0) {
15284                for (int j = 0; j < activitiesSize; j++) {
15285                    final ActivityRecord r = app.activities.get(j);
15286                    if (r.visible) {
15287                        app.systemNoUi = false;
15288                    }
15289                }
15290            }
15291            if (!app.systemNoUi) {
15292                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15293            }
15294            return (app.curAdj=app.maxAdj);
15295        }
15296
15297        app.systemNoUi = false;
15298
15299        // Determine the importance of the process, starting with most
15300        // important to least, and assign an appropriate OOM adjustment.
15301        int adj;
15302        int schedGroup;
15303        int procState;
15304        boolean foregroundActivities = false;
15305        BroadcastQueue queue;
15306        if (app == TOP_APP) {
15307            // The last app on the list is the foreground app.
15308            adj = ProcessList.FOREGROUND_APP_ADJ;
15309            schedGroup = Process.THREAD_GROUP_DEFAULT;
15310            app.adjType = "top-activity";
15311            foregroundActivities = true;
15312            procState = ActivityManager.PROCESS_STATE_TOP;
15313        } else if (app.instrumentationClass != null) {
15314            // Don't want to kill running instrumentation.
15315            adj = ProcessList.FOREGROUND_APP_ADJ;
15316            schedGroup = Process.THREAD_GROUP_DEFAULT;
15317            app.adjType = "instrumentation";
15318            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15319        } else if ((queue = isReceivingBroadcast(app)) != null) {
15320            // An app that is currently receiving a broadcast also
15321            // counts as being in the foreground for OOM killer purposes.
15322            // It's placed in a sched group based on the nature of the
15323            // broadcast as reflected by which queue it's active in.
15324            adj = ProcessList.FOREGROUND_APP_ADJ;
15325            schedGroup = (queue == mFgBroadcastQueue)
15326                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15327            app.adjType = "broadcast";
15328            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15329        } else if (app.executingServices.size() > 0) {
15330            // An app that is currently executing a service callback also
15331            // counts as being in the foreground.
15332            adj = ProcessList.FOREGROUND_APP_ADJ;
15333            schedGroup = app.execServicesFg ?
15334                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15335            app.adjType = "exec-service";
15336            procState = ActivityManager.PROCESS_STATE_SERVICE;
15337            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15338        } else {
15339            // As far as we know the process is empty.  We may change our mind later.
15340            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15341            // At this point we don't actually know the adjustment.  Use the cached adj
15342            // value that the caller wants us to.
15343            adj = cachedAdj;
15344            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15345            app.cached = true;
15346            app.empty = true;
15347            app.adjType = "cch-empty";
15348        }
15349
15350        // Examine all activities if not already foreground.
15351        if (!foregroundActivities && activitiesSize > 0) {
15352            for (int j = 0; j < activitiesSize; j++) {
15353                final ActivityRecord r = app.activities.get(j);
15354                if (r.app != app) {
15355                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15356                            + app + "?!?");
15357                    continue;
15358                }
15359                if (r.visible) {
15360                    // App has a visible activity; only upgrade adjustment.
15361                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15362                        adj = ProcessList.VISIBLE_APP_ADJ;
15363                        app.adjType = "visible";
15364                    }
15365                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15366                        procState = ActivityManager.PROCESS_STATE_TOP;
15367                    }
15368                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15369                    app.cached = false;
15370                    app.empty = false;
15371                    foregroundActivities = true;
15372                    break;
15373                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15374                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15375                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15376                        app.adjType = "pausing";
15377                    }
15378                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15379                        procState = ActivityManager.PROCESS_STATE_TOP;
15380                    }
15381                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15382                    app.cached = false;
15383                    app.empty = false;
15384                    foregroundActivities = true;
15385                } else if (r.state == ActivityState.STOPPING) {
15386                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15387                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15388                        app.adjType = "stopping";
15389                    }
15390                    // For the process state, we will at this point consider the
15391                    // process to be cached.  It will be cached either as an activity
15392                    // or empty depending on whether the activity is finishing.  We do
15393                    // this so that we can treat the process as cached for purposes of
15394                    // memory trimming (determing current memory level, trim command to
15395                    // send to process) since there can be an arbitrary number of stopping
15396                    // processes and they should soon all go into the cached state.
15397                    if (!r.finishing) {
15398                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15399                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15400                        }
15401                    }
15402                    app.cached = false;
15403                    app.empty = false;
15404                    foregroundActivities = true;
15405                } else {
15406                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15407                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15408                        app.adjType = "cch-act";
15409                    }
15410                }
15411            }
15412        }
15413
15414        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15415            if (app.foregroundServices) {
15416                // The user is aware of this app, so make it visible.
15417                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15418                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15419                app.cached = false;
15420                app.adjType = "fg-service";
15421                schedGroup = Process.THREAD_GROUP_DEFAULT;
15422            } else if (app.forcingToForeground != null) {
15423                // The user is aware of this app, so make it visible.
15424                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15425                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15426                app.cached = false;
15427                app.adjType = "force-fg";
15428                app.adjSource = app.forcingToForeground;
15429                schedGroup = Process.THREAD_GROUP_DEFAULT;
15430            }
15431        }
15432
15433        if (app == mHeavyWeightProcess) {
15434            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15435                // We don't want to kill the current heavy-weight process.
15436                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15437                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15438                app.cached = false;
15439                app.adjType = "heavy";
15440            }
15441            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15442                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15443            }
15444        }
15445
15446        if (app == mHomeProcess) {
15447            if (adj > ProcessList.HOME_APP_ADJ) {
15448                // This process is hosting what we currently consider to be the
15449                // home app, so we don't want to let it go into the background.
15450                adj = ProcessList.HOME_APP_ADJ;
15451                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15452                app.cached = false;
15453                app.adjType = "home";
15454            }
15455            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15456                procState = ActivityManager.PROCESS_STATE_HOME;
15457            }
15458        }
15459
15460        if (app == mPreviousProcess && app.activities.size() > 0) {
15461            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15462                // This was the previous process that showed UI to the user.
15463                // We want to try to keep it around more aggressively, to give
15464                // a good experience around switching between two apps.
15465                adj = ProcessList.PREVIOUS_APP_ADJ;
15466                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15467                app.cached = false;
15468                app.adjType = "previous";
15469            }
15470            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15471                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15472            }
15473        }
15474
15475        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15476                + " reason=" + app.adjType);
15477
15478        // By default, we use the computed adjustment.  It may be changed if
15479        // there are applications dependent on our services or providers, but
15480        // this gives us a baseline and makes sure we don't get into an
15481        // infinite recursion.
15482        app.adjSeq = mAdjSeq;
15483        app.curRawAdj = adj;
15484        app.hasStartedServices = false;
15485
15486        if (mBackupTarget != null && app == mBackupTarget.app) {
15487            // If possible we want to avoid killing apps while they're being backed up
15488            if (adj > ProcessList.BACKUP_APP_ADJ) {
15489                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15490                adj = ProcessList.BACKUP_APP_ADJ;
15491                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15492                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15493                }
15494                app.adjType = "backup";
15495                app.cached = false;
15496            }
15497            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15498                procState = ActivityManager.PROCESS_STATE_BACKUP;
15499            }
15500        }
15501
15502        boolean mayBeTop = false;
15503
15504        for (int is = app.services.size()-1;
15505                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15506                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15507                        || procState > ActivityManager.PROCESS_STATE_TOP);
15508                is--) {
15509            ServiceRecord s = app.services.valueAt(is);
15510            if (s.startRequested) {
15511                app.hasStartedServices = true;
15512                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15513                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15514                }
15515                if (app.hasShownUi && app != mHomeProcess) {
15516                    // If this process has shown some UI, let it immediately
15517                    // go to the LRU list because it may be pretty heavy with
15518                    // UI stuff.  We'll tag it with a label just to help
15519                    // debug and understand what is going on.
15520                    if (adj > ProcessList.SERVICE_ADJ) {
15521                        app.adjType = "cch-started-ui-services";
15522                    }
15523                } else {
15524                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15525                        // This service has seen some activity within
15526                        // recent memory, so we will keep its process ahead
15527                        // of the background processes.
15528                        if (adj > ProcessList.SERVICE_ADJ) {
15529                            adj = ProcessList.SERVICE_ADJ;
15530                            app.adjType = "started-services";
15531                            app.cached = false;
15532                        }
15533                    }
15534                    // If we have let the service slide into the background
15535                    // state, still have some text describing what it is doing
15536                    // even though the service no longer has an impact.
15537                    if (adj > ProcessList.SERVICE_ADJ) {
15538                        app.adjType = "cch-started-services";
15539                    }
15540                }
15541            }
15542            for (int conni = s.connections.size()-1;
15543                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15544                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15545                            || procState > ActivityManager.PROCESS_STATE_TOP);
15546                    conni--) {
15547                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15548                for (int i = 0;
15549                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15550                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15551                                || procState > ActivityManager.PROCESS_STATE_TOP);
15552                        i++) {
15553                    // XXX should compute this based on the max of
15554                    // all connected clients.
15555                    ConnectionRecord cr = clist.get(i);
15556                    if (cr.binding.client == app) {
15557                        // Binding to ourself is not interesting.
15558                        continue;
15559                    }
15560                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15561                        ProcessRecord client = cr.binding.client;
15562                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15563                                TOP_APP, doingAll, now);
15564                        int clientProcState = client.curProcState;
15565                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15566                            // If the other app is cached for any reason, for purposes here
15567                            // we are going to consider it empty.  The specific cached state
15568                            // doesn't propagate except under certain conditions.
15569                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15570                        }
15571                        String adjType = null;
15572                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15573                            // Not doing bind OOM management, so treat
15574                            // this guy more like a started service.
15575                            if (app.hasShownUi && app != mHomeProcess) {
15576                                // If this process has shown some UI, let it immediately
15577                                // go to the LRU list because it may be pretty heavy with
15578                                // UI stuff.  We'll tag it with a label just to help
15579                                // debug and understand what is going on.
15580                                if (adj > clientAdj) {
15581                                    adjType = "cch-bound-ui-services";
15582                                }
15583                                app.cached = false;
15584                                clientAdj = adj;
15585                                clientProcState = procState;
15586                            } else {
15587                                if (now >= (s.lastActivity
15588                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15589                                    // This service has not seen activity within
15590                                    // recent memory, so allow it to drop to the
15591                                    // LRU list if there is no other reason to keep
15592                                    // it around.  We'll also tag it with a label just
15593                                    // to help debug and undertand what is going on.
15594                                    if (adj > clientAdj) {
15595                                        adjType = "cch-bound-services";
15596                                    }
15597                                    clientAdj = adj;
15598                                }
15599                            }
15600                        }
15601                        if (adj > clientAdj) {
15602                            // If this process has recently shown UI, and
15603                            // the process that is binding to it is less
15604                            // important than being visible, then we don't
15605                            // care about the binding as much as we care
15606                            // about letting this process get into the LRU
15607                            // list to be killed and restarted if needed for
15608                            // memory.
15609                            if (app.hasShownUi && app != mHomeProcess
15610                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15611                                adjType = "cch-bound-ui-services";
15612                            } else {
15613                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15614                                        |Context.BIND_IMPORTANT)) != 0) {
15615                                    adj = clientAdj;
15616                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15617                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15618                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15619                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15620                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15621                                    adj = clientAdj;
15622                                } else {
15623                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15624                                        adj = ProcessList.VISIBLE_APP_ADJ;
15625                                    }
15626                                }
15627                                if (!client.cached) {
15628                                    app.cached = false;
15629                                }
15630                                adjType = "service";
15631                            }
15632                        }
15633                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15634                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15635                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15636                            }
15637                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15638                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15639                                    // Special handling of clients who are in the top state.
15640                                    // We *may* want to consider this process to be in the
15641                                    // top state as well, but only if there is not another
15642                                    // reason for it to be running.  Being on the top is a
15643                                    // special state, meaning you are specifically running
15644                                    // for the current top app.  If the process is already
15645                                    // running in the background for some other reason, it
15646                                    // is more important to continue considering it to be
15647                                    // in the background state.
15648                                    mayBeTop = true;
15649                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15650                                } else {
15651                                    // Special handling for above-top states (persistent
15652                                    // processes).  These should not bring the current process
15653                                    // into the top state, since they are not on top.  Instead
15654                                    // give them the best state after that.
15655                                    clientProcState =
15656                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15657                                }
15658                            }
15659                        } else {
15660                            if (clientProcState <
15661                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15662                                clientProcState =
15663                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15664                            }
15665                        }
15666                        if (procState > clientProcState) {
15667                            procState = clientProcState;
15668                        }
15669                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15670                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15671                            app.pendingUiClean = true;
15672                        }
15673                        if (adjType != null) {
15674                            app.adjType = adjType;
15675                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15676                                    .REASON_SERVICE_IN_USE;
15677                            app.adjSource = cr.binding.client;
15678                            app.adjSourceProcState = clientProcState;
15679                            app.adjTarget = s.name;
15680                        }
15681                    }
15682                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15683                        app.treatLikeActivity = true;
15684                    }
15685                    final ActivityRecord a = cr.activity;
15686                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15687                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15688                                (a.visible || a.state == ActivityState.RESUMED
15689                                 || a.state == ActivityState.PAUSING)) {
15690                            adj = ProcessList.FOREGROUND_APP_ADJ;
15691                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15692                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15693                            }
15694                            app.cached = false;
15695                            app.adjType = "service";
15696                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15697                                    .REASON_SERVICE_IN_USE;
15698                            app.adjSource = a;
15699                            app.adjSourceProcState = procState;
15700                            app.adjTarget = s.name;
15701                        }
15702                    }
15703                }
15704            }
15705        }
15706
15707        for (int provi = app.pubProviders.size()-1;
15708                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15709                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15710                        || procState > ActivityManager.PROCESS_STATE_TOP);
15711                provi--) {
15712            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15713            for (int i = cpr.connections.size()-1;
15714                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15715                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15716                            || procState > ActivityManager.PROCESS_STATE_TOP);
15717                    i--) {
15718                ContentProviderConnection conn = cpr.connections.get(i);
15719                ProcessRecord client = conn.client;
15720                if (client == app) {
15721                    // Being our own client is not interesting.
15722                    continue;
15723                }
15724                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15725                int clientProcState = client.curProcState;
15726                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15727                    // If the other app is cached for any reason, for purposes here
15728                    // we are going to consider it empty.
15729                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15730                }
15731                if (adj > clientAdj) {
15732                    if (app.hasShownUi && app != mHomeProcess
15733                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15734                        app.adjType = "cch-ui-provider";
15735                    } else {
15736                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15737                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15738                        app.adjType = "provider";
15739                    }
15740                    app.cached &= client.cached;
15741                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15742                            .REASON_PROVIDER_IN_USE;
15743                    app.adjSource = client;
15744                    app.adjSourceProcState = clientProcState;
15745                    app.adjTarget = cpr.name;
15746                }
15747                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15748                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15749                        // Special handling of clients who are in the top state.
15750                        // We *may* want to consider this process to be in the
15751                        // top state as well, but only if there is not another
15752                        // reason for it to be running.  Being on the top is a
15753                        // special state, meaning you are specifically running
15754                        // for the current top app.  If the process is already
15755                        // running in the background for some other reason, it
15756                        // is more important to continue considering it to be
15757                        // in the background state.
15758                        mayBeTop = true;
15759                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15760                    } else {
15761                        // Special handling for above-top states (persistent
15762                        // processes).  These should not bring the current process
15763                        // into the top state, since they are not on top.  Instead
15764                        // give them the best state after that.
15765                        clientProcState =
15766                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15767                    }
15768                }
15769                if (procState > clientProcState) {
15770                    procState = clientProcState;
15771                }
15772                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15773                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15774                }
15775            }
15776            // If the provider has external (non-framework) process
15777            // dependencies, ensure that its adjustment is at least
15778            // FOREGROUND_APP_ADJ.
15779            if (cpr.hasExternalProcessHandles()) {
15780                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15781                    adj = ProcessList.FOREGROUND_APP_ADJ;
15782                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15783                    app.cached = false;
15784                    app.adjType = "provider";
15785                    app.adjTarget = cpr.name;
15786                }
15787                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15788                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15789                }
15790            }
15791        }
15792
15793        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15794            // A client of one of our services or providers is in the top state.  We
15795            // *may* want to be in the top state, but not if we are already running in
15796            // the background for some other reason.  For the decision here, we are going
15797            // to pick out a few specific states that we want to remain in when a client
15798            // is top (states that tend to be longer-term) and otherwise allow it to go
15799            // to the top state.
15800            switch (procState) {
15801                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15802                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15803                case ActivityManager.PROCESS_STATE_SERVICE:
15804                    // These all are longer-term states, so pull them up to the top
15805                    // of the background states, but not all the way to the top state.
15806                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15807                    break;
15808                default:
15809                    // Otherwise, top is a better choice, so take it.
15810                    procState = ActivityManager.PROCESS_STATE_TOP;
15811                    break;
15812            }
15813        }
15814
15815        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15816            if (app.hasClientActivities) {
15817                // This is a cached process, but with client activities.  Mark it so.
15818                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15819                app.adjType = "cch-client-act";
15820            } else if (app.treatLikeActivity) {
15821                // This is a cached process, but somebody wants us to treat it like it has
15822                // an activity, okay!
15823                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15824                app.adjType = "cch-as-act";
15825            }
15826        }
15827
15828        if (adj == ProcessList.SERVICE_ADJ) {
15829            if (doingAll) {
15830                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15831                mNewNumServiceProcs++;
15832                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15833                if (!app.serviceb) {
15834                    // This service isn't far enough down on the LRU list to
15835                    // normally be a B service, but if we are low on RAM and it
15836                    // is large we want to force it down since we would prefer to
15837                    // keep launcher over it.
15838                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15839                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15840                        app.serviceHighRam = true;
15841                        app.serviceb = true;
15842                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15843                    } else {
15844                        mNewNumAServiceProcs++;
15845                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15846                    }
15847                } else {
15848                    app.serviceHighRam = false;
15849                }
15850            }
15851            if (app.serviceb) {
15852                adj = ProcessList.SERVICE_B_ADJ;
15853            }
15854        }
15855
15856        app.curRawAdj = adj;
15857
15858        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15859        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15860        if (adj > app.maxAdj) {
15861            adj = app.maxAdj;
15862            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15863                schedGroup = Process.THREAD_GROUP_DEFAULT;
15864            }
15865        }
15866
15867        // Do final modification to adj.  Everything we do between here and applying
15868        // the final setAdj must be done in this function, because we will also use
15869        // it when computing the final cached adj later.  Note that we don't need to
15870        // worry about this for max adj above, since max adj will always be used to
15871        // keep it out of the cached vaues.
15872        app.curAdj = app.modifyRawOomAdj(adj);
15873        app.curSchedGroup = schedGroup;
15874        app.curProcState = procState;
15875        app.foregroundActivities = foregroundActivities;
15876
15877        return app.curRawAdj;
15878    }
15879
15880    /**
15881     * Schedule PSS collection of a process.
15882     */
15883    void requestPssLocked(ProcessRecord proc, int procState) {
15884        if (mPendingPssProcesses.contains(proc)) {
15885            return;
15886        }
15887        if (mPendingPssProcesses.size() == 0) {
15888            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15889        }
15890        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15891        proc.pssProcState = procState;
15892        mPendingPssProcesses.add(proc);
15893    }
15894
15895    /**
15896     * Schedule PSS collection of all processes.
15897     */
15898    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15899        if (!always) {
15900            if (now < (mLastFullPssTime +
15901                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15902                return;
15903            }
15904        }
15905        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15906        mLastFullPssTime = now;
15907        mFullPssPending = true;
15908        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15909        mPendingPssProcesses.clear();
15910        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15911            ProcessRecord app = mLruProcesses.get(i);
15912            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15913                app.pssProcState = app.setProcState;
15914                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15915                        isSleeping(), now);
15916                mPendingPssProcesses.add(app);
15917            }
15918        }
15919        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15920    }
15921
15922    /**
15923     * Ask a given process to GC right now.
15924     */
15925    final void performAppGcLocked(ProcessRecord app) {
15926        try {
15927            app.lastRequestedGc = SystemClock.uptimeMillis();
15928            if (app.thread != null) {
15929                if (app.reportLowMemory) {
15930                    app.reportLowMemory = false;
15931                    app.thread.scheduleLowMemory();
15932                } else {
15933                    app.thread.processInBackground();
15934                }
15935            }
15936        } catch (Exception e) {
15937            // whatever.
15938        }
15939    }
15940
15941    /**
15942     * Returns true if things are idle enough to perform GCs.
15943     */
15944    private final boolean canGcNowLocked() {
15945        boolean processingBroadcasts = false;
15946        for (BroadcastQueue q : mBroadcastQueues) {
15947            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15948                processingBroadcasts = true;
15949            }
15950        }
15951        return !processingBroadcasts
15952                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15953    }
15954
15955    /**
15956     * Perform GCs on all processes that are waiting for it, but only
15957     * if things are idle.
15958     */
15959    final void performAppGcsLocked() {
15960        final int N = mProcessesToGc.size();
15961        if (N <= 0) {
15962            return;
15963        }
15964        if (canGcNowLocked()) {
15965            while (mProcessesToGc.size() > 0) {
15966                ProcessRecord proc = mProcessesToGc.remove(0);
15967                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15968                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15969                            <= SystemClock.uptimeMillis()) {
15970                        // To avoid spamming the system, we will GC processes one
15971                        // at a time, waiting a few seconds between each.
15972                        performAppGcLocked(proc);
15973                        scheduleAppGcsLocked();
15974                        return;
15975                    } else {
15976                        // It hasn't been long enough since we last GCed this
15977                        // process...  put it in the list to wait for its time.
15978                        addProcessToGcListLocked(proc);
15979                        break;
15980                    }
15981                }
15982            }
15983
15984            scheduleAppGcsLocked();
15985        }
15986    }
15987
15988    /**
15989     * If all looks good, perform GCs on all processes waiting for them.
15990     */
15991    final void performAppGcsIfAppropriateLocked() {
15992        if (canGcNowLocked()) {
15993            performAppGcsLocked();
15994            return;
15995        }
15996        // Still not idle, wait some more.
15997        scheduleAppGcsLocked();
15998    }
15999
16000    /**
16001     * Schedule the execution of all pending app GCs.
16002     */
16003    final void scheduleAppGcsLocked() {
16004        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16005
16006        if (mProcessesToGc.size() > 0) {
16007            // Schedule a GC for the time to the next process.
16008            ProcessRecord proc = mProcessesToGc.get(0);
16009            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16010
16011            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16012            long now = SystemClock.uptimeMillis();
16013            if (when < (now+GC_TIMEOUT)) {
16014                when = now + GC_TIMEOUT;
16015            }
16016            mHandler.sendMessageAtTime(msg, when);
16017        }
16018    }
16019
16020    /**
16021     * Add a process to the array of processes waiting to be GCed.  Keeps the
16022     * list in sorted order by the last GC time.  The process can't already be
16023     * on the list.
16024     */
16025    final void addProcessToGcListLocked(ProcessRecord proc) {
16026        boolean added = false;
16027        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16028            if (mProcessesToGc.get(i).lastRequestedGc <
16029                    proc.lastRequestedGc) {
16030                added = true;
16031                mProcessesToGc.add(i+1, proc);
16032                break;
16033            }
16034        }
16035        if (!added) {
16036            mProcessesToGc.add(0, proc);
16037        }
16038    }
16039
16040    /**
16041     * Set up to ask a process to GC itself.  This will either do it
16042     * immediately, or put it on the list of processes to gc the next
16043     * time things are idle.
16044     */
16045    final void scheduleAppGcLocked(ProcessRecord app) {
16046        long now = SystemClock.uptimeMillis();
16047        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16048            return;
16049        }
16050        if (!mProcessesToGc.contains(app)) {
16051            addProcessToGcListLocked(app);
16052            scheduleAppGcsLocked();
16053        }
16054    }
16055
16056    final void checkExcessivePowerUsageLocked(boolean doKills) {
16057        updateCpuStatsNow();
16058
16059        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16060        boolean doWakeKills = doKills;
16061        boolean doCpuKills = doKills;
16062        if (mLastPowerCheckRealtime == 0) {
16063            doWakeKills = false;
16064        }
16065        if (mLastPowerCheckUptime == 0) {
16066            doCpuKills = false;
16067        }
16068        if (stats.isScreenOn()) {
16069            doWakeKills = false;
16070        }
16071        final long curRealtime = SystemClock.elapsedRealtime();
16072        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16073        final long curUptime = SystemClock.uptimeMillis();
16074        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16075        mLastPowerCheckRealtime = curRealtime;
16076        mLastPowerCheckUptime = curUptime;
16077        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16078            doWakeKills = false;
16079        }
16080        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16081            doCpuKills = false;
16082        }
16083        int i = mLruProcesses.size();
16084        while (i > 0) {
16085            i--;
16086            ProcessRecord app = mLruProcesses.get(i);
16087            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16088                long wtime;
16089                synchronized (stats) {
16090                    wtime = stats.getProcessWakeTime(app.info.uid,
16091                            app.pid, curRealtime);
16092                }
16093                long wtimeUsed = wtime - app.lastWakeTime;
16094                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16095                if (DEBUG_POWER) {
16096                    StringBuilder sb = new StringBuilder(128);
16097                    sb.append("Wake for ");
16098                    app.toShortString(sb);
16099                    sb.append(": over ");
16100                    TimeUtils.formatDuration(realtimeSince, sb);
16101                    sb.append(" used ");
16102                    TimeUtils.formatDuration(wtimeUsed, sb);
16103                    sb.append(" (");
16104                    sb.append((wtimeUsed*100)/realtimeSince);
16105                    sb.append("%)");
16106                    Slog.i(TAG, sb.toString());
16107                    sb.setLength(0);
16108                    sb.append("CPU for ");
16109                    app.toShortString(sb);
16110                    sb.append(": over ");
16111                    TimeUtils.formatDuration(uptimeSince, sb);
16112                    sb.append(" used ");
16113                    TimeUtils.formatDuration(cputimeUsed, sb);
16114                    sb.append(" (");
16115                    sb.append((cputimeUsed*100)/uptimeSince);
16116                    sb.append("%)");
16117                    Slog.i(TAG, sb.toString());
16118                }
16119                // If a process has held a wake lock for more
16120                // than 50% of the time during this period,
16121                // that sounds bad.  Kill!
16122                if (doWakeKills && realtimeSince > 0
16123                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16124                    synchronized (stats) {
16125                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16126                                realtimeSince, wtimeUsed);
16127                    }
16128                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16129                            + " during " + realtimeSince);
16130                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16131                } else if (doCpuKills && uptimeSince > 0
16132                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16133                    synchronized (stats) {
16134                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16135                                uptimeSince, cputimeUsed);
16136                    }
16137                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16138                            + " during " + uptimeSince);
16139                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16140                } else {
16141                    app.lastWakeTime = wtime;
16142                    app.lastCpuTime = app.curCpuTime;
16143                }
16144            }
16145        }
16146    }
16147
16148    private final boolean applyOomAdjLocked(ProcessRecord app,
16149            ProcessRecord TOP_APP, boolean doingAll, long now) {
16150        boolean success = true;
16151
16152        if (app.curRawAdj != app.setRawAdj) {
16153            app.setRawAdj = app.curRawAdj;
16154        }
16155
16156        int changes = 0;
16157
16158        if (app.curAdj != app.setAdj) {
16159            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16160            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16161                TAG, "Set " + app.pid + " " + app.processName +
16162                " adj " + app.curAdj + ": " + app.adjType);
16163            app.setAdj = app.curAdj;
16164        }
16165
16166        if (app.setSchedGroup != app.curSchedGroup) {
16167            app.setSchedGroup = app.curSchedGroup;
16168            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16169                    "Setting process group of " + app.processName
16170                    + " to " + app.curSchedGroup);
16171            if (app.waitingToKill != null &&
16172                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16173                killUnneededProcessLocked(app, app.waitingToKill);
16174                success = false;
16175            } else {
16176                if (true) {
16177                    long oldId = Binder.clearCallingIdentity();
16178                    try {
16179                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16180                    } catch (Exception e) {
16181                        Slog.w(TAG, "Failed setting process group of " + app.pid
16182                                + " to " + app.curSchedGroup);
16183                        e.printStackTrace();
16184                    } finally {
16185                        Binder.restoreCallingIdentity(oldId);
16186                    }
16187                } else {
16188                    if (app.thread != null) {
16189                        try {
16190                            app.thread.setSchedulingGroup(app.curSchedGroup);
16191                        } catch (RemoteException e) {
16192                        }
16193                    }
16194                }
16195                Process.setSwappiness(app.pid,
16196                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16197            }
16198        }
16199        if (app.repForegroundActivities != app.foregroundActivities) {
16200            app.repForegroundActivities = app.foregroundActivities;
16201            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16202        }
16203        if (app.repProcState != app.curProcState) {
16204            app.repProcState = app.curProcState;
16205            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16206            if (app.thread != null) {
16207                try {
16208                    if (false) {
16209                        //RuntimeException h = new RuntimeException("here");
16210                        Slog.i(TAG, "Sending new process state " + app.repProcState
16211                                + " to " + app /*, h*/);
16212                    }
16213                    app.thread.setProcessState(app.repProcState);
16214                } catch (RemoteException e) {
16215                }
16216            }
16217        }
16218        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16219                app.setProcState)) {
16220            app.lastStateTime = now;
16221            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16222                    isSleeping(), now);
16223            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16224                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16225                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16226                    + (app.nextPssTime-now) + ": " + app);
16227        } else {
16228            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16229                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16230                requestPssLocked(app, app.setProcState);
16231                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16232                        isSleeping(), now);
16233            } else if (false && DEBUG_PSS) {
16234                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16235            }
16236        }
16237        if (app.setProcState != app.curProcState) {
16238            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16239                    "Proc state change of " + app.processName
16240                    + " to " + app.curProcState);
16241            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16242            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16243            if (setImportant && !curImportant) {
16244                // This app is no longer something we consider important enough to allow to
16245                // use arbitrary amounts of battery power.  Note
16246                // its current wake lock time to later know to kill it if
16247                // it is not behaving well.
16248                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16249                synchronized (stats) {
16250                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16251                            app.pid, SystemClock.elapsedRealtime());
16252                }
16253                app.lastCpuTime = app.curCpuTime;
16254
16255            }
16256            app.setProcState = app.curProcState;
16257            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16258                app.notCachedSinceIdle = false;
16259            }
16260            if (!doingAll) {
16261                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16262            } else {
16263                app.procStateChanged = true;
16264            }
16265        }
16266
16267        if (changes != 0) {
16268            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16269            int i = mPendingProcessChanges.size()-1;
16270            ProcessChangeItem item = null;
16271            while (i >= 0) {
16272                item = mPendingProcessChanges.get(i);
16273                if (item.pid == app.pid) {
16274                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16275                    break;
16276                }
16277                i--;
16278            }
16279            if (i < 0) {
16280                // No existing item in pending changes; need a new one.
16281                final int NA = mAvailProcessChanges.size();
16282                if (NA > 0) {
16283                    item = mAvailProcessChanges.remove(NA-1);
16284                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16285                } else {
16286                    item = new ProcessChangeItem();
16287                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16288                }
16289                item.changes = 0;
16290                item.pid = app.pid;
16291                item.uid = app.info.uid;
16292                if (mPendingProcessChanges.size() == 0) {
16293                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16294                            "*** Enqueueing dispatch processes changed!");
16295                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16296                }
16297                mPendingProcessChanges.add(item);
16298            }
16299            item.changes |= changes;
16300            item.processState = app.repProcState;
16301            item.foregroundActivities = app.repForegroundActivities;
16302            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16303                    + Integer.toHexString(System.identityHashCode(item))
16304                    + " " + app.toShortString() + ": changes=" + item.changes
16305                    + " procState=" + item.processState
16306                    + " foreground=" + item.foregroundActivities
16307                    + " type=" + app.adjType + " source=" + app.adjSource
16308                    + " target=" + app.adjTarget);
16309        }
16310
16311        return success;
16312    }
16313
16314    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16315        if (proc.thread != null) {
16316            if (proc.baseProcessTracker != null) {
16317                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16318            }
16319            if (proc.repProcState >= 0) {
16320                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16321                        proc.repProcState);
16322            }
16323        }
16324    }
16325
16326    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16327            ProcessRecord TOP_APP, boolean doingAll, long now) {
16328        if (app.thread == null) {
16329            return false;
16330        }
16331
16332        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16333
16334        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16335    }
16336
16337    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16338            boolean oomAdj) {
16339        if (isForeground != proc.foregroundServices) {
16340            proc.foregroundServices = isForeground;
16341            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16342                    proc.info.uid);
16343            if (isForeground) {
16344                if (curProcs == null) {
16345                    curProcs = new ArrayList<ProcessRecord>();
16346                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16347                }
16348                if (!curProcs.contains(proc)) {
16349                    curProcs.add(proc);
16350                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16351                            proc.info.packageName, proc.info.uid);
16352                }
16353            } else {
16354                if (curProcs != null) {
16355                    if (curProcs.remove(proc)) {
16356                        mBatteryStatsService.noteEvent(
16357                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16358                                proc.info.packageName, proc.info.uid);
16359                        if (curProcs.size() <= 0) {
16360                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16361                        }
16362                    }
16363                }
16364            }
16365            if (oomAdj) {
16366                updateOomAdjLocked();
16367            }
16368        }
16369    }
16370
16371    private final ActivityRecord resumedAppLocked() {
16372        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16373        String pkg;
16374        int uid;
16375        if (act != null) {
16376            pkg = act.packageName;
16377            uid = act.info.applicationInfo.uid;
16378        } else {
16379            pkg = null;
16380            uid = -1;
16381        }
16382        // Has the UID or resumed package name changed?
16383        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16384                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16385            if (mCurResumedPackage != null) {
16386                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16387                        mCurResumedPackage, mCurResumedUid);
16388            }
16389            mCurResumedPackage = pkg;
16390            mCurResumedUid = uid;
16391            if (mCurResumedPackage != null) {
16392                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16393                        mCurResumedPackage, mCurResumedUid);
16394            }
16395        }
16396        return act;
16397    }
16398
16399    final boolean updateOomAdjLocked(ProcessRecord app) {
16400        final ActivityRecord TOP_ACT = resumedAppLocked();
16401        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16402        final boolean wasCached = app.cached;
16403
16404        mAdjSeq++;
16405
16406        // This is the desired cached adjusment we want to tell it to use.
16407        // If our app is currently cached, we know it, and that is it.  Otherwise,
16408        // we don't know it yet, and it needs to now be cached we will then
16409        // need to do a complete oom adj.
16410        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16411                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16412        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16413                SystemClock.uptimeMillis());
16414        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16415            // Changed to/from cached state, so apps after it in the LRU
16416            // list may also be changed.
16417            updateOomAdjLocked();
16418        }
16419        return success;
16420    }
16421
16422    final void updateOomAdjLocked() {
16423        final ActivityRecord TOP_ACT = resumedAppLocked();
16424        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16425        final long now = SystemClock.uptimeMillis();
16426        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16427        final int N = mLruProcesses.size();
16428
16429        if (false) {
16430            RuntimeException e = new RuntimeException();
16431            e.fillInStackTrace();
16432            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16433        }
16434
16435        mAdjSeq++;
16436        mNewNumServiceProcs = 0;
16437        mNewNumAServiceProcs = 0;
16438
16439        final int emptyProcessLimit;
16440        final int cachedProcessLimit;
16441        if (mProcessLimit <= 0) {
16442            emptyProcessLimit = cachedProcessLimit = 0;
16443        } else if (mProcessLimit == 1) {
16444            emptyProcessLimit = 1;
16445            cachedProcessLimit = 0;
16446        } else {
16447            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16448            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16449        }
16450
16451        // Let's determine how many processes we have running vs.
16452        // how many slots we have for background processes; we may want
16453        // to put multiple processes in a slot of there are enough of
16454        // them.
16455        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16456                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16457        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16458        if (numEmptyProcs > cachedProcessLimit) {
16459            // If there are more empty processes than our limit on cached
16460            // processes, then use the cached process limit for the factor.
16461            // This ensures that the really old empty processes get pushed
16462            // down to the bottom, so if we are running low on memory we will
16463            // have a better chance at keeping around more cached processes
16464            // instead of a gazillion empty processes.
16465            numEmptyProcs = cachedProcessLimit;
16466        }
16467        int emptyFactor = numEmptyProcs/numSlots;
16468        if (emptyFactor < 1) emptyFactor = 1;
16469        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16470        if (cachedFactor < 1) cachedFactor = 1;
16471        int stepCached = 0;
16472        int stepEmpty = 0;
16473        int numCached = 0;
16474        int numEmpty = 0;
16475        int numTrimming = 0;
16476
16477        mNumNonCachedProcs = 0;
16478        mNumCachedHiddenProcs = 0;
16479
16480        // First update the OOM adjustment for each of the
16481        // application processes based on their current state.
16482        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16483        int nextCachedAdj = curCachedAdj+1;
16484        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16485        int nextEmptyAdj = curEmptyAdj+2;
16486        for (int i=N-1; i>=0; i--) {
16487            ProcessRecord app = mLruProcesses.get(i);
16488            if (!app.killedByAm && app.thread != null) {
16489                app.procStateChanged = false;
16490                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16491
16492                // If we haven't yet assigned the final cached adj
16493                // to the process, do that now.
16494                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16495                    switch (app.curProcState) {
16496                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16497                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16498                            // This process is a cached process holding activities...
16499                            // assign it the next cached value for that type, and then
16500                            // step that cached level.
16501                            app.curRawAdj = curCachedAdj;
16502                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16503                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16504                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16505                                    + ")");
16506                            if (curCachedAdj != nextCachedAdj) {
16507                                stepCached++;
16508                                if (stepCached >= cachedFactor) {
16509                                    stepCached = 0;
16510                                    curCachedAdj = nextCachedAdj;
16511                                    nextCachedAdj += 2;
16512                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16513                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16514                                    }
16515                                }
16516                            }
16517                            break;
16518                        default:
16519                            // For everything else, assign next empty cached process
16520                            // level and bump that up.  Note that this means that
16521                            // long-running services that have dropped down to the
16522                            // cached level will be treated as empty (since their process
16523                            // state is still as a service), which is what we want.
16524                            app.curRawAdj = curEmptyAdj;
16525                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16526                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16527                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16528                                    + ")");
16529                            if (curEmptyAdj != nextEmptyAdj) {
16530                                stepEmpty++;
16531                                if (stepEmpty >= emptyFactor) {
16532                                    stepEmpty = 0;
16533                                    curEmptyAdj = nextEmptyAdj;
16534                                    nextEmptyAdj += 2;
16535                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16536                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16537                                    }
16538                                }
16539                            }
16540                            break;
16541                    }
16542                }
16543
16544                applyOomAdjLocked(app, TOP_APP, true, now);
16545
16546                // Count the number of process types.
16547                switch (app.curProcState) {
16548                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16549                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16550                        mNumCachedHiddenProcs++;
16551                        numCached++;
16552                        if (numCached > cachedProcessLimit) {
16553                            killUnneededProcessLocked(app, "cached #" + numCached);
16554                        }
16555                        break;
16556                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16557                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16558                                && app.lastActivityTime < oldTime) {
16559                            killUnneededProcessLocked(app, "empty for "
16560                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16561                                    / 1000) + "s");
16562                        } else {
16563                            numEmpty++;
16564                            if (numEmpty > emptyProcessLimit) {
16565                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16566                            }
16567                        }
16568                        break;
16569                    default:
16570                        mNumNonCachedProcs++;
16571                        break;
16572                }
16573
16574                if (app.isolated && app.services.size() <= 0) {
16575                    // If this is an isolated process, and there are no
16576                    // services running in it, then the process is no longer
16577                    // needed.  We agressively kill these because we can by
16578                    // definition not re-use the same process again, and it is
16579                    // good to avoid having whatever code was running in them
16580                    // left sitting around after no longer needed.
16581                    killUnneededProcessLocked(app, "isolated not needed");
16582                }
16583
16584                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16585                        && !app.killedByAm) {
16586                    numTrimming++;
16587                }
16588            }
16589        }
16590
16591        mNumServiceProcs = mNewNumServiceProcs;
16592
16593        // Now determine the memory trimming level of background processes.
16594        // Unfortunately we need to start at the back of the list to do this
16595        // properly.  We only do this if the number of background apps we
16596        // are managing to keep around is less than half the maximum we desire;
16597        // if we are keeping a good number around, we'll let them use whatever
16598        // memory they want.
16599        final int numCachedAndEmpty = numCached + numEmpty;
16600        int memFactor;
16601        if (numCached <= ProcessList.TRIM_CACHED_APPS
16602                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16603            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16604                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16605            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16606                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16607            } else {
16608                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16609            }
16610        } else {
16611            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16612        }
16613        // We always allow the memory level to go up (better).  We only allow it to go
16614        // down if we are in a state where that is allowed, *and* the total number of processes
16615        // has gone down since last time.
16616        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16617                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16618                + " last=" + mLastNumProcesses);
16619        if (memFactor > mLastMemoryLevel) {
16620            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16621                memFactor = mLastMemoryLevel;
16622                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16623            }
16624        }
16625        mLastMemoryLevel = memFactor;
16626        mLastNumProcesses = mLruProcesses.size();
16627        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16628        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16629        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16630            if (mLowRamStartTime == 0) {
16631                mLowRamStartTime = now;
16632            }
16633            int step = 0;
16634            int fgTrimLevel;
16635            switch (memFactor) {
16636                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16637                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16638                    break;
16639                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16640                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16641                    break;
16642                default:
16643                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16644                    break;
16645            }
16646            int factor = numTrimming/3;
16647            int minFactor = 2;
16648            if (mHomeProcess != null) minFactor++;
16649            if (mPreviousProcess != null) minFactor++;
16650            if (factor < minFactor) factor = minFactor;
16651            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16652            for (int i=N-1; i>=0; i--) {
16653                ProcessRecord app = mLruProcesses.get(i);
16654                if (allChanged || app.procStateChanged) {
16655                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16656                    app.procStateChanged = false;
16657                }
16658                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16659                        && !app.killedByAm) {
16660                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16661                        try {
16662                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16663                                    "Trimming memory of " + app.processName
16664                                    + " to " + curLevel);
16665                            app.thread.scheduleTrimMemory(curLevel);
16666                        } catch (RemoteException e) {
16667                        }
16668                        if (false) {
16669                            // For now we won't do this; our memory trimming seems
16670                            // to be good enough at this point that destroying
16671                            // activities causes more harm than good.
16672                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16673                                    && app != mHomeProcess && app != mPreviousProcess) {
16674                                // Need to do this on its own message because the stack may not
16675                                // be in a consistent state at this point.
16676                                // For these apps we will also finish their activities
16677                                // to help them free memory.
16678                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16679                            }
16680                        }
16681                    }
16682                    app.trimMemoryLevel = curLevel;
16683                    step++;
16684                    if (step >= factor) {
16685                        step = 0;
16686                        switch (curLevel) {
16687                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16688                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16689                                break;
16690                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16691                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16692                                break;
16693                        }
16694                    }
16695                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16696                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16697                            && app.thread != null) {
16698                        try {
16699                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16700                                    "Trimming memory of heavy-weight " + app.processName
16701                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16702                            app.thread.scheduleTrimMemory(
16703                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16704                        } catch (RemoteException e) {
16705                        }
16706                    }
16707                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16708                } else {
16709                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16710                            || app.systemNoUi) && app.pendingUiClean) {
16711                        // If this application is now in the background and it
16712                        // had done UI, then give it the special trim level to
16713                        // have it free UI resources.
16714                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16715                        if (app.trimMemoryLevel < level && app.thread != null) {
16716                            try {
16717                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16718                                        "Trimming memory of bg-ui " + app.processName
16719                                        + " to " + level);
16720                                app.thread.scheduleTrimMemory(level);
16721                            } catch (RemoteException e) {
16722                            }
16723                        }
16724                        app.pendingUiClean = false;
16725                    }
16726                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16727                        try {
16728                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16729                                    "Trimming memory of fg " + app.processName
16730                                    + " to " + fgTrimLevel);
16731                            app.thread.scheduleTrimMemory(fgTrimLevel);
16732                        } catch (RemoteException e) {
16733                        }
16734                    }
16735                    app.trimMemoryLevel = fgTrimLevel;
16736                }
16737            }
16738        } else {
16739            if (mLowRamStartTime != 0) {
16740                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16741                mLowRamStartTime = 0;
16742            }
16743            for (int i=N-1; i>=0; i--) {
16744                ProcessRecord app = mLruProcesses.get(i);
16745                if (allChanged || app.procStateChanged) {
16746                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16747                    app.procStateChanged = false;
16748                }
16749                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16750                        || app.systemNoUi) && app.pendingUiClean) {
16751                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16752                            && app.thread != null) {
16753                        try {
16754                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16755                                    "Trimming memory of ui hidden " + app.processName
16756                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16757                            app.thread.scheduleTrimMemory(
16758                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16759                        } catch (RemoteException e) {
16760                        }
16761                    }
16762                    app.pendingUiClean = false;
16763                }
16764                app.trimMemoryLevel = 0;
16765            }
16766        }
16767
16768        if (mAlwaysFinishActivities) {
16769            // Need to do this on its own message because the stack may not
16770            // be in a consistent state at this point.
16771            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16772        }
16773
16774        if (allChanged) {
16775            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16776        }
16777
16778        if (mProcessStats.shouldWriteNowLocked(now)) {
16779            mHandler.post(new Runnable() {
16780                @Override public void run() {
16781                    synchronized (ActivityManagerService.this) {
16782                        mProcessStats.writeStateAsyncLocked();
16783                    }
16784                }
16785            });
16786        }
16787
16788        if (DEBUG_OOM_ADJ) {
16789            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16790        }
16791    }
16792
16793    final void trimApplications() {
16794        synchronized (this) {
16795            int i;
16796
16797            // First remove any unused application processes whose package
16798            // has been removed.
16799            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16800                final ProcessRecord app = mRemovedProcesses.get(i);
16801                if (app.activities.size() == 0
16802                        && app.curReceiver == null && app.services.size() == 0) {
16803                    Slog.i(
16804                        TAG, "Exiting empty application process "
16805                        + app.processName + " ("
16806                        + (app.thread != null ? app.thread.asBinder() : null)
16807                        + ")\n");
16808                    if (app.pid > 0 && app.pid != MY_PID) {
16809                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16810                                app.processName, app.setAdj, "empty");
16811                        app.killedByAm = true;
16812                        Process.killProcessQuiet(app.pid);
16813                        Process.killProcessGroup(app.info.uid, app.pid);
16814                    } else {
16815                        try {
16816                            app.thread.scheduleExit();
16817                        } catch (Exception e) {
16818                            // Ignore exceptions.
16819                        }
16820                    }
16821                    cleanUpApplicationRecordLocked(app, false, true, -1);
16822                    mRemovedProcesses.remove(i);
16823
16824                    if (app.persistent) {
16825                        addAppLocked(app.info, false, null /* ABI override */);
16826                    }
16827                }
16828            }
16829
16830            // Now update the oom adj for all processes.
16831            updateOomAdjLocked();
16832        }
16833    }
16834
16835    /** This method sends the specified signal to each of the persistent apps */
16836    public void signalPersistentProcesses(int sig) throws RemoteException {
16837        if (sig != Process.SIGNAL_USR1) {
16838            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16839        }
16840
16841        synchronized (this) {
16842            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16843                    != PackageManager.PERMISSION_GRANTED) {
16844                throw new SecurityException("Requires permission "
16845                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16846            }
16847
16848            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16849                ProcessRecord r = mLruProcesses.get(i);
16850                if (r.thread != null && r.persistent) {
16851                    Process.sendSignal(r.pid, sig);
16852                }
16853            }
16854        }
16855    }
16856
16857    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16858        if (proc == null || proc == mProfileProc) {
16859            proc = mProfileProc;
16860            path = mProfileFile;
16861            profileType = mProfileType;
16862            clearProfilerLocked();
16863        }
16864        if (proc == null) {
16865            return;
16866        }
16867        try {
16868            proc.thread.profilerControl(false, path, null, profileType);
16869        } catch (RemoteException e) {
16870            throw new IllegalStateException("Process disappeared");
16871        }
16872    }
16873
16874    private void clearProfilerLocked() {
16875        if (mProfileFd != null) {
16876            try {
16877                mProfileFd.close();
16878            } catch (IOException e) {
16879            }
16880        }
16881        mProfileApp = null;
16882        mProfileProc = null;
16883        mProfileFile = null;
16884        mProfileType = 0;
16885        mAutoStopProfiler = false;
16886    }
16887
16888    public boolean profileControl(String process, int userId, boolean start,
16889            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16890
16891        try {
16892            synchronized (this) {
16893                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16894                // its own permission.
16895                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16896                        != PackageManager.PERMISSION_GRANTED) {
16897                    throw new SecurityException("Requires permission "
16898                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16899                }
16900
16901                if (start && fd == null) {
16902                    throw new IllegalArgumentException("null fd");
16903                }
16904
16905                ProcessRecord proc = null;
16906                if (process != null) {
16907                    proc = findProcessLocked(process, userId, "profileControl");
16908                }
16909
16910                if (start && (proc == null || proc.thread == null)) {
16911                    throw new IllegalArgumentException("Unknown process: " + process);
16912                }
16913
16914                if (start) {
16915                    stopProfilerLocked(null, null, 0);
16916                    setProfileApp(proc.info, proc.processName, path, fd, false);
16917                    mProfileProc = proc;
16918                    mProfileType = profileType;
16919                    try {
16920                        fd = fd.dup();
16921                    } catch (IOException e) {
16922                        fd = null;
16923                    }
16924                    proc.thread.profilerControl(start, path, fd, profileType);
16925                    fd = null;
16926                    mProfileFd = null;
16927                } else {
16928                    stopProfilerLocked(proc, path, profileType);
16929                    if (fd != null) {
16930                        try {
16931                            fd.close();
16932                        } catch (IOException e) {
16933                        }
16934                    }
16935                }
16936
16937                return true;
16938            }
16939        } catch (RemoteException e) {
16940            throw new IllegalStateException("Process disappeared");
16941        } finally {
16942            if (fd != null) {
16943                try {
16944                    fd.close();
16945                } catch (IOException e) {
16946                }
16947            }
16948        }
16949    }
16950
16951    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16952        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16953                userId, true, ALLOW_FULL_ONLY, callName, null);
16954        ProcessRecord proc = null;
16955        try {
16956            int pid = Integer.parseInt(process);
16957            synchronized (mPidsSelfLocked) {
16958                proc = mPidsSelfLocked.get(pid);
16959            }
16960        } catch (NumberFormatException e) {
16961        }
16962
16963        if (proc == null) {
16964            ArrayMap<String, SparseArray<ProcessRecord>> all
16965                    = mProcessNames.getMap();
16966            SparseArray<ProcessRecord> procs = all.get(process);
16967            if (procs != null && procs.size() > 0) {
16968                proc = procs.valueAt(0);
16969                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16970                    for (int i=1; i<procs.size(); i++) {
16971                        ProcessRecord thisProc = procs.valueAt(i);
16972                        if (thisProc.userId == userId) {
16973                            proc = thisProc;
16974                            break;
16975                        }
16976                    }
16977                }
16978            }
16979        }
16980
16981        return proc;
16982    }
16983
16984    public boolean dumpHeap(String process, int userId, boolean managed,
16985            String path, ParcelFileDescriptor fd) throws RemoteException {
16986
16987        try {
16988            synchronized (this) {
16989                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16990                // its own permission (same as profileControl).
16991                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16992                        != PackageManager.PERMISSION_GRANTED) {
16993                    throw new SecurityException("Requires permission "
16994                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16995                }
16996
16997                if (fd == null) {
16998                    throw new IllegalArgumentException("null fd");
16999                }
17000
17001                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17002                if (proc == null || proc.thread == null) {
17003                    throw new IllegalArgumentException("Unknown process: " + process);
17004                }
17005
17006                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17007                if (!isDebuggable) {
17008                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17009                        throw new SecurityException("Process not debuggable: " + proc);
17010                    }
17011                }
17012
17013                proc.thread.dumpHeap(managed, path, fd);
17014                fd = null;
17015                return true;
17016            }
17017        } catch (RemoteException e) {
17018            throw new IllegalStateException("Process disappeared");
17019        } finally {
17020            if (fd != null) {
17021                try {
17022                    fd.close();
17023                } catch (IOException e) {
17024                }
17025            }
17026        }
17027    }
17028
17029    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17030    public void monitor() {
17031        synchronized (this) { }
17032    }
17033
17034    void onCoreSettingsChange(Bundle settings) {
17035        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17036            ProcessRecord processRecord = mLruProcesses.get(i);
17037            try {
17038                if (processRecord.thread != null) {
17039                    processRecord.thread.setCoreSettings(settings);
17040                }
17041            } catch (RemoteException re) {
17042                /* ignore */
17043            }
17044        }
17045    }
17046
17047    // Multi-user methods
17048
17049    /**
17050     * Start user, if its not already running, but don't bring it to foreground.
17051     */
17052    @Override
17053    public boolean startUserInBackground(final int userId) {
17054        return startUser(userId, /* foreground */ false);
17055    }
17056
17057    /**
17058     * Refreshes the list of users related to the current user when either a
17059     * user switch happens or when a new related user is started in the
17060     * background.
17061     */
17062    private void updateCurrentProfileIdsLocked() {
17063        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17064                mCurrentUserId, false /* enabledOnly */);
17065        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17066        for (int i = 0; i < currentProfileIds.length; i++) {
17067            currentProfileIds[i] = profiles.get(i).id;
17068        }
17069        mCurrentProfileIds = currentProfileIds;
17070
17071        synchronized (mUserProfileGroupIdsSelfLocked) {
17072            mUserProfileGroupIdsSelfLocked.clear();
17073            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17074            for (int i = 0; i < users.size(); i++) {
17075                UserInfo user = users.get(i);
17076                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17077                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17078                }
17079            }
17080        }
17081    }
17082
17083    private Set getProfileIdsLocked(int userId) {
17084        Set userIds = new HashSet<Integer>();
17085        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17086                userId, false /* enabledOnly */);
17087        for (UserInfo user : profiles) {
17088            userIds.add(Integer.valueOf(user.id));
17089        }
17090        return userIds;
17091    }
17092
17093    @Override
17094    public boolean switchUser(final int userId) {
17095        return startUser(userId, /* foregound */ true);
17096    }
17097
17098    private boolean startUser(final int userId, boolean foreground) {
17099        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17100                != PackageManager.PERMISSION_GRANTED) {
17101            String msg = "Permission Denial: switchUser() from pid="
17102                    + Binder.getCallingPid()
17103                    + ", uid=" + Binder.getCallingUid()
17104                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17105            Slog.w(TAG, msg);
17106            throw new SecurityException(msg);
17107        }
17108
17109        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17110
17111        final long ident = Binder.clearCallingIdentity();
17112        try {
17113            synchronized (this) {
17114                final int oldUserId = mCurrentUserId;
17115                if (oldUserId == userId) {
17116                    return true;
17117                }
17118
17119                mStackSupervisor.setLockTaskModeLocked(null, false);
17120
17121                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17122                if (userInfo == null) {
17123                    Slog.w(TAG, "No user info for user #" + userId);
17124                    return false;
17125                }
17126
17127                if (foreground) {
17128                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17129                            R.anim.screen_user_enter);
17130                }
17131
17132                boolean needStart = false;
17133
17134                // If the user we are switching to is not currently started, then
17135                // we need to start it now.
17136                if (mStartedUsers.get(userId) == null) {
17137                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17138                    updateStartedUserArrayLocked();
17139                    needStart = true;
17140                }
17141
17142                final Integer userIdInt = Integer.valueOf(userId);
17143                mUserLru.remove(userIdInt);
17144                mUserLru.add(userIdInt);
17145
17146                if (foreground) {
17147                    mCurrentUserId = userId;
17148                    updateCurrentProfileIdsLocked();
17149                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17150                    // Once the internal notion of the active user has switched, we lock the device
17151                    // with the option to show the user switcher on the keyguard.
17152                    mWindowManager.lockNow(null);
17153                } else {
17154                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17155                    updateCurrentProfileIdsLocked();
17156                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17157                    mUserLru.remove(currentUserIdInt);
17158                    mUserLru.add(currentUserIdInt);
17159                }
17160
17161                final UserStartedState uss = mStartedUsers.get(userId);
17162
17163                // Make sure user is in the started state.  If it is currently
17164                // stopping, we need to knock that off.
17165                if (uss.mState == UserStartedState.STATE_STOPPING) {
17166                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17167                    // so we can just fairly silently bring the user back from
17168                    // the almost-dead.
17169                    uss.mState = UserStartedState.STATE_RUNNING;
17170                    updateStartedUserArrayLocked();
17171                    needStart = true;
17172                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17173                    // This means ACTION_SHUTDOWN has been sent, so we will
17174                    // need to treat this as a new boot of the user.
17175                    uss.mState = UserStartedState.STATE_BOOTING;
17176                    updateStartedUserArrayLocked();
17177                    needStart = true;
17178                }
17179
17180                if (uss.mState == UserStartedState.STATE_BOOTING) {
17181                    // Booting up a new user, need to tell system services about it.
17182                    // Note that this is on the same handler as scheduling of broadcasts,
17183                    // which is important because it needs to go first.
17184                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17185                }
17186
17187                if (foreground) {
17188                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17189                            oldUserId));
17190                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17191                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17192                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17193                            oldUserId, userId, uss));
17194                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17195                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17196                }
17197
17198                if (needStart) {
17199                    // Send USER_STARTED broadcast
17200                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17201                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17202                            | Intent.FLAG_RECEIVER_FOREGROUND);
17203                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17204                    broadcastIntentLocked(null, null, intent,
17205                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17206                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17207                }
17208
17209                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17210                    if (userId != UserHandle.USER_OWNER) {
17211                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17212                        final ArrayList<ComponentName> doneReceivers
17213                                = new ArrayList<ComponentName>();
17214                        deliverPreBootCompleted(null, doneReceivers, userId);
17215
17216                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17217                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17218                        broadcastIntentLocked(null, null, intent, null,
17219                                new IIntentReceiver.Stub() {
17220                                    public void performReceive(Intent intent, int resultCode,
17221                                            String data, Bundle extras, boolean ordered,
17222                                            boolean sticky, int sendingUser) {
17223                                        userInitialized(uss, userId);
17224                                    }
17225                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17226                                true, false, MY_PID, Process.SYSTEM_UID,
17227                                userId);
17228                        uss.initializing = true;
17229                    } else {
17230                        getUserManagerLocked().makeInitialized(userInfo.id);
17231                    }
17232                }
17233
17234                if (foreground) {
17235                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17236                    if (homeInFront) {
17237                        startHomeActivityLocked(userId);
17238                    } else {
17239                        mStackSupervisor.resumeTopActivitiesLocked();
17240                    }
17241                    EventLogTags.writeAmSwitchUser(userId);
17242                    getUserManagerLocked().userForeground(userId);
17243                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17244                } else {
17245                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17246                }
17247
17248                if (needStart) {
17249                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17250                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17251                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17252                    broadcastIntentLocked(null, null, intent,
17253                            null, new IIntentReceiver.Stub() {
17254                                @Override
17255                                public void performReceive(Intent intent, int resultCode, String data,
17256                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17257                                        throws RemoteException {
17258                                }
17259                            }, 0, null, null,
17260                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17261                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17262                }
17263            }
17264        } finally {
17265            Binder.restoreCallingIdentity(ident);
17266        }
17267
17268        return true;
17269    }
17270
17271    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17272        long ident = Binder.clearCallingIdentity();
17273        try {
17274            Intent intent;
17275            if (oldUserId >= 0) {
17276                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17277                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17278                int count = profiles.size();
17279                for (int i = 0; i < count; i++) {
17280                    int profileUserId = profiles.get(i).id;
17281                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17282                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17283                            | Intent.FLAG_RECEIVER_FOREGROUND);
17284                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17285                    broadcastIntentLocked(null, null, intent,
17286                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17287                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17288                }
17289            }
17290            if (newUserId >= 0) {
17291                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17292                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17293                int count = profiles.size();
17294                for (int i = 0; i < count; i++) {
17295                    int profileUserId = profiles.get(i).id;
17296                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17297                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17298                            | Intent.FLAG_RECEIVER_FOREGROUND);
17299                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17300                    broadcastIntentLocked(null, null, intent,
17301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17302                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17303                }
17304                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17305                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17306                        | Intent.FLAG_RECEIVER_FOREGROUND);
17307                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17308                broadcastIntentLocked(null, null, intent,
17309                        null, null, 0, null, null,
17310                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17311                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17312            }
17313        } finally {
17314            Binder.restoreCallingIdentity(ident);
17315        }
17316    }
17317
17318    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17319            final int newUserId) {
17320        final int N = mUserSwitchObservers.beginBroadcast();
17321        if (N > 0) {
17322            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17323                int mCount = 0;
17324                @Override
17325                public void sendResult(Bundle data) throws RemoteException {
17326                    synchronized (ActivityManagerService.this) {
17327                        if (mCurUserSwitchCallback == this) {
17328                            mCount++;
17329                            if (mCount == N) {
17330                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17331                            }
17332                        }
17333                    }
17334                }
17335            };
17336            synchronized (this) {
17337                uss.switching = true;
17338                mCurUserSwitchCallback = callback;
17339            }
17340            for (int i=0; i<N; i++) {
17341                try {
17342                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17343                            newUserId, callback);
17344                } catch (RemoteException e) {
17345                }
17346            }
17347        } else {
17348            synchronized (this) {
17349                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17350            }
17351        }
17352        mUserSwitchObservers.finishBroadcast();
17353    }
17354
17355    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17356        synchronized (this) {
17357            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17358            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17359        }
17360    }
17361
17362    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17363        mCurUserSwitchCallback = null;
17364        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17365        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17366                oldUserId, newUserId, uss));
17367    }
17368
17369    void userInitialized(UserStartedState uss, int newUserId) {
17370        completeSwitchAndInitalize(uss, newUserId, true, false);
17371    }
17372
17373    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17374        completeSwitchAndInitalize(uss, newUserId, false, true);
17375    }
17376
17377    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17378            boolean clearInitializing, boolean clearSwitching) {
17379        boolean unfrozen = false;
17380        synchronized (this) {
17381            if (clearInitializing) {
17382                uss.initializing = false;
17383                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17384            }
17385            if (clearSwitching) {
17386                uss.switching = false;
17387            }
17388            if (!uss.switching && !uss.initializing) {
17389                mWindowManager.stopFreezingScreen();
17390                unfrozen = true;
17391            }
17392        }
17393        if (unfrozen) {
17394            final int N = mUserSwitchObservers.beginBroadcast();
17395            for (int i=0; i<N; i++) {
17396                try {
17397                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17398                } catch (RemoteException e) {
17399                }
17400            }
17401            mUserSwitchObservers.finishBroadcast();
17402        }
17403    }
17404
17405    void scheduleStartProfilesLocked() {
17406        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17407            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17408                    DateUtils.SECOND_IN_MILLIS);
17409        }
17410    }
17411
17412    void startProfilesLocked() {
17413        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17414        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17415                mCurrentUserId, false /* enabledOnly */);
17416        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17417        for (UserInfo user : profiles) {
17418            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17419                    && user.id != mCurrentUserId) {
17420                toStart.add(user);
17421            }
17422        }
17423        final int n = toStart.size();
17424        int i = 0;
17425        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17426            startUserInBackground(toStart.get(i).id);
17427        }
17428        if (i < n) {
17429            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17430        }
17431    }
17432
17433    void finishUserBoot(UserStartedState uss) {
17434        synchronized (this) {
17435            if (uss.mState == UserStartedState.STATE_BOOTING
17436                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17437                uss.mState = UserStartedState.STATE_RUNNING;
17438                final int userId = uss.mHandle.getIdentifier();
17439                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17440                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17441                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17442                broadcastIntentLocked(null, null, intent,
17443                        null, null, 0, null, null,
17444                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17445                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17446            }
17447        }
17448    }
17449
17450    void finishUserSwitch(UserStartedState uss) {
17451        synchronized (this) {
17452            finishUserBoot(uss);
17453
17454            startProfilesLocked();
17455
17456            int num = mUserLru.size();
17457            int i = 0;
17458            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17459                Integer oldUserId = mUserLru.get(i);
17460                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17461                if (oldUss == null) {
17462                    // Shouldn't happen, but be sane if it does.
17463                    mUserLru.remove(i);
17464                    num--;
17465                    continue;
17466                }
17467                if (oldUss.mState == UserStartedState.STATE_STOPPING
17468                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17469                    // This user is already stopping, doesn't count.
17470                    num--;
17471                    i++;
17472                    continue;
17473                }
17474                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17475                    // Owner and current can't be stopped, but count as running.
17476                    i++;
17477                    continue;
17478                }
17479                // This is a user to be stopped.
17480                stopUserLocked(oldUserId, null);
17481                num--;
17482                i++;
17483            }
17484        }
17485    }
17486
17487    @Override
17488    public int stopUser(final int userId, final IStopUserCallback callback) {
17489        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17490                != PackageManager.PERMISSION_GRANTED) {
17491            String msg = "Permission Denial: switchUser() from pid="
17492                    + Binder.getCallingPid()
17493                    + ", uid=" + Binder.getCallingUid()
17494                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17495            Slog.w(TAG, msg);
17496            throw new SecurityException(msg);
17497        }
17498        if (userId <= 0) {
17499            throw new IllegalArgumentException("Can't stop primary user " + userId);
17500        }
17501        synchronized (this) {
17502            return stopUserLocked(userId, callback);
17503        }
17504    }
17505
17506    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17507        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17508        if (mCurrentUserId == userId) {
17509            return ActivityManager.USER_OP_IS_CURRENT;
17510        }
17511
17512        final UserStartedState uss = mStartedUsers.get(userId);
17513        if (uss == null) {
17514            // User is not started, nothing to do...  but we do need to
17515            // callback if requested.
17516            if (callback != null) {
17517                mHandler.post(new Runnable() {
17518                    @Override
17519                    public void run() {
17520                        try {
17521                            callback.userStopped(userId);
17522                        } catch (RemoteException e) {
17523                        }
17524                    }
17525                });
17526            }
17527            return ActivityManager.USER_OP_SUCCESS;
17528        }
17529
17530        if (callback != null) {
17531            uss.mStopCallbacks.add(callback);
17532        }
17533
17534        if (uss.mState != UserStartedState.STATE_STOPPING
17535                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17536            uss.mState = UserStartedState.STATE_STOPPING;
17537            updateStartedUserArrayLocked();
17538
17539            long ident = Binder.clearCallingIdentity();
17540            try {
17541                // We are going to broadcast ACTION_USER_STOPPING and then
17542                // once that is done send a final ACTION_SHUTDOWN and then
17543                // stop the user.
17544                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17545                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17546                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17547                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17548                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17549                // This is the result receiver for the final shutdown broadcast.
17550                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17551                    @Override
17552                    public void performReceive(Intent intent, int resultCode, String data,
17553                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17554                        finishUserStop(uss);
17555                    }
17556                };
17557                // This is the result receiver for the initial stopping broadcast.
17558                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17559                    @Override
17560                    public void performReceive(Intent intent, int resultCode, String data,
17561                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17562                        // On to the next.
17563                        synchronized (ActivityManagerService.this) {
17564                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17565                                // Whoops, we are being started back up.  Abort, abort!
17566                                return;
17567                            }
17568                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17569                        }
17570                        mBatteryStatsService.noteEvent(
17571                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17572                                Integer.toString(userId), userId);
17573                        mSystemServiceManager.stopUser(userId);
17574                        broadcastIntentLocked(null, null, shutdownIntent,
17575                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17576                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17577                    }
17578                };
17579                // Kick things off.
17580                broadcastIntentLocked(null, null, stoppingIntent,
17581                        null, stoppingReceiver, 0, null, null,
17582                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17583                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17584            } finally {
17585                Binder.restoreCallingIdentity(ident);
17586            }
17587        }
17588
17589        return ActivityManager.USER_OP_SUCCESS;
17590    }
17591
17592    void finishUserStop(UserStartedState uss) {
17593        final int userId = uss.mHandle.getIdentifier();
17594        boolean stopped;
17595        ArrayList<IStopUserCallback> callbacks;
17596        synchronized (this) {
17597            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17598            if (mStartedUsers.get(userId) != uss) {
17599                stopped = false;
17600            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17601                stopped = false;
17602            } else {
17603                stopped = true;
17604                // User can no longer run.
17605                mStartedUsers.remove(userId);
17606                mUserLru.remove(Integer.valueOf(userId));
17607                updateStartedUserArrayLocked();
17608
17609                // Clean up all state and processes associated with the user.
17610                // Kill all the processes for the user.
17611                forceStopUserLocked(userId, "finish user");
17612            }
17613        }
17614
17615        for (int i=0; i<callbacks.size(); i++) {
17616            try {
17617                if (stopped) callbacks.get(i).userStopped(userId);
17618                else callbacks.get(i).userStopAborted(userId);
17619            } catch (RemoteException e) {
17620            }
17621        }
17622
17623        if (stopped) {
17624            mSystemServiceManager.cleanupUser(userId);
17625            synchronized (this) {
17626                mStackSupervisor.removeUserLocked(userId);
17627            }
17628        }
17629    }
17630
17631    @Override
17632    public UserInfo getCurrentUser() {
17633        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17634                != PackageManager.PERMISSION_GRANTED) && (
17635                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17636                != PackageManager.PERMISSION_GRANTED)) {
17637            String msg = "Permission Denial: getCurrentUser() from pid="
17638                    + Binder.getCallingPid()
17639                    + ", uid=" + Binder.getCallingUid()
17640                    + " requires " + INTERACT_ACROSS_USERS;
17641            Slog.w(TAG, msg);
17642            throw new SecurityException(msg);
17643        }
17644        synchronized (this) {
17645            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17646        }
17647    }
17648
17649    int getCurrentUserIdLocked() {
17650        return mCurrentUserId;
17651    }
17652
17653    @Override
17654    public boolean isUserRunning(int userId, boolean orStopped) {
17655        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17656                != PackageManager.PERMISSION_GRANTED) {
17657            String msg = "Permission Denial: isUserRunning() 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 isUserRunningLocked(userId, orStopped);
17666        }
17667    }
17668
17669    boolean isUserRunningLocked(int userId, boolean orStopped) {
17670        UserStartedState state = mStartedUsers.get(userId);
17671        if (state == null) {
17672            return false;
17673        }
17674        if (orStopped) {
17675            return true;
17676        }
17677        return state.mState != UserStartedState.STATE_STOPPING
17678                && state.mState != UserStartedState.STATE_SHUTDOWN;
17679    }
17680
17681    @Override
17682    public int[] getRunningUserIds() {
17683        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17684                != PackageManager.PERMISSION_GRANTED) {
17685            String msg = "Permission Denial: isUserRunning() from pid="
17686                    + Binder.getCallingPid()
17687                    + ", uid=" + Binder.getCallingUid()
17688                    + " requires " + INTERACT_ACROSS_USERS;
17689            Slog.w(TAG, msg);
17690            throw new SecurityException(msg);
17691        }
17692        synchronized (this) {
17693            return mStartedUserArray;
17694        }
17695    }
17696
17697    private void updateStartedUserArrayLocked() {
17698        int num = 0;
17699        for (int i=0; i<mStartedUsers.size();  i++) {
17700            UserStartedState uss = mStartedUsers.valueAt(i);
17701            // This list does not include stopping users.
17702            if (uss.mState != UserStartedState.STATE_STOPPING
17703                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17704                num++;
17705            }
17706        }
17707        mStartedUserArray = new int[num];
17708        num = 0;
17709        for (int i=0; i<mStartedUsers.size();  i++) {
17710            UserStartedState uss = mStartedUsers.valueAt(i);
17711            if (uss.mState != UserStartedState.STATE_STOPPING
17712                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17713                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17714                num++;
17715            }
17716        }
17717    }
17718
17719    @Override
17720    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17721        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17722                != PackageManager.PERMISSION_GRANTED) {
17723            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17724                    + Binder.getCallingPid()
17725                    + ", uid=" + Binder.getCallingUid()
17726                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17727            Slog.w(TAG, msg);
17728            throw new SecurityException(msg);
17729        }
17730
17731        mUserSwitchObservers.register(observer);
17732    }
17733
17734    @Override
17735    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17736        mUserSwitchObservers.unregister(observer);
17737    }
17738
17739    private boolean userExists(int userId) {
17740        if (userId == 0) {
17741            return true;
17742        }
17743        UserManagerService ums = getUserManagerLocked();
17744        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17745    }
17746
17747    int[] getUsersLocked() {
17748        UserManagerService ums = getUserManagerLocked();
17749        return ums != null ? ums.getUserIds() : new int[] { 0 };
17750    }
17751
17752    UserManagerService getUserManagerLocked() {
17753        if (mUserManager == null) {
17754            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17755            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17756        }
17757        return mUserManager;
17758    }
17759
17760    private int applyUserId(int uid, int userId) {
17761        return UserHandle.getUid(userId, uid);
17762    }
17763
17764    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17765        if (info == null) return null;
17766        ApplicationInfo newInfo = new ApplicationInfo(info);
17767        newInfo.uid = applyUserId(info.uid, userId);
17768        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17769                + info.packageName;
17770        return newInfo;
17771    }
17772
17773    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17774        if (aInfo == null
17775                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17776            return aInfo;
17777        }
17778
17779        ActivityInfo info = new ActivityInfo(aInfo);
17780        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17781        return info;
17782    }
17783
17784    private final class LocalService extends ActivityManagerInternal {
17785        @Override
17786        public void goingToSleep() {
17787            ActivityManagerService.this.goingToSleep();
17788        }
17789
17790        @Override
17791        public void wakingUp() {
17792            ActivityManagerService.this.wakingUp();
17793        }
17794    }
17795
17796    /**
17797     * An implementation of IAppTask, that allows an app to manage its own tasks via
17798     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17799     * only the process that calls getAppTasks() can call the AppTask methods.
17800     */
17801    class AppTaskImpl extends IAppTask.Stub {
17802        private int mTaskId;
17803        private int mCallingUid;
17804
17805        public AppTaskImpl(int taskId, int callingUid) {
17806            mTaskId = taskId;
17807            mCallingUid = callingUid;
17808        }
17809
17810        @Override
17811        public void finishAndRemoveTask() {
17812            // Ensure that we are called from the same process that created this AppTask
17813            if (mCallingUid != Binder.getCallingUid()) {
17814                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17815                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17816                return;
17817            }
17818
17819            synchronized (ActivityManagerService.this) {
17820                long origId = Binder.clearCallingIdentity();
17821                try {
17822                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17823                    if (tr != null) {
17824                        // Only kill the process if we are not a new document
17825                        int flags = tr.getBaseIntent().getFlags();
17826                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17827                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17828                        removeTaskByIdLocked(mTaskId,
17829                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17830                    }
17831                } finally {
17832                    Binder.restoreCallingIdentity(origId);
17833                }
17834            }
17835        }
17836
17837        @Override
17838        public ActivityManager.RecentTaskInfo getTaskInfo() {
17839            // Ensure that we are called from the same process that created this AppTask
17840            if (mCallingUid != Binder.getCallingUid()) {
17841                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17842                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17843                return null;
17844            }
17845
17846            synchronized (ActivityManagerService.this) {
17847                long origId = Binder.clearCallingIdentity();
17848                try {
17849                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17850                    if (tr != null) {
17851                        return createRecentTaskInfoFromTaskRecord(tr);
17852                    }
17853                } finally {
17854                    Binder.restoreCallingIdentity(origId);
17855                }
17856                return null;
17857            }
17858        }
17859    }
17860}
17861