ActivityManagerService.java revision 648c83b4ee5fe825aa4032e0bb32c1d6269b02ad
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.Manifest;
32import android.app.AppOpsManager;
33import android.app.IActivityContainer;
34import android.app.IActivityContainerCallback;
35import android.appwidget.AppWidgetManager;
36import android.graphics.Rect;
37import android.os.BatteryStats;
38import android.service.voice.IVoiceInteractionSession;
39import android.util.ArrayMap;
40
41import com.android.internal.R;
42import com.android.internal.annotations.GuardedBy;
43import com.android.internal.app.IAppOpsService;
44import com.android.internal.app.IVoiceInteractor;
45import com.android.internal.app.ProcessMap;
46import com.android.internal.app.ProcessStats;
47import com.android.internal.content.PackageMonitor;
48import com.android.internal.os.BackgroundThread;
49import com.android.internal.os.BatteryStatsImpl;
50import com.android.internal.os.ProcessCpuTracker;
51import com.android.internal.os.TransferPipe;
52import com.android.internal.os.Zygote;
53import com.android.internal.util.FastPrintWriter;
54import com.android.internal.util.FastXmlSerializer;
55import com.android.internal.util.MemInfoReader;
56import com.android.internal.util.Preconditions;
57import com.android.server.AppOpsService;
58import com.android.server.AttributeCache;
59import com.android.server.IntentResolver;
60import com.android.server.LocalServices;
61import com.android.server.ServiceThread;
62import com.android.server.SystemService;
63import com.android.server.SystemServiceManager;
64import com.android.server.Watchdog;
65import com.android.server.am.ActivityStack.ActivityState;
66import com.android.server.firewall.IntentFirewall;
67import com.android.server.pm.UserManagerService;
68import com.android.server.wm.AppTransition;
69import com.android.server.wm.WindowManagerService;
70import com.google.android.collect.Lists;
71import com.google.android.collect.Maps;
72
73import libcore.io.IoUtils;
74
75import org.xmlpull.v1.XmlPullParser;
76import org.xmlpull.v1.XmlPullParserException;
77import org.xmlpull.v1.XmlSerializer;
78
79import android.app.Activity;
80import android.app.ActivityManager;
81import android.app.ActivityManager.RunningTaskInfo;
82import android.app.ActivityManager.StackInfo;
83import android.app.ActivityManagerInternal;
84import android.app.ActivityManagerNative;
85import android.app.ActivityOptions;
86import android.app.ActivityThread;
87import android.app.AlertDialog;
88import android.app.AppGlobals;
89import android.app.ApplicationErrorReport;
90import android.app.Dialog;
91import android.app.IActivityController;
92import android.app.IApplicationThread;
93import android.app.IInstrumentationWatcher;
94import android.app.INotificationManager;
95import android.app.IProcessObserver;
96import android.app.IServiceConnection;
97import android.app.IStopUserCallback;
98import android.app.IThumbnailReceiver;
99import android.app.IUiAutomationConnection;
100import android.app.IUserSwitchObserver;
101import android.app.Instrumentation;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.backup.IBackupManager;
106import android.content.ActivityNotFoundException;
107import android.content.BroadcastReceiver;
108import android.content.ClipData;
109import android.content.ComponentCallbacks2;
110import android.content.ComponentName;
111import android.content.ContentProvider;
112import android.content.ContentResolver;
113import android.content.Context;
114import android.content.DialogInterface;
115import android.content.IContentProvider;
116import android.content.IIntentReceiver;
117import android.content.IIntentSender;
118import android.content.Intent;
119import android.content.IntentFilter;
120import android.content.IntentSender;
121import android.content.pm.ActivityInfo;
122import android.content.pm.ApplicationInfo;
123import android.content.pm.ConfigurationInfo;
124import android.content.pm.IPackageDataObserver;
125import android.content.pm.IPackageManager;
126import android.content.pm.InstrumentationInfo;
127import android.content.pm.PackageInfo;
128import android.content.pm.PackageManager;
129import android.content.pm.ParceledListSlice;
130import android.content.pm.UserInfo;
131import android.content.pm.PackageManager.NameNotFoundException;
132import android.content.pm.PathPermission;
133import android.content.pm.ProviderInfo;
134import android.content.pm.ResolveInfo;
135import android.content.pm.ServiceInfo;
136import android.content.res.CompatibilityInfo;
137import android.content.res.Configuration;
138import android.graphics.Bitmap;
139import android.net.Proxy;
140import android.net.ProxyProperties;
141import android.net.Uri;
142import android.os.Binder;
143import android.os.Build;
144import android.os.Bundle;
145import android.os.Debug;
146import android.os.DropBoxManager;
147import android.os.Environment;
148import android.os.FactoryTest;
149import android.os.FileObserver;
150import android.os.FileUtils;
151import android.os.Handler;
152import android.os.IBinder;
153import android.os.IPermissionController;
154import android.os.IRemoteCallback;
155import android.os.IUserManager;
156import android.os.Looper;
157import android.os.Message;
158import android.os.Parcel;
159import android.os.ParcelFileDescriptor;
160import android.os.Process;
161import android.os.RemoteCallbackList;
162import android.os.RemoteException;
163import android.os.SELinux;
164import android.os.ServiceManager;
165import android.os.StrictMode;
166import android.os.SystemClock;
167import android.os.SystemProperties;
168import android.os.UpdateLock;
169import android.os.UserHandle;
170import android.provider.Settings;
171import android.text.format.DateUtils;
172import android.text.format.Time;
173import android.util.AtomicFile;
174import android.util.EventLog;
175import android.util.Log;
176import android.util.Pair;
177import android.util.PrintWriterPrinter;
178import android.util.Slog;
179import android.util.SparseArray;
180import android.util.TimeUtils;
181import android.util.Xml;
182import android.view.Gravity;
183import android.view.LayoutInflater;
184import android.view.View;
185import android.view.WindowManager;
186
187import java.io.BufferedInputStream;
188import java.io.BufferedOutputStream;
189import java.io.DataInputStream;
190import java.io.DataOutputStream;
191import java.io.File;
192import java.io.FileDescriptor;
193import java.io.FileInputStream;
194import java.io.FileNotFoundException;
195import java.io.FileOutputStream;
196import java.io.IOException;
197import java.io.InputStreamReader;
198import java.io.PrintWriter;
199import java.io.StringWriter;
200import java.lang.ref.WeakReference;
201import java.util.ArrayList;
202import java.util.Arrays;
203import java.util.Collections;
204import java.util.Comparator;
205import java.util.HashMap;
206import java.util.HashSet;
207import java.util.Iterator;
208import java.util.List;
209import java.util.Locale;
210import java.util.Map;
211import java.util.Set;
212import java.util.concurrent.atomic.AtomicBoolean;
213import java.util.concurrent.atomic.AtomicLong;
214
215public final class ActivityManagerService extends ActivityManagerNative
216        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
217    private static final String USER_DATA_DIR = "/data/user/";
218    static final String TAG = "ActivityManager";
219    static final String TAG_MU = "ActivityManagerServiceMU";
220    static final boolean DEBUG = false;
221    static final boolean localLOGV = DEBUG;
222    static final boolean DEBUG_BACKUP = localLOGV || false;
223    static final boolean DEBUG_BROADCAST = localLOGV || false;
224    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
225    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
226    static final boolean DEBUG_CLEANUP = localLOGV || false;
227    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
228    static final boolean DEBUG_FOCUS = false;
229    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
230    static final boolean DEBUG_MU = localLOGV || false;
231    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
232    static final boolean DEBUG_LRU = localLOGV || false;
233    static final boolean DEBUG_PAUSE = localLOGV || false;
234    static final boolean DEBUG_POWER = localLOGV || false;
235    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
236    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
237    static final boolean DEBUG_PROCESSES = localLOGV || false;
238    static final boolean DEBUG_PROVIDER = localLOGV || false;
239    static final boolean DEBUG_RESULTS = localLOGV || false;
240    static final boolean DEBUG_SERVICE = localLOGV || false;
241    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
242    static final boolean DEBUG_STACK = localLOGV || false;
243    static final boolean DEBUG_SWITCH = localLOGV || false;
244    static final boolean DEBUG_TASKS = localLOGV || false;
245    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
246    static final boolean DEBUG_TRANSITION = localLOGV || false;
247    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
248    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
249    static final boolean DEBUG_VISBILITY = localLOGV || false;
250    static final boolean DEBUG_PSS = localLOGV || false;
251    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
252    static final boolean VALIDATE_TOKENS = false;
253    static final boolean SHOW_ACTIVITY_START_TIME = true;
254
255    // Control over CPU and battery monitoring.
256    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
257    static final boolean MONITOR_CPU_USAGE = true;
258    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
259    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
260    static final boolean MONITOR_THREAD_CPU_USAGE = false;
261
262    // The flags that are set for all calls we make to the package manager.
263    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
264
265    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
266
267    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
268
269    // Maximum number of recent tasks that we can remember.
270    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
271
272    // Amount of time after a call to stopAppSwitches() during which we will
273    // prevent further untrusted switches from happening.
274    static final long APP_SWITCH_DELAY_TIME = 5*1000;
275
276    // How long we wait for a launched process to attach to the activity manager
277    // before we decide it's never going to come up for real.
278    static final int PROC_START_TIMEOUT = 10*1000;
279
280    // How long we wait for a launched process to attach to the activity manager
281    // before we decide it's never going to come up for real, when the process was
282    // started with a wrapper for instrumentation (such as Valgrind) because it
283    // could take much longer than usual.
284    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
285
286    // How long to wait after going idle before forcing apps to GC.
287    static final int GC_TIMEOUT = 5*1000;
288
289    // The minimum amount of time between successive GC requests for a process.
290    static final int GC_MIN_INTERVAL = 60*1000;
291
292    // The minimum amount of time between successive PSS requests for a process.
293    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process
296    // when the request is due to the memory state being lowered.
297    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
298
299    // The rate at which we check for apps using excessive power -- 15 mins.
300    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
301
302    // The minimum sample duration we will allow before deciding we have
303    // enough data on wake locks to start killing things.
304    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
305
306    // The minimum sample duration we will allow before deciding we have
307    // enough data on CPU usage to start killing things.
308    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
309
310    // How long we allow a receiver to run before giving up on it.
311    static final int BROADCAST_FG_TIMEOUT = 10*1000;
312    static final int BROADCAST_BG_TIMEOUT = 60*1000;
313
314    // How long we wait until we timeout on key dispatching.
315    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
316
317    // How long we wait until we timeout on key dispatching during instrumentation.
318    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
319
320    // Amount of time we wait for observers to handle a user switch before
321    // giving up on them and unfreezing the screen.
322    static final int USER_SWITCH_TIMEOUT = 2*1000;
323
324    // Maximum number of users we allow to be running at a time.
325    static final int MAX_RUNNING_USERS = 3;
326
327    // How long to wait in getAssistContextExtras for the activity and foreground services
328    // to respond with the result.
329    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
330
331    // Maximum number of persisted Uri grants a package is allowed
332    static final int MAX_PERSISTED_URI_GRANTS = 128;
333
334    static final int MY_PID = Process.myPid();
335
336    static final String[] EMPTY_STRING_ARRAY = new String[0];
337
338    // How many bytes to write into the dropbox log before truncating
339    static final int DROPBOX_MAX_SIZE = 256 * 1024;
340
341    /** All system services */
342    SystemServiceManager mSystemServiceManager;
343
344    /** Run all ActivityStacks through this */
345    ActivityStackSupervisor mStackSupervisor;
346
347    public IntentFirewall mIntentFirewall;
348
349    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
350    // default actuion automatically.  Important for devices without direct input
351    // devices.
352    private boolean mShowDialogs = true;
353
354    /**
355     * Description of a request to start a new activity, which has been held
356     * due to app switches being disabled.
357     */
358    static class PendingActivityLaunch {
359        final ActivityRecord r;
360        final ActivityRecord sourceRecord;
361        final int startFlags;
362        final ActivityStack stack;
363
364        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
365                int _startFlags, ActivityStack _stack) {
366            r = _r;
367            sourceRecord = _sourceRecord;
368            startFlags = _startFlags;
369            stack = _stack;
370        }
371    }
372
373    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
374            = new ArrayList<PendingActivityLaunch>();
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    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
411
412    public class PendingAssistExtras extends Binder implements Runnable {
413        public final ActivityRecord activity;
414        public boolean haveResult = false;
415        public Bundle result = null;
416        public PendingAssistExtras(ActivityRecord _activity) {
417            activity = _activity;
418        }
419        @Override
420        public void run() {
421            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
422            synchronized (this) {
423                haveResult = true;
424                notifyAll();
425            }
426        }
427    }
428
429    final ArrayList<PendingAssistExtras> mPendingAssistExtras
430            = new ArrayList<PendingAssistExtras>();
431
432    /**
433     * Process management.
434     */
435    final ProcessList mProcessList = new ProcessList();
436
437    /**
438     * All of the applications we currently have running organized by name.
439     * The keys are strings of the application package name (as
440     * returned by the package manager), and the keys are ApplicationRecord
441     * objects.
442     */
443    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
444
445    /**
446     * Tracking long-term execution of processes to look for abuse and other
447     * bad app behavior.
448     */
449    final ProcessStatsService mProcessStats;
450
451    /**
452     * The currently running isolated processes.
453     */
454    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
455
456    /**
457     * Counter for assigning isolated process uids, to avoid frequently reusing the
458     * same ones.
459     */
460    int mNextIsolatedProcessUid = 0;
461
462    /**
463     * The currently running heavy-weight process, if any.
464     */
465    ProcessRecord mHeavyWeightProcess = null;
466
467    /**
468     * The last time that various processes have crashed.
469     */
470    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
471
472    /**
473     * Information about a process that is currently marked as bad.
474     */
475    static final class BadProcessInfo {
476        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
477            this.time = time;
478            this.shortMsg = shortMsg;
479            this.longMsg = longMsg;
480            this.stack = stack;
481        }
482
483        final long time;
484        final String shortMsg;
485        final String longMsg;
486        final String stack;
487    }
488
489    /**
490     * Set of applications that we consider to be bad, and will reject
491     * incoming broadcasts from (which the user has no control over).
492     * Processes are added to this set when they have crashed twice within
493     * a minimum amount of time; they are removed from it when they are
494     * later restarted (hopefully due to some user action).  The value is the
495     * time it was added to the list.
496     */
497    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
498
499    /**
500     * All of the processes we currently have running organized by pid.
501     * The keys are the pid running the application.
502     *
503     * <p>NOTE: This object is protected by its own lock, NOT the global
504     * activity manager lock!
505     */
506    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
507
508    /**
509     * All of the processes that have been forced to be foreground.  The key
510     * is the pid of the caller who requested it (we hold a death
511     * link on it).
512     */
513    abstract class ForegroundToken implements IBinder.DeathRecipient {
514        int pid;
515        IBinder token;
516    }
517    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
518
519    /**
520     * List of records for processes that someone had tried to start before the
521     * system was ready.  We don't start them at that point, but ensure they
522     * are started by the time booting is complete.
523     */
524    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of persistent applications that are in the process
528     * of being started.
529     */
530    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Processes that are being forcibly torn down.
534     */
535    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
536
537    /**
538     * List of running applications, sorted by recent usage.
539     * The first entry in the list is the least recently used.
540     */
541    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * Where in mLruProcesses that the processes hosting activities start.
545     */
546    int mLruProcessActivityStart = 0;
547
548    /**
549     * Where in mLruProcesses that the processes hosting services start.
550     * This is after (lower index) than mLruProcessesActivityStart.
551     */
552    int mLruProcessServiceStart = 0;
553
554    /**
555     * List of processes that should gc as soon as things are idle.
556     */
557    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
558
559    /**
560     * Processes we want to collect PSS data from.
561     */
562    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Last time we requested PSS data of all processes.
566     */
567    long mLastFullPssTime = SystemClock.uptimeMillis();
568
569    /**
570     * This is the process holding what we currently consider to be
571     * the "home" activity.
572     */
573    ProcessRecord mHomeProcess;
574
575    /**
576     * This is the process holding the activity the user last visited that
577     * is in a different process from the one they are currently in.
578     */
579    ProcessRecord mPreviousProcess;
580
581    /**
582     * The time at which the previous process was last visible.
583     */
584    long mPreviousProcessVisibleTime;
585
586    /**
587     * Which uses have been started, so are allowed to run code.
588     */
589    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
590
591    /**
592     * LRU list of history of current users.  Most recently current is at the end.
593     */
594    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
595
596    /**
597     * Constant array of the users that are currently started.
598     */
599    int[] mStartedUserArray = new int[] { 0 };
600
601    /**
602     * Registered observers of the user switching mechanics.
603     */
604    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
605            = new RemoteCallbackList<IUserSwitchObserver>();
606
607    /**
608     * Currently active user switch.
609     */
610    Object mCurUserSwitchCallback;
611
612    /**
613     * Packages that the user has asked to have run in screen size
614     * compatibility mode instead of filling the screen.
615     */
616    final CompatModePackages mCompatModePackages;
617
618    /**
619     * Set of IntentSenderRecord objects that are currently active.
620     */
621    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
622            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
623
624    /**
625     * Fingerprints (hashCode()) of stack traces that we've
626     * already logged DropBox entries for.  Guarded by itself.  If
627     * something (rogue user app) forces this over
628     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
629     */
630    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
631    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
632
633    /**
634     * Strict Mode background batched logging state.
635     *
636     * The string buffer is guarded by itself, and its lock is also
637     * used to determine if another batched write is already
638     * in-flight.
639     */
640    private final StringBuilder mStrictModeBuffer = new StringBuilder();
641
642    /**
643     * Keeps track of all IIntentReceivers that have been registered for
644     * broadcasts.  Hash keys are the receiver IBinder, hash value is
645     * a ReceiverList.
646     */
647    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
648            new HashMap<IBinder, ReceiverList>();
649
650    /**
651     * Resolver for broadcast intents to registered receivers.
652     * Holds BroadcastFilter (subclass of IntentFilter).
653     */
654    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
655            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
656        @Override
657        protected boolean allowFilterResult(
658                BroadcastFilter filter, List<BroadcastFilter> dest) {
659            IBinder target = filter.receiverList.receiver.asBinder();
660            for (int i=dest.size()-1; i>=0; i--) {
661                if (dest.get(i).receiverList.receiver.asBinder() == target) {
662                    return false;
663                }
664            }
665            return true;
666        }
667
668        @Override
669        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
670            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
671                    || userId == filter.owningUserId) {
672                return super.newResult(filter, match, userId);
673            }
674            return null;
675        }
676
677        @Override
678        protected BroadcastFilter[] newArray(int size) {
679            return new BroadcastFilter[size];
680        }
681
682        @Override
683        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
684            return packageName.equals(filter.packageName);
685        }
686    };
687
688    /**
689     * State of all active sticky broadcasts per user.  Keys are the action of the
690     * sticky Intent, values are an ArrayList of all broadcasted intents with
691     * that action (which should usually be one).  The SparseArray is keyed
692     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
693     * for stickies that are sent to all users.
694     */
695    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
696            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
697
698    final ActiveServices mServices;
699
700    /**
701     * Backup/restore process management
702     */
703    String mBackupAppName = null;
704    BackupRecord mBackupTarget = null;
705
706    /**
707     * List of PendingThumbnailsRecord objects of clients who are still
708     * waiting to receive all of the thumbnails for a task.
709     */
710    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
711            new ArrayList<PendingThumbnailsRecord>();
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_PKG = "sourcePkg";
733    private static final String ATTR_TARGET_PKG = "targetPkg";
734    private static final String ATTR_URI = "uri";
735    private static final String ATTR_MODE_FLAGS = "modeFlags";
736    private static final String ATTR_CREATED_TIME = "createdTime";
737    private static final String ATTR_PREFIX = "prefix";
738
739    /**
740     * Global set of specific {@link Uri} permissions that have been granted.
741     * This optimized lookup structure maps from {@link UriPermission#targetUid}
742     * to {@link UriPermission#uri} to {@link UriPermission}.
743     */
744    @GuardedBy("this")
745    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
746            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
747
748    public static class GrantUri {
749        public final Uri uri;
750        public final boolean prefix;
751
752        public GrantUri(Uri uri, boolean prefix) {
753            this.uri = uri;
754            this.prefix = prefix;
755        }
756
757        @Override
758        public int hashCode() {
759            return toString().hashCode();
760        }
761
762        @Override
763        public boolean equals(Object o) {
764            if (o instanceof GrantUri) {
765                GrantUri other = (GrantUri) o;
766                return uri.equals(other.uri) && prefix == other.prefix;
767            }
768            return false;
769        }
770
771        @Override
772        public String toString() {
773            if (prefix) {
774                return uri.toString() + " [prefix]";
775            } else {
776                return uri.toString();
777            }
778        }
779    }
780
781    CoreSettingsObserver mCoreSettingsObserver;
782
783    /**
784     * Thread-local storage used to carry caller permissions over through
785     * indirect content-provider access.
786     */
787    private class Identity {
788        public int pid;
789        public int uid;
790
791        Identity(int _pid, int _uid) {
792            pid = _pid;
793            uid = _uid;
794        }
795    }
796
797    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
798
799    /**
800     * All information we have collected about the runtime performance of
801     * any user id that can impact battery performance.
802     */
803    final BatteryStatsService mBatteryStatsService;
804
805    /**
806     * Information about component usage
807     */
808    final UsageStatsService mUsageStatsService;
809
810    /**
811     * Information about and control over application operations
812     */
813    final AppOpsService mAppOpsService;
814
815    /**
816     * Current configuration information.  HistoryRecord objects are given
817     * a reference to this object to indicate which configuration they are
818     * currently running in, so this object must be kept immutable.
819     */
820    Configuration mConfiguration = new Configuration();
821
822    /**
823     * Current sequencing integer of the configuration, for skipping old
824     * configurations.
825     */
826    int mConfigurationSeq = 0;
827
828    /**
829     * Hardware-reported OpenGLES version.
830     */
831    final int GL_ES_VERSION;
832
833    /**
834     * List of initialization arguments to pass to all processes when binding applications to them.
835     * For example, references to the commonly used services.
836     */
837    HashMap<String, IBinder> mAppBindArgs;
838
839    /**
840     * Temporary to avoid allocations.  Protected by main lock.
841     */
842    final StringBuilder mStringBuilder = new StringBuilder(256);
843
844    /**
845     * Used to control how we initialize the service.
846     */
847    ComponentName mTopComponent;
848    String mTopAction = Intent.ACTION_MAIN;
849    String mTopData;
850    boolean mProcessesReady = false;
851    boolean mSystemReady = false;
852    boolean mBooting = false;
853    boolean mWaitingUpdate = false;
854    boolean mDidUpdate = false;
855    boolean mOnBattery = false;
856    boolean mLaunchWarningShown = false;
857
858    Context mContext;
859
860    int mFactoryTest;
861
862    boolean mCheckedForSetup;
863
864    /**
865     * The time at which we will allow normal application switches again,
866     * after a call to {@link #stopAppSwitches()}.
867     */
868    long mAppSwitchesAllowedTime;
869
870    /**
871     * This is set to true after the first switch after mAppSwitchesAllowedTime
872     * is set; any switches after that will clear the time.
873     */
874    boolean mDidAppSwitch;
875
876    /**
877     * Last time (in realtime) at which we checked for power usage.
878     */
879    long mLastPowerCheckRealtime;
880
881    /**
882     * Last time (in uptime) at which we checked for power usage.
883     */
884    long mLastPowerCheckUptime;
885
886    /**
887     * Set while we are wanting to sleep, to prevent any
888     * activities from being started/resumed.
889     */
890    private boolean mSleeping = false;
891
892    /**
893     * Set while we are running a voice interaction.  This overrides
894     * sleeping while it is active.
895     */
896    private boolean mRunningVoice = false;
897
898    /**
899     * State of external calls telling us if the device is asleep.
900     */
901    private boolean mWentToSleep = false;
902
903    /**
904     * State of external call telling us if the lock screen is shown.
905     */
906    private boolean mLockScreenShown = false;
907
908    /**
909     * Set if we are shutting down the system, similar to sleeping.
910     */
911    boolean mShuttingDown = false;
912
913    /**
914     * Current sequence id for oom_adj computation traversal.
915     */
916    int mAdjSeq = 0;
917
918    /**
919     * Current sequence id for process LRU updating.
920     */
921    int mLruSeq = 0;
922
923    /**
924     * Keep track of the non-cached/empty process we last found, to help
925     * determine how to distribute cached/empty processes next time.
926     */
927    int mNumNonCachedProcs = 0;
928
929    /**
930     * Keep track of the number of cached hidden procs, to balance oom adj
931     * distribution between those and empty procs.
932     */
933    int mNumCachedHiddenProcs = 0;
934
935    /**
936     * Keep track of the number of service processes we last found, to
937     * determine on the next iteration which should be B services.
938     */
939    int mNumServiceProcs = 0;
940    int mNewNumAServiceProcs = 0;
941    int mNewNumServiceProcs = 0;
942
943    /**
944     * Allow the current computed overall memory level of the system to go down?
945     * This is set to false when we are killing processes for reasons other than
946     * memory management, so that the now smaller process list will not be taken as
947     * an indication that memory is tighter.
948     */
949    boolean mAllowLowerMemLevel = false;
950
951    /**
952     * The last computed memory level, for holding when we are in a state that
953     * processes are going away for other reasons.
954     */
955    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
956
957    /**
958     * The last total number of process we have, to determine if changes actually look
959     * like a shrinking number of process due to lower RAM.
960     */
961    int mLastNumProcesses;
962
963    /**
964     * The uptime of the last time we performed idle maintenance.
965     */
966    long mLastIdleTime = SystemClock.uptimeMillis();
967
968    /**
969     * Total time spent with RAM that has been added in the past since the last idle time.
970     */
971    long mLowRamTimeSinceLastIdle = 0;
972
973    /**
974     * If RAM is currently low, when that horrible situation started.
975     */
976    long mLowRamStartTime = 0;
977
978    /**
979     * For reporting to battery stats the current top application.
980     */
981    private String mCurResumedPackage = null;
982    private int mCurResumedUid = -1;
983
984    /**
985     * For reporting to battery stats the apps currently running foreground
986     * service.  The ProcessMap is package/uid tuples; each of these contain
987     * an array of the currently foreground processes.
988     */
989    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
990            = new ProcessMap<ArrayList<ProcessRecord>>();
991
992    /**
993     * This is set if we had to do a delayed dexopt of an app before launching
994     * it, to increasing the ANR timeouts in that case.
995     */
996    boolean mDidDexOpt;
997
998    /**
999     * Set if the systemServer made a call to enterSafeMode.
1000     */
1001    boolean mSafeMode;
1002
1003    String mDebugApp = null;
1004    boolean mWaitForDebugger = false;
1005    boolean mDebugTransient = false;
1006    String mOrigDebugApp = null;
1007    boolean mOrigWaitForDebugger = false;
1008    boolean mAlwaysFinishActivities = false;
1009    IActivityController mController = null;
1010    String mProfileApp = null;
1011    ProcessRecord mProfileProc = null;
1012    String mProfileFile;
1013    ParcelFileDescriptor mProfileFd;
1014    int mProfileType = 0;
1015    boolean mAutoStopProfiler = false;
1016    String mOpenGlTraceApp = null;
1017
1018    static class ProcessChangeItem {
1019        static final int CHANGE_ACTIVITIES = 1<<0;
1020        static final int CHANGE_IMPORTANCE= 1<<1;
1021        int changes;
1022        int uid;
1023        int pid;
1024        int importance;
1025        boolean foregroundActivities;
1026    }
1027
1028    final RemoteCallbackList<IProcessObserver> mProcessObservers
1029            = new RemoteCallbackList<IProcessObserver>();
1030    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1031
1032    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1033            = new ArrayList<ProcessChangeItem>();
1034    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1035            = new ArrayList<ProcessChangeItem>();
1036
1037    /**
1038     * Runtime CPU use collection thread.  This object's lock is used to
1039     * protect all related state.
1040     */
1041    final Thread mProcessCpuThread;
1042
1043    /**
1044     * Used to collect process stats when showing not responding dialog.
1045     * Protected by mProcessCpuThread.
1046     */
1047    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1048            MONITOR_THREAD_CPU_USAGE);
1049    final AtomicLong mLastCpuTime = new AtomicLong(0);
1050    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1051
1052    long mLastWriteTime = 0;
1053
1054    /**
1055     * Used to retain an update lock when the foreground activity is in
1056     * immersive mode.
1057     */
1058    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1059
1060    /**
1061     * Set to true after the system has finished booting.
1062     */
1063    boolean mBooted = false;
1064
1065    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1066    int mProcessLimitOverride = -1;
1067
1068    WindowManagerService mWindowManager;
1069
1070    final ActivityThread mSystemThread;
1071
1072    int mCurrentUserId = 0;
1073    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1074    private UserManagerService mUserManager;
1075
1076    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1077        final ProcessRecord mApp;
1078        final int mPid;
1079        final IApplicationThread mAppThread;
1080
1081        AppDeathRecipient(ProcessRecord app, int pid,
1082                IApplicationThread thread) {
1083            if (localLOGV) Slog.v(
1084                TAG, "New death recipient " + this
1085                + " for thread " + thread.asBinder());
1086            mApp = app;
1087            mPid = pid;
1088            mAppThread = thread;
1089        }
1090
1091        @Override
1092        public void binderDied() {
1093            if (localLOGV) Slog.v(
1094                TAG, "Death received in " + this
1095                + " for thread " + mAppThread.asBinder());
1096            synchronized(ActivityManagerService.this) {
1097                appDiedLocked(mApp, mPid, mAppThread);
1098            }
1099        }
1100    }
1101
1102    static final int SHOW_ERROR_MSG = 1;
1103    static final int SHOW_NOT_RESPONDING_MSG = 2;
1104    static final int SHOW_FACTORY_ERROR_MSG = 3;
1105    static final int UPDATE_CONFIGURATION_MSG = 4;
1106    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1107    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1108    static final int SERVICE_TIMEOUT_MSG = 12;
1109    static final int UPDATE_TIME_ZONE = 13;
1110    static final int SHOW_UID_ERROR_MSG = 14;
1111    static final int IM_FEELING_LUCKY_MSG = 15;
1112    static final int PROC_START_TIMEOUT_MSG = 20;
1113    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1114    static final int KILL_APPLICATION_MSG = 22;
1115    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1116    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1117    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1118    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1119    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1120    static final int CLEAR_DNS_CACHE_MSG = 28;
1121    static final int UPDATE_HTTP_PROXY_MSG = 29;
1122    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1123    static final int DISPATCH_PROCESSES_CHANGED = 31;
1124    static final int DISPATCH_PROCESS_DIED = 32;
1125    static final int REPORT_MEM_USAGE_MSG = 33;
1126    static final int REPORT_USER_SWITCH_MSG = 34;
1127    static final int CONTINUE_USER_SWITCH_MSG = 35;
1128    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1129    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1130    static final int PERSIST_URI_GRANTS_MSG = 38;
1131    static final int REQUEST_ALL_PSS_MSG = 39;
1132    static final int START_PROFILES_MSG = 40;
1133    static final int UPDATE_TIME = 41;
1134    static final int SYSTEM_USER_START_MSG = 42;
1135    static final int SYSTEM_USER_CURRENT_MSG = 43;
1136
1137    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1138    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1139    static final int FIRST_COMPAT_MODE_MSG = 300;
1140    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1141
1142    AlertDialog mUidAlert;
1143    CompatModeDialog mCompatModeDialog;
1144    long mLastMemUsageReportTime = 0;
1145
1146    /**
1147     * Flag whether the current user is a "monkey", i.e. whether
1148     * the UI is driven by a UI automation tool.
1149     */
1150    private boolean mUserIsMonkey;
1151
1152    final ServiceThread mHandlerThread;
1153    final MainHandler mHandler;
1154
1155    final class MainHandler extends Handler {
1156        public MainHandler(Looper looper) {
1157            super(looper, null, true);
1158        }
1159
1160        @Override
1161        public void handleMessage(Message msg) {
1162            switch (msg.what) {
1163            case SHOW_ERROR_MSG: {
1164                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1165                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1166                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1167                synchronized (ActivityManagerService.this) {
1168                    ProcessRecord proc = (ProcessRecord)data.get("app");
1169                    AppErrorResult res = (AppErrorResult) data.get("result");
1170                    if (proc != null && proc.crashDialog != null) {
1171                        Slog.e(TAG, "App already has crash dialog: " + proc);
1172                        if (res != null) {
1173                            res.set(0);
1174                        }
1175                        return;
1176                    }
1177                    if (!showBackground && UserHandle.getAppId(proc.uid)
1178                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1179                            && proc.pid != MY_PID) {
1180                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1181                        if (res != null) {
1182                            res.set(0);
1183                        }
1184                        return;
1185                    }
1186                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1187                        Dialog d = new AppErrorDialog(mContext,
1188                                ActivityManagerService.this, res, proc);
1189                        d.show();
1190                        proc.crashDialog = d;
1191                    } else {
1192                        // The device is asleep, so just pretend that the user
1193                        // saw a crash dialog and hit "force quit".
1194                        if (res != null) {
1195                            res.set(0);
1196                        }
1197                    }
1198                }
1199
1200                ensureBootCompleted();
1201            } break;
1202            case SHOW_NOT_RESPONDING_MSG: {
1203                synchronized (ActivityManagerService.this) {
1204                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1205                    ProcessRecord proc = (ProcessRecord)data.get("app");
1206                    if (proc != null && proc.anrDialog != null) {
1207                        Slog.e(TAG, "App already has anr dialog: " + proc);
1208                        return;
1209                    }
1210
1211                    Intent intent = new Intent("android.intent.action.ANR");
1212                    if (!mProcessesReady) {
1213                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1214                                | Intent.FLAG_RECEIVER_FOREGROUND);
1215                    }
1216                    broadcastIntentLocked(null, null, intent,
1217                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1218                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1219
1220                    if (mShowDialogs) {
1221                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1222                                mContext, proc, (ActivityRecord)data.get("activity"),
1223                                msg.arg1 != 0);
1224                        d.show();
1225                        proc.anrDialog = d;
1226                    } else {
1227                        // Just kill the app if there is no dialog to be shown.
1228                        killAppAtUsersRequest(proc, null);
1229                    }
1230                }
1231
1232                ensureBootCompleted();
1233            } break;
1234            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1235                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                synchronized (ActivityManagerService.this) {
1237                    ProcessRecord proc = (ProcessRecord) data.get("app");
1238                    if (proc == null) {
1239                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1240                        break;
1241                    }
1242                    if (proc.crashDialog != null) {
1243                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1244                        return;
1245                    }
1246                    AppErrorResult res = (AppErrorResult) data.get("result");
1247                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1248                        Dialog d = new StrictModeViolationDialog(mContext,
1249                                ActivityManagerService.this, res, proc);
1250                        d.show();
1251                        proc.crashDialog = d;
1252                    } else {
1253                        // The device is asleep, so just pretend that the user
1254                        // saw a crash dialog and hit "force quit".
1255                        res.set(0);
1256                    }
1257                }
1258                ensureBootCompleted();
1259            } break;
1260            case SHOW_FACTORY_ERROR_MSG: {
1261                Dialog d = new FactoryErrorDialog(
1262                    mContext, msg.getData().getCharSequence("msg"));
1263                d.show();
1264                ensureBootCompleted();
1265            } break;
1266            case UPDATE_CONFIGURATION_MSG: {
1267                final ContentResolver resolver = mContext.getContentResolver();
1268                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1269            } break;
1270            case GC_BACKGROUND_PROCESSES_MSG: {
1271                synchronized (ActivityManagerService.this) {
1272                    performAppGcsIfAppropriateLocked();
1273                }
1274            } break;
1275            case WAIT_FOR_DEBUGGER_MSG: {
1276                synchronized (ActivityManagerService.this) {
1277                    ProcessRecord app = (ProcessRecord)msg.obj;
1278                    if (msg.arg1 != 0) {
1279                        if (!app.waitedForDebugger) {
1280                            Dialog d = new AppWaitingForDebuggerDialog(
1281                                    ActivityManagerService.this,
1282                                    mContext, app);
1283                            app.waitDialog = d;
1284                            app.waitedForDebugger = true;
1285                            d.show();
1286                        }
1287                    } else {
1288                        if (app.waitDialog != null) {
1289                            app.waitDialog.dismiss();
1290                            app.waitDialog = null;
1291                        }
1292                    }
1293                }
1294            } break;
1295            case SERVICE_TIMEOUT_MSG: {
1296                if (mDidDexOpt) {
1297                    mDidDexOpt = false;
1298                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1299                    nmsg.obj = msg.obj;
1300                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1301                    return;
1302                }
1303                mServices.serviceTimeout((ProcessRecord)msg.obj);
1304            } break;
1305            case UPDATE_TIME_ZONE: {
1306                synchronized (ActivityManagerService.this) {
1307                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1308                        ProcessRecord r = mLruProcesses.get(i);
1309                        if (r.thread != null) {
1310                            try {
1311                                r.thread.updateTimeZone();
1312                            } catch (RemoteException ex) {
1313                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1314                            }
1315                        }
1316                    }
1317                }
1318            } break;
1319            case CLEAR_DNS_CACHE_MSG: {
1320                synchronized (ActivityManagerService.this) {
1321                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1322                        ProcessRecord r = mLruProcesses.get(i);
1323                        if (r.thread != null) {
1324                            try {
1325                                r.thread.clearDnsCache();
1326                            } catch (RemoteException ex) {
1327                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1328                            }
1329                        }
1330                    }
1331                }
1332            } break;
1333            case UPDATE_HTTP_PROXY_MSG: {
1334                ProxyProperties proxy = (ProxyProperties)msg.obj;
1335                String host = "";
1336                String port = "";
1337                String exclList = "";
1338                String pacFileUrl = null;
1339                if (proxy != null) {
1340                    host = proxy.getHost();
1341                    port = Integer.toString(proxy.getPort());
1342                    exclList = proxy.getExclusionList();
1343                    pacFileUrl = proxy.getPacFileUrl();
1344                }
1345                synchronized (ActivityManagerService.this) {
1346                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1347                        ProcessRecord r = mLruProcesses.get(i);
1348                        if (r.thread != null) {
1349                            try {
1350                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1351                            } catch (RemoteException ex) {
1352                                Slog.w(TAG, "Failed to update http proxy for: " +
1353                                        r.info.processName);
1354                            }
1355                        }
1356                    }
1357                }
1358            } break;
1359            case SHOW_UID_ERROR_MSG: {
1360                String title = "System UIDs Inconsistent";
1361                String text = "UIDs on the system are inconsistent, you need to wipe your"
1362                        + " data partition or your device will be unstable.";
1363                Log.e(TAG, title + ": " + text);
1364                if (mShowDialogs) {
1365                    // XXX This is a temporary dialog, no need to localize.
1366                    AlertDialog d = new BaseErrorDialog(mContext);
1367                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1368                    d.setCancelable(false);
1369                    d.setTitle(title);
1370                    d.setMessage(text);
1371                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1372                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1373                    mUidAlert = d;
1374                    d.show();
1375                }
1376            } break;
1377            case IM_FEELING_LUCKY_MSG: {
1378                if (mUidAlert != null) {
1379                    mUidAlert.dismiss();
1380                    mUidAlert = null;
1381                }
1382            } break;
1383            case PROC_START_TIMEOUT_MSG: {
1384                if (mDidDexOpt) {
1385                    mDidDexOpt = false;
1386                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1387                    nmsg.obj = msg.obj;
1388                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1389                    return;
1390                }
1391                ProcessRecord app = (ProcessRecord)msg.obj;
1392                synchronized (ActivityManagerService.this) {
1393                    processStartTimedOutLocked(app);
1394                }
1395            } break;
1396            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1397                synchronized (ActivityManagerService.this) {
1398                    doPendingActivityLaunchesLocked(true);
1399                }
1400            } break;
1401            case KILL_APPLICATION_MSG: {
1402                synchronized (ActivityManagerService.this) {
1403                    int appid = msg.arg1;
1404                    boolean restart = (msg.arg2 == 1);
1405                    Bundle bundle = (Bundle)msg.obj;
1406                    String pkg = bundle.getString("pkg");
1407                    String reason = bundle.getString("reason");
1408                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1409                            false, UserHandle.USER_ALL, reason);
1410                }
1411            } break;
1412            case FINALIZE_PENDING_INTENT_MSG: {
1413                ((PendingIntentRecord)msg.obj).completeFinalize();
1414            } break;
1415            case POST_HEAVY_NOTIFICATION_MSG: {
1416                INotificationManager inm = NotificationManager.getService();
1417                if (inm == null) {
1418                    return;
1419                }
1420
1421                ActivityRecord root = (ActivityRecord)msg.obj;
1422                ProcessRecord process = root.app;
1423                if (process == null) {
1424                    return;
1425                }
1426
1427                try {
1428                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1429                    String text = mContext.getString(R.string.heavy_weight_notification,
1430                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1431                    Notification notification = new Notification();
1432                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1433                    notification.when = 0;
1434                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1435                    notification.tickerText = text;
1436                    notification.defaults = 0; // please be quiet
1437                    notification.sound = null;
1438                    notification.vibrate = null;
1439                    notification.setLatestEventInfo(context, text,
1440                            mContext.getText(R.string.heavy_weight_notification_detail),
1441                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1442                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1443                                    new UserHandle(root.userId)));
1444
1445                    try {
1446                        int[] outId = new int[1];
1447                        inm.enqueueNotificationWithTag("android", "android", null,
1448                                R.string.heavy_weight_notification,
1449                                notification, outId, root.userId);
1450                    } catch (RuntimeException e) {
1451                        Slog.w(ActivityManagerService.TAG,
1452                                "Error showing notification for heavy-weight app", e);
1453                    } catch (RemoteException e) {
1454                    }
1455                } catch (NameNotFoundException e) {
1456                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1457                }
1458            } break;
1459            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1460                INotificationManager inm = NotificationManager.getService();
1461                if (inm == null) {
1462                    return;
1463                }
1464                try {
1465                    inm.cancelNotificationWithTag("android", null,
1466                            R.string.heavy_weight_notification,  msg.arg1);
1467                } catch (RuntimeException e) {
1468                    Slog.w(ActivityManagerService.TAG,
1469                            "Error canceling notification for service", e);
1470                } catch (RemoteException e) {
1471                }
1472            } break;
1473            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1474                synchronized (ActivityManagerService.this) {
1475                    checkExcessivePowerUsageLocked(true);
1476                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1477                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1478                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1479                }
1480            } break;
1481            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1482                synchronized (ActivityManagerService.this) {
1483                    ActivityRecord ar = (ActivityRecord)msg.obj;
1484                    if (mCompatModeDialog != null) {
1485                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1486                                ar.info.applicationInfo.packageName)) {
1487                            return;
1488                        }
1489                        mCompatModeDialog.dismiss();
1490                        mCompatModeDialog = null;
1491                    }
1492                    if (ar != null && false) {
1493                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1494                                ar.packageName)) {
1495                            int mode = mCompatModePackages.computeCompatModeLocked(
1496                                    ar.info.applicationInfo);
1497                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1498                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1499                                mCompatModeDialog = new CompatModeDialog(
1500                                        ActivityManagerService.this, mContext,
1501                                        ar.info.applicationInfo);
1502                                mCompatModeDialog.show();
1503                            }
1504                        }
1505                    }
1506                }
1507                break;
1508            }
1509            case DISPATCH_PROCESSES_CHANGED: {
1510                dispatchProcessesChanged();
1511                break;
1512            }
1513            case DISPATCH_PROCESS_DIED: {
1514                final int pid = msg.arg1;
1515                final int uid = msg.arg2;
1516                dispatchProcessDied(pid, uid);
1517                break;
1518            }
1519            case REPORT_MEM_USAGE_MSG: {
1520                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1521                Thread thread = new Thread() {
1522                    @Override public void run() {
1523                        final SparseArray<ProcessMemInfo> infoMap
1524                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1525                        for (int i=0, N=memInfos.size(); i<N; i++) {
1526                            ProcessMemInfo mi = memInfos.get(i);
1527                            infoMap.put(mi.pid, mi);
1528                        }
1529                        updateCpuStatsNow();
1530                        synchronized (mProcessCpuThread) {
1531                            final int N = mProcessCpuTracker.countStats();
1532                            for (int i=0; i<N; i++) {
1533                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1534                                if (st.vsize > 0) {
1535                                    long pss = Debug.getPss(st.pid, null);
1536                                    if (pss > 0) {
1537                                        if (infoMap.indexOfKey(st.pid) < 0) {
1538                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1539                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1540                                            mi.pss = pss;
1541                                            memInfos.add(mi);
1542                                        }
1543                                    }
1544                                }
1545                            }
1546                        }
1547
1548                        long totalPss = 0;
1549                        for (int i=0, N=memInfos.size(); i<N; i++) {
1550                            ProcessMemInfo mi = memInfos.get(i);
1551                            if (mi.pss == 0) {
1552                                mi.pss = Debug.getPss(mi.pid, null);
1553                            }
1554                            totalPss += mi.pss;
1555                        }
1556                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1557                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1558                                if (lhs.oomAdj != rhs.oomAdj) {
1559                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1560                                }
1561                                if (lhs.pss != rhs.pss) {
1562                                    return lhs.pss < rhs.pss ? 1 : -1;
1563                                }
1564                                return 0;
1565                            }
1566                        });
1567
1568                        StringBuilder tag = new StringBuilder(128);
1569                        StringBuilder stack = new StringBuilder(128);
1570                        tag.append("Low on memory -- ");
1571                        appendMemBucket(tag, totalPss, "total", false);
1572                        appendMemBucket(stack, totalPss, "total", true);
1573
1574                        StringBuilder logBuilder = new StringBuilder(1024);
1575                        logBuilder.append("Low on memory:\n");
1576
1577                        boolean firstLine = true;
1578                        int lastOomAdj = Integer.MIN_VALUE;
1579                        for (int i=0, N=memInfos.size(); i<N; i++) {
1580                            ProcessMemInfo mi = memInfos.get(i);
1581
1582                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1583                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1584                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1585                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1586                                if (lastOomAdj != mi.oomAdj) {
1587                                    lastOomAdj = mi.oomAdj;
1588                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1589                                        tag.append(" / ");
1590                                    }
1591                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1592                                        if (firstLine) {
1593                                            stack.append(":");
1594                                            firstLine = false;
1595                                        }
1596                                        stack.append("\n\t at ");
1597                                    } else {
1598                                        stack.append("$");
1599                                    }
1600                                } else {
1601                                    tag.append(" ");
1602                                    stack.append("$");
1603                                }
1604                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1605                                    appendMemBucket(tag, mi.pss, mi.name, false);
1606                                }
1607                                appendMemBucket(stack, mi.pss, mi.name, true);
1608                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1609                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1610                                    stack.append("(");
1611                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1612                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1613                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1614                                            stack.append(":");
1615                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1616                                        }
1617                                    }
1618                                    stack.append(")");
1619                                }
1620                            }
1621
1622                            logBuilder.append("  ");
1623                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1624                            logBuilder.append(' ');
1625                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1626                            logBuilder.append(' ');
1627                            ProcessList.appendRamKb(logBuilder, mi.pss);
1628                            logBuilder.append(" kB: ");
1629                            logBuilder.append(mi.name);
1630                            logBuilder.append(" (");
1631                            logBuilder.append(mi.pid);
1632                            logBuilder.append(") ");
1633                            logBuilder.append(mi.adjType);
1634                            logBuilder.append('\n');
1635                            if (mi.adjReason != null) {
1636                                logBuilder.append("                      ");
1637                                logBuilder.append(mi.adjReason);
1638                                logBuilder.append('\n');
1639                            }
1640                        }
1641
1642                        logBuilder.append("           ");
1643                        ProcessList.appendRamKb(logBuilder, totalPss);
1644                        logBuilder.append(" kB: TOTAL\n");
1645
1646                        long[] infos = new long[Debug.MEMINFO_COUNT];
1647                        Debug.getMemInfo(infos);
1648                        logBuilder.append("  MemInfo: ");
1649                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1650                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1651                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1652                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1653                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1654                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1655                            logBuilder.append("  ZRAM: ");
1656                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1657                            logBuilder.append(" kB RAM, ");
1658                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1659                            logBuilder.append(" kB swap total, ");
1660                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1661                            logBuilder.append(" kB swap free\n");
1662                        }
1663                        Slog.i(TAG, logBuilder.toString());
1664
1665                        StringBuilder dropBuilder = new StringBuilder(1024);
1666                        /*
1667                        StringWriter oomSw = new StringWriter();
1668                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1669                        StringWriter catSw = new StringWriter();
1670                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1671                        String[] emptyArgs = new String[] { };
1672                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1673                        oomPw.flush();
1674                        String oomString = oomSw.toString();
1675                        */
1676                        dropBuilder.append(stack);
1677                        dropBuilder.append('\n');
1678                        dropBuilder.append('\n');
1679                        dropBuilder.append(logBuilder);
1680                        dropBuilder.append('\n');
1681                        /*
1682                        dropBuilder.append(oomString);
1683                        dropBuilder.append('\n');
1684                        */
1685                        StringWriter catSw = new StringWriter();
1686                        synchronized (ActivityManagerService.this) {
1687                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1688                            String[] emptyArgs = new String[] { };
1689                            catPw.println();
1690                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1691                            catPw.println();
1692                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1693                                    false, false, null);
1694                            catPw.println();
1695                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1696                            catPw.flush();
1697                        }
1698                        dropBuilder.append(catSw.toString());
1699                        addErrorToDropBox("lowmem", null, "system_server", null,
1700                                null, tag.toString(), dropBuilder.toString(), null, null);
1701                        //Slog.i(TAG, "Sent to dropbox:");
1702                        //Slog.i(TAG, dropBuilder.toString());
1703                        synchronized (ActivityManagerService.this) {
1704                            long now = SystemClock.uptimeMillis();
1705                            if (mLastMemUsageReportTime < now) {
1706                                mLastMemUsageReportTime = now;
1707                            }
1708                        }
1709                    }
1710                };
1711                thread.start();
1712                break;
1713            }
1714            case REPORT_USER_SWITCH_MSG: {
1715                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1716                break;
1717            }
1718            case CONTINUE_USER_SWITCH_MSG: {
1719                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1720                break;
1721            }
1722            case USER_SWITCH_TIMEOUT_MSG: {
1723                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1724                break;
1725            }
1726            case IMMERSIVE_MODE_LOCK_MSG: {
1727                final boolean nextState = (msg.arg1 != 0);
1728                if (mUpdateLock.isHeld() != nextState) {
1729                    if (DEBUG_IMMERSIVE) {
1730                        final ActivityRecord r = (ActivityRecord) msg.obj;
1731                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1732                    }
1733                    if (nextState) {
1734                        mUpdateLock.acquire();
1735                    } else {
1736                        mUpdateLock.release();
1737                    }
1738                }
1739                break;
1740            }
1741            case PERSIST_URI_GRANTS_MSG: {
1742                writeGrantedUriPermissions();
1743                break;
1744            }
1745            case REQUEST_ALL_PSS_MSG: {
1746                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1747                break;
1748            }
1749            case START_PROFILES_MSG: {
1750                synchronized (ActivityManagerService.this) {
1751                    startProfilesLocked();
1752                }
1753                break;
1754            }
1755            case UPDATE_TIME: {
1756                synchronized (ActivityManagerService.this) {
1757                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1758                        ProcessRecord r = mLruProcesses.get(i);
1759                        if (r.thread != null) {
1760                            try {
1761                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1762                            } catch (RemoteException ex) {
1763                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1764                            }
1765                        }
1766                    }
1767                }
1768                break;
1769            }
1770            case SYSTEM_USER_START_MSG: {
1771                mSystemServiceManager.startUser(msg.arg1);
1772                break;
1773            }
1774            case SYSTEM_USER_CURRENT_MSG: {
1775                mSystemServiceManager.switchUser(msg.arg1);
1776                break;
1777            }
1778            }
1779        }
1780    };
1781
1782    static final int COLLECT_PSS_BG_MSG = 1;
1783
1784    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1785        @Override
1786        public void handleMessage(Message msg) {
1787            switch (msg.what) {
1788            case COLLECT_PSS_BG_MSG: {
1789                int i=0, num=0;
1790                long start = SystemClock.uptimeMillis();
1791                long[] tmp = new long[1];
1792                do {
1793                    ProcessRecord proc;
1794                    int procState;
1795                    int pid;
1796                    synchronized (ActivityManagerService.this) {
1797                        if (i >= mPendingPssProcesses.size()) {
1798                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1799                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1800                            mPendingPssProcesses.clear();
1801                            return;
1802                        }
1803                        proc = mPendingPssProcesses.get(i);
1804                        procState = proc.pssProcState;
1805                        if (proc.thread != null && procState == proc.setProcState) {
1806                            pid = proc.pid;
1807                        } else {
1808                            proc = null;
1809                            pid = 0;
1810                        }
1811                        i++;
1812                    }
1813                    if (proc != null) {
1814                        long pss = Debug.getPss(pid, tmp);
1815                        synchronized (ActivityManagerService.this) {
1816                            if (proc.thread != null && proc.setProcState == procState
1817                                    && proc.pid == pid) {
1818                                num++;
1819                                proc.lastPssTime = SystemClock.uptimeMillis();
1820                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1821                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1822                                        + ": " + pss + " lastPss=" + proc.lastPss
1823                                        + " state=" + ProcessList.makeProcStateString(procState));
1824                                if (proc.initialIdlePss == 0) {
1825                                    proc.initialIdlePss = pss;
1826                                }
1827                                proc.lastPss = pss;
1828                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1829                                    proc.lastCachedPss = pss;
1830                                }
1831                            }
1832                        }
1833                    }
1834                } while (true);
1835            }
1836            }
1837        }
1838    };
1839
1840    /**
1841     * Monitor for package changes and update our internal state.
1842     */
1843    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1844        @Override
1845        public void onPackageRemoved(String packageName, int uid) {
1846            // Remove all tasks with activities in the specified package from the list of recent tasks
1847            synchronized (ActivityManagerService.this) {
1848                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1849                    TaskRecord tr = mRecentTasks.get(i);
1850                    ComponentName cn = tr.intent.getComponent();
1851                    if (cn != null && cn.getPackageName().equals(packageName)) {
1852                        // If the package name matches, remove the task and kill the process
1853                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1854                    }
1855                }
1856            }
1857        }
1858
1859        @Override
1860        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1861            final PackageManager pm = mContext.getPackageManager();
1862            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1863                    new ArrayList<Pair<Intent, Integer>>();
1864            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1865            // Copy the list of recent tasks so that we don't hold onto the lock on
1866            // ActivityManagerService for long periods while checking if components exist.
1867            synchronized (ActivityManagerService.this) {
1868                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1869                    TaskRecord tr = mRecentTasks.get(i);
1870                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1871                }
1872            }
1873            // Check the recent tasks and filter out all tasks with components that no longer exist.
1874            Intent tmpI = new Intent();
1875            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1876                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1877                ComponentName cn = p.first.getComponent();
1878                if (cn != null && cn.getPackageName().equals(packageName)) {
1879                    try {
1880                        // Add the task to the list to remove if the component no longer exists
1881                        tmpI.setComponent(cn);
1882                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1883                            tasksToRemove.add(p.second);
1884                        }
1885                    } catch (Exception e) {}
1886                }
1887            }
1888            // Prune all the tasks with removed components from the list of recent tasks
1889            synchronized (ActivityManagerService.this) {
1890                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1891                    // Remove the task but don't kill the process (since other components in that
1892                    // package may still be running and in the background)
1893                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1894                }
1895            }
1896            return true;
1897        }
1898
1899        @Override
1900        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1901            // Force stop the specified packages
1902            if (packages != null) {
1903                for (String pkg : packages) {
1904                    synchronized (ActivityManagerService.this) {
1905                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1906                                "finished booting")) {
1907                            return true;
1908                        }
1909                    }
1910                }
1911            }
1912            return false;
1913        }
1914    };
1915
1916    public void setSystemProcess() {
1917        try {
1918            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1919            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1920            ServiceManager.addService("meminfo", new MemBinder(this));
1921            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1922            ServiceManager.addService("dbinfo", new DbBinder(this));
1923            if (MONITOR_CPU_USAGE) {
1924                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1925            }
1926            ServiceManager.addService("permission", new PermissionController(this));
1927
1928            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1929                    "android", STOCK_PM_FLAGS);
1930            mSystemThread.installSystemApplicationInfo(info);
1931
1932            synchronized (this) {
1933                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1934                app.persistent = true;
1935                app.pid = MY_PID;
1936                app.maxAdj = ProcessList.SYSTEM_ADJ;
1937                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1938                mProcessNames.put(app.processName, app.uid, app);
1939                synchronized (mPidsSelfLocked) {
1940                    mPidsSelfLocked.put(app.pid, app);
1941                }
1942                updateLruProcessLocked(app, false, null);
1943                updateOomAdjLocked();
1944            }
1945        } catch (PackageManager.NameNotFoundException e) {
1946            throw new RuntimeException(
1947                    "Unable to find android system package", e);
1948        }
1949    }
1950
1951    public void setWindowManager(WindowManagerService wm) {
1952        mWindowManager = wm;
1953        mStackSupervisor.setWindowManager(wm);
1954    }
1955
1956    public void startObservingNativeCrashes() {
1957        final NativeCrashListener ncl = new NativeCrashListener(this);
1958        ncl.start();
1959    }
1960
1961    public IAppOpsService getAppOpsService() {
1962        return mAppOpsService;
1963    }
1964
1965    static class MemBinder extends Binder {
1966        ActivityManagerService mActivityManagerService;
1967        MemBinder(ActivityManagerService activityManagerService) {
1968            mActivityManagerService = activityManagerService;
1969        }
1970
1971        @Override
1972        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1973            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1974                    != PackageManager.PERMISSION_GRANTED) {
1975                pw.println("Permission Denial: can't dump meminfo from from pid="
1976                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1977                        + " without permission " + android.Manifest.permission.DUMP);
1978                return;
1979            }
1980
1981            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1982        }
1983    }
1984
1985    static class GraphicsBinder extends Binder {
1986        ActivityManagerService mActivityManagerService;
1987        GraphicsBinder(ActivityManagerService activityManagerService) {
1988            mActivityManagerService = activityManagerService;
1989        }
1990
1991        @Override
1992        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1993            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1994                    != PackageManager.PERMISSION_GRANTED) {
1995                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1996                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1997                        + " without permission " + android.Manifest.permission.DUMP);
1998                return;
1999            }
2000
2001            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2002        }
2003    }
2004
2005    static class DbBinder extends Binder {
2006        ActivityManagerService mActivityManagerService;
2007        DbBinder(ActivityManagerService activityManagerService) {
2008            mActivityManagerService = activityManagerService;
2009        }
2010
2011        @Override
2012        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2013            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2014                    != PackageManager.PERMISSION_GRANTED) {
2015                pw.println("Permission Denial: can't dump dbinfo from from pid="
2016                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2017                        + " without permission " + android.Manifest.permission.DUMP);
2018                return;
2019            }
2020
2021            mActivityManagerService.dumpDbInfo(fd, pw, args);
2022        }
2023    }
2024
2025    static class CpuBinder extends Binder {
2026        ActivityManagerService mActivityManagerService;
2027        CpuBinder(ActivityManagerService activityManagerService) {
2028            mActivityManagerService = activityManagerService;
2029        }
2030
2031        @Override
2032        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2033            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2034                    != PackageManager.PERMISSION_GRANTED) {
2035                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2036                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2037                        + " without permission " + android.Manifest.permission.DUMP);
2038                return;
2039            }
2040
2041            synchronized (mActivityManagerService.mProcessCpuThread) {
2042                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2043                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2044                        SystemClock.uptimeMillis()));
2045            }
2046        }
2047    }
2048
2049    public static final class Lifecycle extends SystemService {
2050        private final ActivityManagerService mService;
2051
2052        public Lifecycle(Context context) {
2053            super(context);
2054            mService = new ActivityManagerService(context);
2055        }
2056
2057        @Override
2058        public void onStart() {
2059            mService.start();
2060        }
2061
2062        public ActivityManagerService getService() {
2063            return mService;
2064        }
2065    }
2066
2067    // Note: This method is invoked on the main thread but may need to attach various
2068    // handlers to other threads.  So take care to be explicit about the looper.
2069    public ActivityManagerService(Context systemContext) {
2070        mContext = systemContext;
2071        mFactoryTest = FactoryTest.getMode();
2072        mSystemThread = ActivityThread.currentActivityThread();
2073
2074        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2075
2076        mHandlerThread = new ServiceThread(TAG,
2077                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2078        mHandlerThread.start();
2079        mHandler = new MainHandler(mHandlerThread.getLooper());
2080
2081        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2082                "foreground", BROADCAST_FG_TIMEOUT, false);
2083        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2084                "background", BROADCAST_BG_TIMEOUT, true);
2085        mBroadcastQueues[0] = mFgBroadcastQueue;
2086        mBroadcastQueues[1] = mBgBroadcastQueue;
2087
2088        mServices = new ActiveServices(this);
2089        mProviderMap = new ProviderMap(this);
2090
2091        // TODO: Move creation of battery stats service outside of activity manager service.
2092        File dataDir = Environment.getDataDirectory();
2093        File systemDir = new File(dataDir, "system");
2094        systemDir.mkdirs();
2095        mBatteryStatsService = new BatteryStatsService(new File(
2096                systemDir, "batterystats.bin").toString(), mHandler);
2097        mBatteryStatsService.getActiveStatistics().readLocked();
2098        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2099        mOnBattery = DEBUG_POWER ? true
2100                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2101        mBatteryStatsService.getActiveStatistics().setCallback(this);
2102
2103        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2104
2105        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2106        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2107
2108        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2109
2110        // User 0 is the first and only user that runs at boot.
2111        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2112        mUserLru.add(Integer.valueOf(0));
2113        updateStartedUserArrayLocked();
2114
2115        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2116            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2117
2118        mConfiguration.setToDefaults();
2119        mConfiguration.setLocale(Locale.getDefault());
2120
2121        mConfigurationSeq = mConfiguration.seq = 1;
2122        mProcessCpuTracker.init();
2123
2124        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2125        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2126        mStackSupervisor = new ActivityStackSupervisor(this);
2127
2128        mProcessCpuThread = new Thread("CpuTracker") {
2129            @Override
2130            public void run() {
2131                while (true) {
2132                    try {
2133                        try {
2134                            synchronized(this) {
2135                                final long now = SystemClock.uptimeMillis();
2136                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2137                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2138                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2139                                //        + ", write delay=" + nextWriteDelay);
2140                                if (nextWriteDelay < nextCpuDelay) {
2141                                    nextCpuDelay = nextWriteDelay;
2142                                }
2143                                if (nextCpuDelay > 0) {
2144                                    mProcessCpuMutexFree.set(true);
2145                                    this.wait(nextCpuDelay);
2146                                }
2147                            }
2148                        } catch (InterruptedException e) {
2149                        }
2150                        updateCpuStatsNow();
2151                    } catch (Exception e) {
2152                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2153                    }
2154                }
2155            }
2156        };
2157
2158        Watchdog.getInstance().addMonitor(this);
2159        Watchdog.getInstance().addThread(mHandler);
2160    }
2161
2162    public void setSystemServiceManager(SystemServiceManager mgr) {
2163        mSystemServiceManager = mgr;
2164    }
2165
2166    private void start() {
2167        mProcessCpuThread.start();
2168
2169        mBatteryStatsService.publish(mContext);
2170        mUsageStatsService.publish(mContext);
2171        mAppOpsService.publish(mContext);
2172
2173        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2174    }
2175
2176    @Override
2177    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2178            throws RemoteException {
2179        if (code == SYSPROPS_TRANSACTION) {
2180            // We need to tell all apps about the system property change.
2181            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2182            synchronized(this) {
2183                final int NP = mProcessNames.getMap().size();
2184                for (int ip=0; ip<NP; ip++) {
2185                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2186                    final int NA = apps.size();
2187                    for (int ia=0; ia<NA; ia++) {
2188                        ProcessRecord app = apps.valueAt(ia);
2189                        if (app.thread != null) {
2190                            procs.add(app.thread.asBinder());
2191                        }
2192                    }
2193                }
2194            }
2195
2196            int N = procs.size();
2197            for (int i=0; i<N; i++) {
2198                Parcel data2 = Parcel.obtain();
2199                try {
2200                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2201                } catch (RemoteException e) {
2202                }
2203                data2.recycle();
2204            }
2205        }
2206        try {
2207            return super.onTransact(code, data, reply, flags);
2208        } catch (RuntimeException e) {
2209            // The activity manager only throws security exceptions, so let's
2210            // log all others.
2211            if (!(e instanceof SecurityException)) {
2212                Slog.wtf(TAG, "Activity Manager Crash", e);
2213            }
2214            throw e;
2215        }
2216    }
2217
2218    void updateCpuStats() {
2219        final long now = SystemClock.uptimeMillis();
2220        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2221            return;
2222        }
2223        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2224            synchronized (mProcessCpuThread) {
2225                mProcessCpuThread.notify();
2226            }
2227        }
2228    }
2229
2230    void updateCpuStatsNow() {
2231        synchronized (mProcessCpuThread) {
2232            mProcessCpuMutexFree.set(false);
2233            final long now = SystemClock.uptimeMillis();
2234            boolean haveNewCpuStats = false;
2235
2236            if (MONITOR_CPU_USAGE &&
2237                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2238                mLastCpuTime.set(now);
2239                haveNewCpuStats = true;
2240                mProcessCpuTracker.update();
2241                //Slog.i(TAG, mProcessCpu.printCurrentState());
2242                //Slog.i(TAG, "Total CPU usage: "
2243                //        + mProcessCpu.getTotalCpuPercent() + "%");
2244
2245                // Slog the cpu usage if the property is set.
2246                if ("true".equals(SystemProperties.get("events.cpu"))) {
2247                    int user = mProcessCpuTracker.getLastUserTime();
2248                    int system = mProcessCpuTracker.getLastSystemTime();
2249                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2250                    int irq = mProcessCpuTracker.getLastIrqTime();
2251                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2252                    int idle = mProcessCpuTracker.getLastIdleTime();
2253
2254                    int total = user + system + iowait + irq + softIrq + idle;
2255                    if (total == 0) total = 1;
2256
2257                    EventLog.writeEvent(EventLogTags.CPU,
2258                            ((user+system+iowait+irq+softIrq) * 100) / total,
2259                            (user * 100) / total,
2260                            (system * 100) / total,
2261                            (iowait * 100) / total,
2262                            (irq * 100) / total,
2263                            (softIrq * 100) / total);
2264                }
2265            }
2266
2267            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2268            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2269            synchronized(bstats) {
2270                synchronized(mPidsSelfLocked) {
2271                    if (haveNewCpuStats) {
2272                        if (mOnBattery) {
2273                            int perc = bstats.startAddingCpuLocked();
2274                            int totalUTime = 0;
2275                            int totalSTime = 0;
2276                            final int N = mProcessCpuTracker.countStats();
2277                            for (int i=0; i<N; i++) {
2278                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2279                                if (!st.working) {
2280                                    continue;
2281                                }
2282                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2283                                int otherUTime = (st.rel_utime*perc)/100;
2284                                int otherSTime = (st.rel_stime*perc)/100;
2285                                totalUTime += otherUTime;
2286                                totalSTime += otherSTime;
2287                                if (pr != null) {
2288                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2289                                    if (ps == null || !ps.isActive()) {
2290                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2291                                                pr.info.uid, pr.processName);
2292                                    }
2293                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2294                                            st.rel_stime-otherSTime);
2295                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2296                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2297                                } else {
2298                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2299                                    if (ps == null || !ps.isActive()) {
2300                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2301                                                bstats.mapUid(st.uid), st.name);
2302                                    }
2303                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2304                                            st.rel_stime-otherSTime);
2305                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2306                                }
2307                            }
2308                            bstats.finishAddingCpuLocked(perc, totalUTime,
2309                                    totalSTime, cpuSpeedTimes);
2310                        }
2311                    }
2312                }
2313
2314                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2315                    mLastWriteTime = now;
2316                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2317                }
2318            }
2319        }
2320    }
2321
2322    @Override
2323    public void batteryNeedsCpuUpdate() {
2324        updateCpuStatsNow();
2325    }
2326
2327    @Override
2328    public void batteryPowerChanged(boolean onBattery) {
2329        // When plugging in, update the CPU stats first before changing
2330        // the plug state.
2331        updateCpuStatsNow();
2332        synchronized (this) {
2333            synchronized(mPidsSelfLocked) {
2334                mOnBattery = DEBUG_POWER ? true : onBattery;
2335            }
2336        }
2337    }
2338
2339    /**
2340     * Initialize the application bind args. These are passed to each
2341     * process when the bindApplication() IPC is sent to the process. They're
2342     * lazily setup to make sure the services are running when they're asked for.
2343     */
2344    private HashMap<String, IBinder> getCommonServicesLocked() {
2345        if (mAppBindArgs == null) {
2346            mAppBindArgs = new HashMap<String, IBinder>();
2347
2348            // Setup the application init args
2349            mAppBindArgs.put("package", ServiceManager.getService("package"));
2350            mAppBindArgs.put("window", ServiceManager.getService("window"));
2351            mAppBindArgs.put(Context.ALARM_SERVICE,
2352                    ServiceManager.getService(Context.ALARM_SERVICE));
2353        }
2354        return mAppBindArgs;
2355    }
2356
2357    final void setFocusedActivityLocked(ActivityRecord r) {
2358        if (mFocusedActivity != r) {
2359            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2360            mFocusedActivity = r;
2361            if (r.task != null && r.task.voiceInteractor != null) {
2362                startRunningVoiceLocked();
2363            } else {
2364                finishRunningVoiceLocked();
2365            }
2366            mStackSupervisor.setFocusedStack(r);
2367            if (r != null) {
2368                mWindowManager.setFocusedApp(r.appToken, true);
2369            }
2370            applyUpdateLockStateLocked(r);
2371        }
2372    }
2373
2374    final void clearFocusedActivity(ActivityRecord r) {
2375        if (mFocusedActivity == r) {
2376            mFocusedActivity = null;
2377        }
2378    }
2379
2380    @Override
2381    public void setFocusedStack(int stackId) {
2382        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2383        synchronized (ActivityManagerService.this) {
2384            ActivityStack stack = mStackSupervisor.getStack(stackId);
2385            if (stack != null) {
2386                ActivityRecord r = stack.topRunningActivityLocked(null);
2387                if (r != null) {
2388                    setFocusedActivityLocked(r);
2389                }
2390            }
2391        }
2392    }
2393
2394    @Override
2395    public void notifyActivityDrawn(IBinder token) {
2396        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2397        synchronized (this) {
2398            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2399            if (r != null) {
2400                r.task.stack.notifyActivityDrawnLocked(r);
2401            }
2402        }
2403    }
2404
2405    final void applyUpdateLockStateLocked(ActivityRecord r) {
2406        // Modifications to the UpdateLock state are done on our handler, outside
2407        // the activity manager's locks.  The new state is determined based on the
2408        // state *now* of the relevant activity record.  The object is passed to
2409        // the handler solely for logging detail, not to be consulted/modified.
2410        final boolean nextState = r != null && r.immersive;
2411        mHandler.sendMessage(
2412                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2413    }
2414
2415    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2416        Message msg = Message.obtain();
2417        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2418        msg.obj = r.task.askedCompatMode ? null : r;
2419        mHandler.sendMessage(msg);
2420    }
2421
2422    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2423            String what, Object obj, ProcessRecord srcApp) {
2424        app.lastActivityTime = now;
2425
2426        if (app.activities.size() > 0) {
2427            // Don't want to touch dependent processes that are hosting activities.
2428            return index;
2429        }
2430
2431        int lrui = mLruProcesses.lastIndexOf(app);
2432        if (lrui < 0) {
2433            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2434                    + what + " " + obj + " from " + srcApp);
2435            return index;
2436        }
2437
2438        if (lrui >= index) {
2439            // Don't want to cause this to move dependent processes *back* in the
2440            // list as if they were less frequently used.
2441            return index;
2442        }
2443
2444        if (lrui >= mLruProcessActivityStart) {
2445            // Don't want to touch dependent processes that are hosting activities.
2446            return index;
2447        }
2448
2449        mLruProcesses.remove(lrui);
2450        if (index > 0) {
2451            index--;
2452        }
2453        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2454                + " in LRU list: " + app);
2455        mLruProcesses.add(index, app);
2456        return index;
2457    }
2458
2459    final void removeLruProcessLocked(ProcessRecord app) {
2460        int lrui = mLruProcesses.lastIndexOf(app);
2461        if (lrui >= 0) {
2462            if (lrui <= mLruProcessActivityStart) {
2463                mLruProcessActivityStart--;
2464            }
2465            if (lrui <= mLruProcessServiceStart) {
2466                mLruProcessServiceStart--;
2467            }
2468            mLruProcesses.remove(lrui);
2469        }
2470    }
2471
2472    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2473            ProcessRecord client) {
2474        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2475                || app.treatLikeActivity;
2476        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2477        if (!activityChange && hasActivity) {
2478            // The process has activities, so we are only allowing activity-based adjustments
2479            // to move it.  It should be kept in the front of the list with other
2480            // processes that have activities, and we don't want those to change their
2481            // order except due to activity operations.
2482            return;
2483        }
2484
2485        mLruSeq++;
2486        final long now = SystemClock.uptimeMillis();
2487        app.lastActivityTime = now;
2488
2489        // First a quick reject: if the app is already at the position we will
2490        // put it, then there is nothing to do.
2491        if (hasActivity) {
2492            final int N = mLruProcesses.size();
2493            if (N > 0 && mLruProcesses.get(N-1) == app) {
2494                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2495                return;
2496            }
2497        } else {
2498            if (mLruProcessServiceStart > 0
2499                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2500                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2501                return;
2502            }
2503        }
2504
2505        int lrui = mLruProcesses.lastIndexOf(app);
2506
2507        if (app.persistent && lrui >= 0) {
2508            // We don't care about the position of persistent processes, as long as
2509            // they are in the list.
2510            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2511            return;
2512        }
2513
2514        /* In progress: compute new position first, so we can avoid doing work
2515           if the process is not actually going to move.  Not yet working.
2516        int addIndex;
2517        int nextIndex;
2518        boolean inActivity = false, inService = false;
2519        if (hasActivity) {
2520            // Process has activities, put it at the very tipsy-top.
2521            addIndex = mLruProcesses.size();
2522            nextIndex = mLruProcessServiceStart;
2523            inActivity = true;
2524        } else if (hasService) {
2525            // Process has services, put it at the top of the service list.
2526            addIndex = mLruProcessActivityStart;
2527            nextIndex = mLruProcessServiceStart;
2528            inActivity = true;
2529            inService = true;
2530        } else  {
2531            // Process not otherwise of interest, it goes to the top of the non-service area.
2532            addIndex = mLruProcessServiceStart;
2533            if (client != null) {
2534                int clientIndex = mLruProcesses.lastIndexOf(client);
2535                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2536                        + app);
2537                if (clientIndex >= 0 && addIndex > clientIndex) {
2538                    addIndex = clientIndex;
2539                }
2540            }
2541            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2542        }
2543
2544        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2545                + mLruProcessActivityStart + "): " + app);
2546        */
2547
2548        if (lrui >= 0) {
2549            if (lrui < mLruProcessActivityStart) {
2550                mLruProcessActivityStart--;
2551            }
2552            if (lrui < mLruProcessServiceStart) {
2553                mLruProcessServiceStart--;
2554            }
2555            /*
2556            if (addIndex > lrui) {
2557                addIndex--;
2558            }
2559            if (nextIndex > lrui) {
2560                nextIndex--;
2561            }
2562            */
2563            mLruProcesses.remove(lrui);
2564        }
2565
2566        /*
2567        mLruProcesses.add(addIndex, app);
2568        if (inActivity) {
2569            mLruProcessActivityStart++;
2570        }
2571        if (inService) {
2572            mLruProcessActivityStart++;
2573        }
2574        */
2575
2576        int nextIndex;
2577        if (hasActivity) {
2578            final int N = mLruProcesses.size();
2579            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2580                // Process doesn't have activities, but has clients with
2581                // activities...  move it up, but one below the top (the top
2582                // should always have a real activity).
2583                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2584                mLruProcesses.add(N-1, app);
2585                // To keep it from spamming the LRU list (by making a bunch of clients),
2586                // we will push down any other entries owned by the app.
2587                final int uid = app.info.uid;
2588                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2589                    ProcessRecord subProc = mLruProcesses.get(i);
2590                    if (subProc.info.uid == uid) {
2591                        // We want to push this one down the list.  If the process after
2592                        // it is for the same uid, however, don't do so, because we don't
2593                        // want them internally to be re-ordered.
2594                        if (mLruProcesses.get(i-1).info.uid != uid) {
2595                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2596                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2597                            ProcessRecord tmp = mLruProcesses.get(i);
2598                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2599                            mLruProcesses.set(i-1, tmp);
2600                            i--;
2601                        }
2602                    } else {
2603                        // A gap, we can stop here.
2604                        break;
2605                    }
2606                }
2607            } else {
2608                // Process has activities, put it at the very tipsy-top.
2609                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2610                mLruProcesses.add(app);
2611            }
2612            nextIndex = mLruProcessServiceStart;
2613        } else if (hasService) {
2614            // Process has services, put it at the top of the service list.
2615            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2616            mLruProcesses.add(mLruProcessActivityStart, app);
2617            nextIndex = mLruProcessServiceStart;
2618            mLruProcessActivityStart++;
2619        } else  {
2620            // Process not otherwise of interest, it goes to the top of the non-service area.
2621            int index = mLruProcessServiceStart;
2622            if (client != null) {
2623                // If there is a client, don't allow the process to be moved up higher
2624                // in the list than that client.
2625                int clientIndex = mLruProcesses.lastIndexOf(client);
2626                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2627                        + " when updating " + app);
2628                if (clientIndex <= lrui) {
2629                    // Don't allow the client index restriction to push it down farther in the
2630                    // list than it already is.
2631                    clientIndex = lrui;
2632                }
2633                if (clientIndex >= 0 && index > clientIndex) {
2634                    index = clientIndex;
2635                }
2636            }
2637            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2638            mLruProcesses.add(index, app);
2639            nextIndex = index-1;
2640            mLruProcessActivityStart++;
2641            mLruProcessServiceStart++;
2642        }
2643
2644        // If the app is currently using a content provider or service,
2645        // bump those processes as well.
2646        for (int j=app.connections.size()-1; j>=0; j--) {
2647            ConnectionRecord cr = app.connections.valueAt(j);
2648            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2649                    && cr.binding.service.app != null
2650                    && cr.binding.service.app.lruSeq != mLruSeq
2651                    && !cr.binding.service.app.persistent) {
2652                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2653                        "service connection", cr, app);
2654            }
2655        }
2656        for (int j=app.conProviders.size()-1; j>=0; j--) {
2657            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2658            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2659                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2660                        "provider reference", cpr, app);
2661            }
2662        }
2663    }
2664
2665    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2666        if (uid == Process.SYSTEM_UID) {
2667            // The system gets to run in any process.  If there are multiple
2668            // processes with the same uid, just pick the first (this
2669            // should never happen).
2670            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2671            if (procs == null) return null;
2672            final int N = procs.size();
2673            for (int i = 0; i < N; i++) {
2674                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2675            }
2676        }
2677        ProcessRecord proc = mProcessNames.get(processName, uid);
2678        if (false && proc != null && !keepIfLarge
2679                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2680                && proc.lastCachedPss >= 4000) {
2681            // Turn this condition on to cause killing to happen regularly, for testing.
2682            if (proc.baseProcessTracker != null) {
2683                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2684            }
2685            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2686                    + "k from cached");
2687        } else if (proc != null && !keepIfLarge
2688                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2689                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2690            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2691            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2692                if (proc.baseProcessTracker != null) {
2693                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2694                }
2695                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2696                        + "k from cached");
2697            }
2698        }
2699        return proc;
2700    }
2701
2702    void ensurePackageDexOpt(String packageName) {
2703        IPackageManager pm = AppGlobals.getPackageManager();
2704        try {
2705            if (pm.performDexOpt(packageName)) {
2706                mDidDexOpt = true;
2707            }
2708        } catch (RemoteException e) {
2709        }
2710    }
2711
2712    boolean isNextTransitionForward() {
2713        int transit = mWindowManager.getPendingAppTransition();
2714        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2715                || transit == AppTransition.TRANSIT_TASK_OPEN
2716                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2717    }
2718
2719    final ProcessRecord startProcessLocked(String processName,
2720            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2721            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2722            boolean isolated, boolean keepIfLarge) {
2723        ProcessRecord app;
2724        if (!isolated) {
2725            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2726        } else {
2727            // If this is an isolated process, it can't re-use an existing process.
2728            app = null;
2729        }
2730        // We don't have to do anything more if:
2731        // (1) There is an existing application record; and
2732        // (2) The caller doesn't think it is dead, OR there is no thread
2733        //     object attached to it so we know it couldn't have crashed; and
2734        // (3) There is a pid assigned to it, so it is either starting or
2735        //     already running.
2736        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2737                + " app=" + app + " knownToBeDead=" + knownToBeDead
2738                + " thread=" + (app != null ? app.thread : null)
2739                + " pid=" + (app != null ? app.pid : -1));
2740        if (app != null && app.pid > 0) {
2741            if (!knownToBeDead || app.thread == null) {
2742                // We already have the app running, or are waiting for it to
2743                // come up (we have a pid but not yet its thread), so keep it.
2744                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2745                // If this is a new package in the process, add the package to the list
2746                app.addPackage(info.packageName, mProcessStats);
2747                return app;
2748            }
2749
2750            // An application record is attached to a previous process,
2751            // clean it up now.
2752            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2753            handleAppDiedLocked(app, true, true);
2754        }
2755
2756        String hostingNameStr = hostingName != null
2757                ? hostingName.flattenToShortString() : null;
2758
2759        if (!isolated) {
2760            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2761                // If we are in the background, then check to see if this process
2762                // is bad.  If so, we will just silently fail.
2763                if (mBadProcesses.get(info.processName, info.uid) != null) {
2764                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2765                            + "/" + info.processName);
2766                    return null;
2767                }
2768            } else {
2769                // When the user is explicitly starting a process, then clear its
2770                // crash count so that we won't make it bad until they see at
2771                // least one crash dialog again, and make the process good again
2772                // if it had been bad.
2773                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2774                        + "/" + info.processName);
2775                mProcessCrashTimes.remove(info.processName, info.uid);
2776                if (mBadProcesses.get(info.processName, info.uid) != null) {
2777                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2778                            UserHandle.getUserId(info.uid), info.uid,
2779                            info.processName);
2780                    mBadProcesses.remove(info.processName, info.uid);
2781                    if (app != null) {
2782                        app.bad = false;
2783                    }
2784                }
2785            }
2786        }
2787
2788        if (app == null) {
2789            app = newProcessRecordLocked(info, processName, isolated);
2790            if (app == null) {
2791                Slog.w(TAG, "Failed making new process record for "
2792                        + processName + "/" + info.uid + " isolated=" + isolated);
2793                return null;
2794            }
2795            mProcessNames.put(processName, app.uid, app);
2796            if (isolated) {
2797                mIsolatedProcesses.put(app.uid, app);
2798            }
2799        } else {
2800            // If this is a new package in the process, add the package to the list
2801            app.addPackage(info.packageName, mProcessStats);
2802        }
2803
2804        // If the system is not ready yet, then hold off on starting this
2805        // process until it is.
2806        if (!mProcessesReady
2807                && !isAllowedWhileBooting(info)
2808                && !allowWhileBooting) {
2809            if (!mProcessesOnHold.contains(app)) {
2810                mProcessesOnHold.add(app);
2811            }
2812            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2813            return app;
2814        }
2815
2816        startProcessLocked(app, hostingType, hostingNameStr);
2817        return (app.pid != 0) ? app : null;
2818    }
2819
2820    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2821        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2822    }
2823
2824    private final void startProcessLocked(ProcessRecord app,
2825            String hostingType, String hostingNameStr) {
2826        if (app.pid > 0 && app.pid != MY_PID) {
2827            synchronized (mPidsSelfLocked) {
2828                mPidsSelfLocked.remove(app.pid);
2829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2830            }
2831            app.setPid(0);
2832        }
2833
2834        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2835                "startProcessLocked removing on hold: " + app);
2836        mProcessesOnHold.remove(app);
2837
2838        updateCpuStats();
2839
2840        try {
2841            int uid = app.uid;
2842
2843            int[] gids = null;
2844            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2845            if (!app.isolated) {
2846                int[] permGids = null;
2847                try {
2848                    final PackageManager pm = mContext.getPackageManager();
2849                    permGids = pm.getPackageGids(app.info.packageName);
2850
2851                    if (Environment.isExternalStorageEmulated()) {
2852                        if (pm.checkPermission(
2853                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2854                                app.info.packageName) == PERMISSION_GRANTED) {
2855                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2856                        } else {
2857                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2858                        }
2859                    }
2860                } catch (PackageManager.NameNotFoundException e) {
2861                    Slog.w(TAG, "Unable to retrieve gids", e);
2862                }
2863
2864                /*
2865                 * Add shared application GID so applications can share some
2866                 * resources like shared libraries
2867                 */
2868                if (permGids == null) {
2869                    gids = new int[1];
2870                } else {
2871                    gids = new int[permGids.length + 1];
2872                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2873                }
2874                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2875            }
2876            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2877                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2878                        && mTopComponent != null
2879                        && app.processName.equals(mTopComponent.getPackageName())) {
2880                    uid = 0;
2881                }
2882                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2883                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2884                    uid = 0;
2885                }
2886            }
2887            int debugFlags = 0;
2888            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2889                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2890                // Also turn on CheckJNI for debuggable apps. It's quite
2891                // awkward to turn on otherwise.
2892                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2893            }
2894            // Run the app in safe mode if its manifest requests so or the
2895            // system is booted in safe mode.
2896            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2897                mSafeMode == true) {
2898                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2899            }
2900            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2901                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2902            }
2903            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2904                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2905            }
2906            if ("1".equals(SystemProperties.get("debug.assert"))) {
2907                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2908            }
2909
2910            String requiredAbi = app.info.requiredCpuAbi;
2911            if (requiredAbi == null) {
2912                requiredAbi = Build.SUPPORTED_ABIS[0];
2913            }
2914
2915            // Start the process.  It will either succeed and return a result containing
2916            // the PID of the new process, or else throw a RuntimeException.
2917            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2918                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2919                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2920
2921            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2922            synchronized (bs) {
2923                if (bs.isOnBattery()) {
2924                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2925                }
2926            }
2927
2928            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2929                    UserHandle.getUserId(uid), startResult.pid, uid,
2930                    app.processName, hostingType,
2931                    hostingNameStr != null ? hostingNameStr : "");
2932
2933            if (app.persistent) {
2934                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2935            }
2936
2937            StringBuilder buf = mStringBuilder;
2938            buf.setLength(0);
2939            buf.append("Start proc ");
2940            buf.append(app.processName);
2941            buf.append(" for ");
2942            buf.append(hostingType);
2943            if (hostingNameStr != null) {
2944                buf.append(" ");
2945                buf.append(hostingNameStr);
2946            }
2947            buf.append(": pid=");
2948            buf.append(startResult.pid);
2949            buf.append(" uid=");
2950            buf.append(uid);
2951            buf.append(" gids={");
2952            if (gids != null) {
2953                for (int gi=0; gi<gids.length; gi++) {
2954                    if (gi != 0) buf.append(", ");
2955                    buf.append(gids[gi]);
2956
2957                }
2958            }
2959            buf.append("}");
2960            Slog.i(TAG, buf.toString());
2961            app.setPid(startResult.pid);
2962            app.usingWrapper = startResult.usingWrapper;
2963            app.removed = false;
2964            synchronized (mPidsSelfLocked) {
2965                this.mPidsSelfLocked.put(startResult.pid, app);
2966                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2967                msg.obj = app;
2968                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2969                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2970            }
2971            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2972                    app.processName, app.info.uid);
2973            if (app.isolated) {
2974                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2975            }
2976        } catch (RuntimeException e) {
2977            // XXX do better error recovery.
2978            app.setPid(0);
2979            Slog.e(TAG, "Failure starting process " + app.processName, e);
2980        }
2981    }
2982
2983    void updateUsageStats(ActivityRecord component, boolean resumed) {
2984        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2985        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2986        if (resumed) {
2987            mUsageStatsService.noteResumeComponent(component.realActivity);
2988            synchronized (stats) {
2989                stats.noteActivityResumedLocked(component.app.uid);
2990            }
2991        } else {
2992            mUsageStatsService.notePauseComponent(component.realActivity);
2993            synchronized (stats) {
2994                stats.noteActivityPausedLocked(component.app.uid);
2995            }
2996        }
2997    }
2998
2999    Intent getHomeIntent() {
3000        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3001        intent.setComponent(mTopComponent);
3002        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3003            intent.addCategory(Intent.CATEGORY_HOME);
3004        }
3005        return intent;
3006    }
3007
3008    boolean startHomeActivityLocked(int userId) {
3009        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3010                && mTopAction == null) {
3011            // We are running in factory test mode, but unable to find
3012            // the factory test app, so just sit around displaying the
3013            // error message and don't try to start anything.
3014            return false;
3015        }
3016        Intent intent = getHomeIntent();
3017        ActivityInfo aInfo =
3018            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3019        if (aInfo != null) {
3020            intent.setComponent(new ComponentName(
3021                    aInfo.applicationInfo.packageName, aInfo.name));
3022            // Don't do this if the home app is currently being
3023            // instrumented.
3024            aInfo = new ActivityInfo(aInfo);
3025            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3026            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3027                    aInfo.applicationInfo.uid, true);
3028            if (app == null || app.instrumentationClass == null) {
3029                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3030                mStackSupervisor.startHomeActivity(intent, aInfo);
3031            }
3032        }
3033
3034        return true;
3035    }
3036
3037    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3038        ActivityInfo ai = null;
3039        ComponentName comp = intent.getComponent();
3040        try {
3041            if (comp != null) {
3042                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3043            } else {
3044                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3045                        intent,
3046                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3047                            flags, userId);
3048
3049                if (info != null) {
3050                    ai = info.activityInfo;
3051                }
3052            }
3053        } catch (RemoteException e) {
3054            // ignore
3055        }
3056
3057        return ai;
3058    }
3059
3060    /**
3061     * Starts the "new version setup screen" if appropriate.
3062     */
3063    void startSetupActivityLocked() {
3064        // Only do this once per boot.
3065        if (mCheckedForSetup) {
3066            return;
3067        }
3068
3069        // We will show this screen if the current one is a different
3070        // version than the last one shown, and we are not running in
3071        // low-level factory test mode.
3072        final ContentResolver resolver = mContext.getContentResolver();
3073        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3074                Settings.Global.getInt(resolver,
3075                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3076            mCheckedForSetup = true;
3077
3078            // See if we should be showing the platform update setup UI.
3079            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3080            List<ResolveInfo> ris = mContext.getPackageManager()
3081                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3082
3083            // We don't allow third party apps to replace this.
3084            ResolveInfo ri = null;
3085            for (int i=0; ris != null && i<ris.size(); i++) {
3086                if ((ris.get(i).activityInfo.applicationInfo.flags
3087                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3088                    ri = ris.get(i);
3089                    break;
3090                }
3091            }
3092
3093            if (ri != null) {
3094                String vers = ri.activityInfo.metaData != null
3095                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3096                        : null;
3097                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3098                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3099                            Intent.METADATA_SETUP_VERSION);
3100                }
3101                String lastVers = Settings.Secure.getString(
3102                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3103                if (vers != null && !vers.equals(lastVers)) {
3104                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3105                    intent.setComponent(new ComponentName(
3106                            ri.activityInfo.packageName, ri.activityInfo.name));
3107                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3108                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3109                }
3110            }
3111        }
3112    }
3113
3114    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3115        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3116    }
3117
3118    void enforceNotIsolatedCaller(String caller) {
3119        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3120            throw new SecurityException("Isolated process not allowed to call " + caller);
3121        }
3122    }
3123
3124    @Override
3125    public int getFrontActivityScreenCompatMode() {
3126        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3127        synchronized (this) {
3128            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3129        }
3130    }
3131
3132    @Override
3133    public void setFrontActivityScreenCompatMode(int mode) {
3134        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3135                "setFrontActivityScreenCompatMode");
3136        synchronized (this) {
3137            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3138        }
3139    }
3140
3141    @Override
3142    public int getPackageScreenCompatMode(String packageName) {
3143        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3144        synchronized (this) {
3145            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3146        }
3147    }
3148
3149    @Override
3150    public void setPackageScreenCompatMode(String packageName, int mode) {
3151        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3152                "setPackageScreenCompatMode");
3153        synchronized (this) {
3154            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3155        }
3156    }
3157
3158    @Override
3159    public boolean getPackageAskScreenCompat(String packageName) {
3160        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3161        synchronized (this) {
3162            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3163        }
3164    }
3165
3166    @Override
3167    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3168        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3169                "setPackageAskScreenCompat");
3170        synchronized (this) {
3171            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3172        }
3173    }
3174
3175    private void dispatchProcessesChanged() {
3176        int N;
3177        synchronized (this) {
3178            N = mPendingProcessChanges.size();
3179            if (mActiveProcessChanges.length < N) {
3180                mActiveProcessChanges = new ProcessChangeItem[N];
3181            }
3182            mPendingProcessChanges.toArray(mActiveProcessChanges);
3183            mAvailProcessChanges.addAll(mPendingProcessChanges);
3184            mPendingProcessChanges.clear();
3185            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3186        }
3187
3188        int i = mProcessObservers.beginBroadcast();
3189        while (i > 0) {
3190            i--;
3191            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3192            if (observer != null) {
3193                try {
3194                    for (int j=0; j<N; j++) {
3195                        ProcessChangeItem item = mActiveProcessChanges[j];
3196                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3197                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3198                                    + item.pid + " uid=" + item.uid + ": "
3199                                    + item.foregroundActivities);
3200                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3201                                    item.foregroundActivities);
3202                        }
3203                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3204                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3205                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3206                            observer.onImportanceChanged(item.pid, item.uid,
3207                                    item.importance);
3208                        }
3209                    }
3210                } catch (RemoteException e) {
3211                }
3212            }
3213        }
3214        mProcessObservers.finishBroadcast();
3215    }
3216
3217    private void dispatchProcessDied(int pid, int uid) {
3218        int i = mProcessObservers.beginBroadcast();
3219        while (i > 0) {
3220            i--;
3221            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3222            if (observer != null) {
3223                try {
3224                    observer.onProcessDied(pid, uid);
3225                } catch (RemoteException e) {
3226                }
3227            }
3228        }
3229        mProcessObservers.finishBroadcast();
3230    }
3231
3232    final void doPendingActivityLaunchesLocked(boolean doResume) {
3233        final int N = mPendingActivityLaunches.size();
3234        if (N <= 0) {
3235            return;
3236        }
3237        for (int i=0; i<N; i++) {
3238            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3239            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3240                    doResume && i == (N-1), null);
3241        }
3242        mPendingActivityLaunches.clear();
3243    }
3244
3245    @Override
3246    public final int startActivity(IApplicationThread caller, String callingPackage,
3247            Intent intent, String resolvedType, IBinder resultTo,
3248            String resultWho, int requestCode, int startFlags,
3249            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3250        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3251                resultWho, requestCode,
3252                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3253    }
3254
3255    @Override
3256    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3257            Intent intent, String resolvedType, IBinder resultTo,
3258            String resultWho, int requestCode, int startFlags,
3259            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3260        enforceNotIsolatedCaller("startActivity");
3261        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3262                false, true, "startActivity", null);
3263        // TODO: Switch to user app stacks here.
3264        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3265                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3266                null, null, options, userId, null);
3267    }
3268
3269    @Override
3270    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3271            Intent intent, String resolvedType, IBinder resultTo,
3272            String resultWho, int requestCode, int startFlags, String profileFile,
3273            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3274        enforceNotIsolatedCaller("startActivityAndWait");
3275        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3276                false, true, "startActivityAndWait", null);
3277        WaitResult res = new WaitResult();
3278        // TODO: Switch to user app stacks here.
3279        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3280                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3281                res, null, options, UserHandle.getCallingUserId(), null);
3282        return res;
3283    }
3284
3285    @Override
3286    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3287            Intent intent, String resolvedType, IBinder resultTo,
3288            String resultWho, int requestCode, int startFlags, Configuration config,
3289            Bundle options, int userId) {
3290        enforceNotIsolatedCaller("startActivityWithConfig");
3291        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3292                false, true, "startActivityWithConfig", null);
3293        // TODO: Switch to user app stacks here.
3294        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3295                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3296                null, null, null, config, options, userId, null);
3297        return ret;
3298    }
3299
3300    @Override
3301    public int startActivityIntentSender(IApplicationThread caller,
3302            IntentSender intent, Intent fillInIntent, String resolvedType,
3303            IBinder resultTo, String resultWho, int requestCode,
3304            int flagsMask, int flagsValues, Bundle options) {
3305        enforceNotIsolatedCaller("startActivityIntentSender");
3306        // Refuse possible leaked file descriptors
3307        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3308            throw new IllegalArgumentException("File descriptors passed in Intent");
3309        }
3310
3311        IIntentSender sender = intent.getTarget();
3312        if (!(sender instanceof PendingIntentRecord)) {
3313            throw new IllegalArgumentException("Bad PendingIntent object");
3314        }
3315
3316        PendingIntentRecord pir = (PendingIntentRecord)sender;
3317
3318        synchronized (this) {
3319            // If this is coming from the currently resumed activity, it is
3320            // effectively saying that app switches are allowed at this point.
3321            final ActivityStack stack = getFocusedStack();
3322            if (stack.mResumedActivity != null &&
3323                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3324                mAppSwitchesAllowedTime = 0;
3325            }
3326        }
3327        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3328                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3329        return ret;
3330    }
3331
3332    @Override
3333    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3334            Intent intent, String resolvedType, IVoiceInteractionSession session,
3335            IVoiceInteractor interactor, int startFlags, String profileFile,
3336            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3337        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3338                != PackageManager.PERMISSION_GRANTED) {
3339            String msg = "Permission Denial: startVoiceActivity() from pid="
3340                    + Binder.getCallingPid()
3341                    + ", uid=" + Binder.getCallingUid()
3342                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3343            Slog.w(TAG, msg);
3344            throw new SecurityException(msg);
3345        }
3346        if (session == null || interactor == null) {
3347            throw new NullPointerException("null session or interactor");
3348        }
3349        userId = handleIncomingUser(callingPid, callingUid, userId,
3350                false, true, "startVoiceActivity", null);
3351        // TODO: Switch to user app stacks here.
3352        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3353                resolvedType, session, interactor, null, null, 0, startFlags,
3354                profileFile, profileFd, null, null, options, userId, null);
3355    }
3356
3357    @Override
3358    public boolean startNextMatchingActivity(IBinder callingActivity,
3359            Intent intent, Bundle options) {
3360        // Refuse possible leaked file descriptors
3361        if (intent != null && intent.hasFileDescriptors() == true) {
3362            throw new IllegalArgumentException("File descriptors passed in Intent");
3363        }
3364
3365        synchronized (this) {
3366            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3367            if (r == null) {
3368                ActivityOptions.abort(options);
3369                return false;
3370            }
3371            if (r.app == null || r.app.thread == null) {
3372                // The caller is not running...  d'oh!
3373                ActivityOptions.abort(options);
3374                return false;
3375            }
3376            intent = new Intent(intent);
3377            // The caller is not allowed to change the data.
3378            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3379            // And we are resetting to find the next component...
3380            intent.setComponent(null);
3381
3382            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3383
3384            ActivityInfo aInfo = null;
3385            try {
3386                List<ResolveInfo> resolves =
3387                    AppGlobals.getPackageManager().queryIntentActivities(
3388                            intent, r.resolvedType,
3389                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3390                            UserHandle.getCallingUserId());
3391
3392                // Look for the original activity in the list...
3393                final int N = resolves != null ? resolves.size() : 0;
3394                for (int i=0; i<N; i++) {
3395                    ResolveInfo rInfo = resolves.get(i);
3396                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3397                            && rInfo.activityInfo.name.equals(r.info.name)) {
3398                        // We found the current one...  the next matching is
3399                        // after it.
3400                        i++;
3401                        if (i<N) {
3402                            aInfo = resolves.get(i).activityInfo;
3403                        }
3404                        if (debug) {
3405                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3406                                    + "/" + r.info.name);
3407                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3408                                    + "/" + aInfo.name);
3409                        }
3410                        break;
3411                    }
3412                }
3413            } catch (RemoteException e) {
3414            }
3415
3416            if (aInfo == null) {
3417                // Nobody who is next!
3418                ActivityOptions.abort(options);
3419                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3420                return false;
3421            }
3422
3423            intent.setComponent(new ComponentName(
3424                    aInfo.applicationInfo.packageName, aInfo.name));
3425            intent.setFlags(intent.getFlags()&~(
3426                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3427                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3428                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3429                    Intent.FLAG_ACTIVITY_NEW_TASK));
3430
3431            // Okay now we need to start the new activity, replacing the
3432            // currently running activity.  This is a little tricky because
3433            // we want to start the new one as if the current one is finished,
3434            // but not finish the current one first so that there is no flicker.
3435            // And thus...
3436            final boolean wasFinishing = r.finishing;
3437            r.finishing = true;
3438
3439            // Propagate reply information over to the new activity.
3440            final ActivityRecord resultTo = r.resultTo;
3441            final String resultWho = r.resultWho;
3442            final int requestCode = r.requestCode;
3443            r.resultTo = null;
3444            if (resultTo != null) {
3445                resultTo.removeResultsLocked(r, resultWho, requestCode);
3446            }
3447
3448            final long origId = Binder.clearCallingIdentity();
3449            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3450                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3451                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3452                    options, false, null, null);
3453            Binder.restoreCallingIdentity(origId);
3454
3455            r.finishing = wasFinishing;
3456            if (res != ActivityManager.START_SUCCESS) {
3457                return false;
3458            }
3459            return true;
3460        }
3461    }
3462
3463    final int startActivityInPackage(int uid, String callingPackage,
3464            Intent intent, String resolvedType, IBinder resultTo,
3465            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3466                    IActivityContainer container) {
3467
3468        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3469                false, true, "startActivityInPackage", null);
3470
3471        // TODO: Switch to user app stacks here.
3472        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3473                null, null, resultTo, resultWho, requestCode, startFlags,
3474                null, null, null, null, options, userId, container);
3475        return ret;
3476    }
3477
3478    @Override
3479    public final int startActivities(IApplicationThread caller, String callingPackage,
3480            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3481            int userId) {
3482        enforceNotIsolatedCaller("startActivities");
3483        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3484                false, true, "startActivity", null);
3485        // TODO: Switch to user app stacks here.
3486        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3487                resolvedTypes, resultTo, options, userId);
3488        return ret;
3489    }
3490
3491    final int startActivitiesInPackage(int uid, String callingPackage,
3492            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3493            Bundle options, int userId) {
3494
3495        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3496                false, true, "startActivityInPackage", null);
3497        // TODO: Switch to user app stacks here.
3498        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3499                resultTo, options, userId);
3500        return ret;
3501    }
3502
3503    final void addRecentTaskLocked(TaskRecord task) {
3504        int N = mRecentTasks.size();
3505        // Quick case: check if the top-most recent task is the same.
3506        if (N > 0 && mRecentTasks.get(0) == task) {
3507            return;
3508        }
3509        // Another quick case: never add voice sessions.
3510        if (task.voiceSession != null) {
3511            return;
3512        }
3513        // Remove any existing entries that are the same kind of task.
3514        final Intent intent = task.intent;
3515        final boolean document = intent != null && intent.isDocument();
3516        for (int i=0; i<N; i++) {
3517            TaskRecord tr = mRecentTasks.get(i);
3518            if (task != tr) {
3519                if (task.userId != tr.userId) {
3520                    continue;
3521                }
3522                final Intent trIntent = tr.intent;
3523                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3524                    (intent == null || !intent.filterEquals(trIntent))) {
3525                    continue;
3526                }
3527                if (document || trIntent != null && trIntent.isDocument()) {
3528                    // Document tasks do not match other tasks.
3529                    continue;
3530                }
3531            }
3532
3533            // Either task and tr are the same or, their affinities match or their intents match
3534            // and neither of them is a document.
3535            tr.disposeThumbnail();
3536            mRecentTasks.remove(i);
3537            i--;
3538            N--;
3539            if (task.intent == null) {
3540                // If the new recent task we are adding is not fully
3541                // specified, then replace it with the existing recent task.
3542                task = tr;
3543            }
3544        }
3545        if (N >= MAX_RECENT_TASKS) {
3546            mRecentTasks.remove(N-1).disposeThumbnail();
3547        }
3548        mRecentTasks.add(0, task);
3549    }
3550
3551    @Override
3552    public void reportActivityFullyDrawn(IBinder token) {
3553        synchronized (this) {
3554            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3555            if (r == null) {
3556                return;
3557            }
3558            r.reportFullyDrawnLocked();
3559        }
3560    }
3561
3562    @Override
3563    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3564        synchronized (this) {
3565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3566            if (r == null) {
3567                return;
3568            }
3569            final long origId = Binder.clearCallingIdentity();
3570            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3571            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3572                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3573            if (config != null) {
3574                r.frozenBeforeDestroy = true;
3575                if (!updateConfigurationLocked(config, r, false, false)) {
3576                    mStackSupervisor.resumeTopActivitiesLocked();
3577                }
3578            }
3579            Binder.restoreCallingIdentity(origId);
3580        }
3581    }
3582
3583    @Override
3584    public int getRequestedOrientation(IBinder token) {
3585        synchronized (this) {
3586            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3587            if (r == null) {
3588                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3589            }
3590            return mWindowManager.getAppOrientation(r.appToken);
3591        }
3592    }
3593
3594    /**
3595     * This is the internal entry point for handling Activity.finish().
3596     *
3597     * @param token The Binder token referencing the Activity we want to finish.
3598     * @param resultCode Result code, if any, from this Activity.
3599     * @param resultData Result data (Intent), if any, from this Activity.
3600     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3601     *            the root Activity in the task.
3602     *
3603     * @return Returns true if the activity successfully finished, or false if it is still running.
3604     */
3605    @Override
3606    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3607            boolean finishTask) {
3608        // Refuse possible leaked file descriptors
3609        if (resultData != null && resultData.hasFileDescriptors() == true) {
3610            throw new IllegalArgumentException("File descriptors passed in Intent");
3611        }
3612
3613        synchronized(this) {
3614            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3615            if (r == null) {
3616                return true;
3617            }
3618            // Keep track of the root activity of the task before we finish it
3619            TaskRecord tr = r.task;
3620            ActivityRecord rootR = tr.getRootActivity();
3621            if (mController != null) {
3622                // Find the first activity that is not finishing.
3623                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3624                if (next != null) {
3625                    // ask watcher if this is allowed
3626                    boolean resumeOK = true;
3627                    try {
3628                        resumeOK = mController.activityResuming(next.packageName);
3629                    } catch (RemoteException e) {
3630                        mController = null;
3631                        Watchdog.getInstance().setActivityController(null);
3632                    }
3633
3634                    if (!resumeOK) {
3635                        return false;
3636                    }
3637                }
3638            }
3639            final long origId = Binder.clearCallingIdentity();
3640            try {
3641                boolean res;
3642                if (finishTask && r == rootR) {
3643                    // If requested, remove the task that is associated to this activity only if it
3644                    // was the root activity in the task.  The result code and data is ignored because
3645                    // we don't support returning them across task boundaries.
3646                    res = removeTaskByIdLocked(tr.taskId, 0);
3647                } else {
3648                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3649                            resultData, "app-request", true);
3650                }
3651                return res;
3652            } finally {
3653                Binder.restoreCallingIdentity(origId);
3654            }
3655        }
3656    }
3657
3658    @Override
3659    public final void finishHeavyWeightApp() {
3660        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3661                != PackageManager.PERMISSION_GRANTED) {
3662            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3663                    + Binder.getCallingPid()
3664                    + ", uid=" + Binder.getCallingUid()
3665                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3666            Slog.w(TAG, msg);
3667            throw new SecurityException(msg);
3668        }
3669
3670        synchronized(this) {
3671            if (mHeavyWeightProcess == null) {
3672                return;
3673            }
3674
3675            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3676                    mHeavyWeightProcess.activities);
3677            for (int i=0; i<activities.size(); i++) {
3678                ActivityRecord r = activities.get(i);
3679                if (!r.finishing) {
3680                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3681                            null, "finish-heavy", true);
3682                }
3683            }
3684
3685            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3686                    mHeavyWeightProcess.userId, 0));
3687            mHeavyWeightProcess = null;
3688        }
3689    }
3690
3691    @Override
3692    public void crashApplication(int uid, int initialPid, String packageName,
3693            String message) {
3694        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3695                != PackageManager.PERMISSION_GRANTED) {
3696            String msg = "Permission Denial: crashApplication() from pid="
3697                    + Binder.getCallingPid()
3698                    + ", uid=" + Binder.getCallingUid()
3699                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3700            Slog.w(TAG, msg);
3701            throw new SecurityException(msg);
3702        }
3703
3704        synchronized(this) {
3705            ProcessRecord proc = null;
3706
3707            // Figure out which process to kill.  We don't trust that initialPid
3708            // still has any relation to current pids, so must scan through the
3709            // list.
3710            synchronized (mPidsSelfLocked) {
3711                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3712                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3713                    if (p.uid != uid) {
3714                        continue;
3715                    }
3716                    if (p.pid == initialPid) {
3717                        proc = p;
3718                        break;
3719                    }
3720                    if (p.pkgList.containsKey(packageName)) {
3721                        proc = p;
3722                    }
3723                }
3724            }
3725
3726            if (proc == null) {
3727                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3728                        + " initialPid=" + initialPid
3729                        + " packageName=" + packageName);
3730                return;
3731            }
3732
3733            if (proc.thread != null) {
3734                if (proc.pid == Process.myPid()) {
3735                    Log.w(TAG, "crashApplication: trying to crash self!");
3736                    return;
3737                }
3738                long ident = Binder.clearCallingIdentity();
3739                try {
3740                    proc.thread.scheduleCrash(message);
3741                } catch (RemoteException e) {
3742                }
3743                Binder.restoreCallingIdentity(ident);
3744            }
3745        }
3746    }
3747
3748    @Override
3749    public final void finishSubActivity(IBinder token, String resultWho,
3750            int requestCode) {
3751        synchronized(this) {
3752            final long origId = Binder.clearCallingIdentity();
3753            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3754            if (r != null) {
3755                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3756            }
3757            Binder.restoreCallingIdentity(origId);
3758        }
3759    }
3760
3761    @Override
3762    public boolean finishActivityAffinity(IBinder token) {
3763        synchronized(this) {
3764            final long origId = Binder.clearCallingIdentity();
3765            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3766            boolean res = false;
3767            if (r != null) {
3768                res = r.task.stack.finishActivityAffinityLocked(r);
3769            }
3770            Binder.restoreCallingIdentity(origId);
3771            return res;
3772        }
3773    }
3774
3775    @Override
3776    public boolean willActivityBeVisible(IBinder token) {
3777        synchronized(this) {
3778            ActivityStack stack = ActivityRecord.getStackLocked(token);
3779            if (stack != null) {
3780                return stack.willActivityBeVisibleLocked(token);
3781            }
3782            return false;
3783        }
3784    }
3785
3786    @Override
3787    public void overridePendingTransition(IBinder token, String packageName,
3788            int enterAnim, int exitAnim) {
3789        synchronized(this) {
3790            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3791            if (self == null) {
3792                return;
3793            }
3794
3795            final long origId = Binder.clearCallingIdentity();
3796
3797            if (self.state == ActivityState.RESUMED
3798                    || self.state == ActivityState.PAUSING) {
3799                mWindowManager.overridePendingAppTransition(packageName,
3800                        enterAnim, exitAnim, null);
3801            }
3802
3803            Binder.restoreCallingIdentity(origId);
3804        }
3805    }
3806
3807    /**
3808     * Main function for removing an existing process from the activity manager
3809     * as a result of that process going away.  Clears out all connections
3810     * to the process.
3811     */
3812    private final void handleAppDiedLocked(ProcessRecord app,
3813            boolean restarting, boolean allowRestart) {
3814        int pid = app.pid;
3815        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3816        if (!restarting) {
3817            removeLruProcessLocked(app);
3818            if (pid > 0) {
3819                ProcessList.remove(pid);
3820            }
3821        }
3822
3823        if (mProfileProc == app) {
3824            clearProfilerLocked();
3825        }
3826
3827        // Remove this application's activities from active lists.
3828        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3829
3830        app.activities.clear();
3831
3832        if (app.instrumentationClass != null) {
3833            Slog.w(TAG, "Crash of app " + app.processName
3834                  + " running instrumentation " + app.instrumentationClass);
3835            Bundle info = new Bundle();
3836            info.putString("shortMsg", "Process crashed.");
3837            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3838        }
3839
3840        if (!restarting) {
3841            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3842                // If there was nothing to resume, and we are not already
3843                // restarting this process, but there is a visible activity that
3844                // is hosted by the process...  then make sure all visible
3845                // activities are running, taking care of restarting this
3846                // process.
3847                if (hasVisibleActivities) {
3848                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3849                }
3850            }
3851        }
3852    }
3853
3854    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3855        IBinder threadBinder = thread.asBinder();
3856        // Find the application record.
3857        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3858            ProcessRecord rec = mLruProcesses.get(i);
3859            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3860                return i;
3861            }
3862        }
3863        return -1;
3864    }
3865
3866    final ProcessRecord getRecordForAppLocked(
3867            IApplicationThread thread) {
3868        if (thread == null) {
3869            return null;
3870        }
3871
3872        int appIndex = getLRURecordIndexForAppLocked(thread);
3873        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3874    }
3875
3876    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3877        // If there are no longer any background processes running,
3878        // and the app that died was not running instrumentation,
3879        // then tell everyone we are now low on memory.
3880        boolean haveBg = false;
3881        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3882            ProcessRecord rec = mLruProcesses.get(i);
3883            if (rec.thread != null
3884                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3885                haveBg = true;
3886                break;
3887            }
3888        }
3889
3890        if (!haveBg) {
3891            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3892            if (doReport) {
3893                long now = SystemClock.uptimeMillis();
3894                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3895                    doReport = false;
3896                } else {
3897                    mLastMemUsageReportTime = now;
3898                }
3899            }
3900            final ArrayList<ProcessMemInfo> memInfos
3901                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3902            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3903            long now = SystemClock.uptimeMillis();
3904            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3905                ProcessRecord rec = mLruProcesses.get(i);
3906                if (rec == dyingProc || rec.thread == null) {
3907                    continue;
3908                }
3909                if (doReport) {
3910                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3911                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3912                }
3913                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3914                    // The low memory report is overriding any current
3915                    // state for a GC request.  Make sure to do
3916                    // heavy/important/visible/foreground processes first.
3917                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3918                        rec.lastRequestedGc = 0;
3919                    } else {
3920                        rec.lastRequestedGc = rec.lastLowMemory;
3921                    }
3922                    rec.reportLowMemory = true;
3923                    rec.lastLowMemory = now;
3924                    mProcessesToGc.remove(rec);
3925                    addProcessToGcListLocked(rec);
3926                }
3927            }
3928            if (doReport) {
3929                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3930                mHandler.sendMessage(msg);
3931            }
3932            scheduleAppGcsLocked();
3933        }
3934    }
3935
3936    final void appDiedLocked(ProcessRecord app, int pid,
3937            IApplicationThread thread) {
3938
3939        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3940        synchronized (stats) {
3941            stats.noteProcessDiedLocked(app.info.uid, pid);
3942        }
3943
3944        // Clean up already done if the process has been re-started.
3945        if (app.pid == pid && app.thread != null &&
3946                app.thread.asBinder() == thread.asBinder()) {
3947            boolean doLowMem = app.instrumentationClass == null;
3948            boolean doOomAdj = doLowMem;
3949            if (!app.killedByAm) {
3950                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3951                        + ") has died.");
3952                mAllowLowerMemLevel = true;
3953            } else {
3954                // Note that we always want to do oom adj to update our state with the
3955                // new number of procs.
3956                mAllowLowerMemLevel = false;
3957                doLowMem = false;
3958            }
3959            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3960            if (DEBUG_CLEANUP) Slog.v(
3961                TAG, "Dying app: " + app + ", pid: " + pid
3962                + ", thread: " + thread.asBinder());
3963            handleAppDiedLocked(app, false, true);
3964
3965            if (doOomAdj) {
3966                updateOomAdjLocked();
3967            }
3968            if (doLowMem) {
3969                doLowMemReportIfNeededLocked(app);
3970            }
3971        } else if (app.pid != pid) {
3972            // A new process has already been started.
3973            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3974                    + ") has died and restarted (pid " + app.pid + ").");
3975            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3976        } else if (DEBUG_PROCESSES) {
3977            Slog.d(TAG, "Received spurious death notification for thread "
3978                    + thread.asBinder());
3979        }
3980    }
3981
3982    /**
3983     * If a stack trace dump file is configured, dump process stack traces.
3984     * @param clearTraces causes the dump file to be erased prior to the new
3985     *    traces being written, if true; when false, the new traces will be
3986     *    appended to any existing file content.
3987     * @param firstPids of dalvik VM processes to dump stack traces for first
3988     * @param lastPids of dalvik VM processes to dump stack traces for last
3989     * @param nativeProcs optional list of native process names to dump stack crawls
3990     * @return file containing stack traces, or null if no dump file is configured
3991     */
3992    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3993            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3994        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3995        if (tracesPath == null || tracesPath.length() == 0) {
3996            return null;
3997        }
3998
3999        File tracesFile = new File(tracesPath);
4000        try {
4001            File tracesDir = tracesFile.getParentFile();
4002            if (!tracesDir.exists()) {
4003                tracesFile.mkdirs();
4004                if (!SELinux.restorecon(tracesDir)) {
4005                    return null;
4006                }
4007            }
4008            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4009
4010            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4011            tracesFile.createNewFile();
4012            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4013        } catch (IOException e) {
4014            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4015            return null;
4016        }
4017
4018        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4019        return tracesFile;
4020    }
4021
4022    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4023            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4024        // Use a FileObserver to detect when traces finish writing.
4025        // The order of traces is considered important to maintain for legibility.
4026        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4027            @Override
4028            public synchronized void onEvent(int event, String path) { notify(); }
4029        };
4030
4031        try {
4032            observer.startWatching();
4033
4034            // First collect all of the stacks of the most important pids.
4035            if (firstPids != null) {
4036                try {
4037                    int num = firstPids.size();
4038                    for (int i = 0; i < num; i++) {
4039                        synchronized (observer) {
4040                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4041                            observer.wait(200);  // Wait for write-close, give up after 200msec
4042                        }
4043                    }
4044                } catch (InterruptedException e) {
4045                    Log.wtf(TAG, e);
4046                }
4047            }
4048
4049            // Next collect the stacks of the native pids
4050            if (nativeProcs != null) {
4051                int[] pids = Process.getPidsForCommands(nativeProcs);
4052                if (pids != null) {
4053                    for (int pid : pids) {
4054                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4055                    }
4056                }
4057            }
4058
4059            // Lastly, measure CPU usage.
4060            if (processCpuTracker != null) {
4061                processCpuTracker.init();
4062                System.gc();
4063                processCpuTracker.update();
4064                try {
4065                    synchronized (processCpuTracker) {
4066                        processCpuTracker.wait(500); // measure over 1/2 second.
4067                    }
4068                } catch (InterruptedException e) {
4069                }
4070                processCpuTracker.update();
4071
4072                // We'll take the stack crawls of just the top apps using CPU.
4073                final int N = processCpuTracker.countWorkingStats();
4074                int numProcs = 0;
4075                for (int i=0; i<N && numProcs<5; i++) {
4076                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4077                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4078                        numProcs++;
4079                        try {
4080                            synchronized (observer) {
4081                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4082                                observer.wait(200);  // Wait for write-close, give up after 200msec
4083                            }
4084                        } catch (InterruptedException e) {
4085                            Log.wtf(TAG, e);
4086                        }
4087
4088                    }
4089                }
4090            }
4091        } finally {
4092            observer.stopWatching();
4093        }
4094    }
4095
4096    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4097        if (true || IS_USER_BUILD) {
4098            return;
4099        }
4100        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4101        if (tracesPath == null || tracesPath.length() == 0) {
4102            return;
4103        }
4104
4105        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4106        StrictMode.allowThreadDiskWrites();
4107        try {
4108            final File tracesFile = new File(tracesPath);
4109            final File tracesDir = tracesFile.getParentFile();
4110            final File tracesTmp = new File(tracesDir, "__tmp__");
4111            try {
4112                if (!tracesDir.exists()) {
4113                    tracesFile.mkdirs();
4114                    if (!SELinux.restorecon(tracesDir.getPath())) {
4115                        return;
4116                    }
4117                }
4118                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4119
4120                if (tracesFile.exists()) {
4121                    tracesTmp.delete();
4122                    tracesFile.renameTo(tracesTmp);
4123                }
4124                StringBuilder sb = new StringBuilder();
4125                Time tobj = new Time();
4126                tobj.set(System.currentTimeMillis());
4127                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4128                sb.append(": ");
4129                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4130                sb.append(" since ");
4131                sb.append(msg);
4132                FileOutputStream fos = new FileOutputStream(tracesFile);
4133                fos.write(sb.toString().getBytes());
4134                if (app == null) {
4135                    fos.write("\n*** No application process!".getBytes());
4136                }
4137                fos.close();
4138                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4139            } catch (IOException e) {
4140                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4141                return;
4142            }
4143
4144            if (app != null) {
4145                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4146                firstPids.add(app.pid);
4147                dumpStackTraces(tracesPath, firstPids, null, null, null);
4148            }
4149
4150            File lastTracesFile = null;
4151            File curTracesFile = null;
4152            for (int i=9; i>=0; i--) {
4153                String name = String.format(Locale.US, "slow%02d.txt", i);
4154                curTracesFile = new File(tracesDir, name);
4155                if (curTracesFile.exists()) {
4156                    if (lastTracesFile != null) {
4157                        curTracesFile.renameTo(lastTracesFile);
4158                    } else {
4159                        curTracesFile.delete();
4160                    }
4161                }
4162                lastTracesFile = curTracesFile;
4163            }
4164            tracesFile.renameTo(curTracesFile);
4165            if (tracesTmp.exists()) {
4166                tracesTmp.renameTo(tracesFile);
4167            }
4168        } finally {
4169            StrictMode.setThreadPolicy(oldPolicy);
4170        }
4171    }
4172
4173    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4174            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4175        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4176        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4177
4178        if (mController != null) {
4179            try {
4180                // 0 == continue, -1 = kill process immediately
4181                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4182                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4183            } catch (RemoteException e) {
4184                mController = null;
4185                Watchdog.getInstance().setActivityController(null);
4186            }
4187        }
4188
4189        long anrTime = SystemClock.uptimeMillis();
4190        if (MONITOR_CPU_USAGE) {
4191            updateCpuStatsNow();
4192        }
4193
4194        synchronized (this) {
4195            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4196            if (mShuttingDown) {
4197                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4198                return;
4199            } else if (app.notResponding) {
4200                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4201                return;
4202            } else if (app.crashing) {
4203                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4204                return;
4205            }
4206
4207            // In case we come through here for the same app before completing
4208            // this one, mark as anring now so we will bail out.
4209            app.notResponding = true;
4210
4211            // Log the ANR to the event log.
4212            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4213                    app.processName, app.info.flags, annotation);
4214
4215            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4216            firstPids.add(app.pid);
4217
4218            int parentPid = app.pid;
4219            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4220            if (parentPid != app.pid) firstPids.add(parentPid);
4221
4222            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4223
4224            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4225                ProcessRecord r = mLruProcesses.get(i);
4226                if (r != null && r.thread != null) {
4227                    int pid = r.pid;
4228                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4229                        if (r.persistent) {
4230                            firstPids.add(pid);
4231                        } else {
4232                            lastPids.put(pid, Boolean.TRUE);
4233                        }
4234                    }
4235                }
4236            }
4237        }
4238
4239        // Log the ANR to the main log.
4240        StringBuilder info = new StringBuilder();
4241        info.setLength(0);
4242        info.append("ANR in ").append(app.processName);
4243        if (activity != null && activity.shortComponentName != null) {
4244            info.append(" (").append(activity.shortComponentName).append(")");
4245        }
4246        info.append("\n");
4247        info.append("PID: ").append(app.pid).append("\n");
4248        if (annotation != null) {
4249            info.append("Reason: ").append(annotation).append("\n");
4250        }
4251        if (parent != null && parent != activity) {
4252            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4253        }
4254
4255        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4256
4257        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4258                NATIVE_STACKS_OF_INTEREST);
4259
4260        String cpuInfo = null;
4261        if (MONITOR_CPU_USAGE) {
4262            updateCpuStatsNow();
4263            synchronized (mProcessCpuThread) {
4264                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4265            }
4266            info.append(processCpuTracker.printCurrentLoad());
4267            info.append(cpuInfo);
4268        }
4269
4270        info.append(processCpuTracker.printCurrentState(anrTime));
4271
4272        Slog.e(TAG, info.toString());
4273        if (tracesFile == null) {
4274            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4275            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4276        }
4277
4278        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4279                cpuInfo, tracesFile, null);
4280
4281        if (mController != null) {
4282            try {
4283                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4284                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4285                if (res != 0) {
4286                    if (res < 0 && app.pid != MY_PID) {
4287                        Process.killProcess(app.pid);
4288                    } else {
4289                        synchronized (this) {
4290                            mServices.scheduleServiceTimeoutLocked(app);
4291                        }
4292                    }
4293                    return;
4294                }
4295            } catch (RemoteException e) {
4296                mController = null;
4297                Watchdog.getInstance().setActivityController(null);
4298            }
4299        }
4300
4301        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4302        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4303                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4304
4305        synchronized (this) {
4306            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4307                killUnneededProcessLocked(app, "background ANR");
4308                return;
4309            }
4310
4311            // Set the app's notResponding state, and look up the errorReportReceiver
4312            makeAppNotRespondingLocked(app,
4313                    activity != null ? activity.shortComponentName : null,
4314                    annotation != null ? "ANR " + annotation : "ANR",
4315                    info.toString());
4316
4317            // Bring up the infamous App Not Responding dialog
4318            Message msg = Message.obtain();
4319            HashMap<String, Object> map = new HashMap<String, Object>();
4320            msg.what = SHOW_NOT_RESPONDING_MSG;
4321            msg.obj = map;
4322            msg.arg1 = aboveSystem ? 1 : 0;
4323            map.put("app", app);
4324            if (activity != null) {
4325                map.put("activity", activity);
4326            }
4327
4328            mHandler.sendMessage(msg);
4329        }
4330    }
4331
4332    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4333        if (!mLaunchWarningShown) {
4334            mLaunchWarningShown = true;
4335            mHandler.post(new Runnable() {
4336                @Override
4337                public void run() {
4338                    synchronized (ActivityManagerService.this) {
4339                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4340                        d.show();
4341                        mHandler.postDelayed(new Runnable() {
4342                            @Override
4343                            public void run() {
4344                                synchronized (ActivityManagerService.this) {
4345                                    d.dismiss();
4346                                    mLaunchWarningShown = false;
4347                                }
4348                            }
4349                        }, 4000);
4350                    }
4351                }
4352            });
4353        }
4354    }
4355
4356    @Override
4357    public boolean clearApplicationUserData(final String packageName,
4358            final IPackageDataObserver observer, int userId) {
4359        enforceNotIsolatedCaller("clearApplicationUserData");
4360        int uid = Binder.getCallingUid();
4361        int pid = Binder.getCallingPid();
4362        userId = handleIncomingUser(pid, uid,
4363                userId, false, true, "clearApplicationUserData", null);
4364        long callingId = Binder.clearCallingIdentity();
4365        try {
4366            IPackageManager pm = AppGlobals.getPackageManager();
4367            int pkgUid = -1;
4368            synchronized(this) {
4369                try {
4370                    pkgUid = pm.getPackageUid(packageName, userId);
4371                } catch (RemoteException e) {
4372                }
4373                if (pkgUid == -1) {
4374                    Slog.w(TAG, "Invalid packageName: " + packageName);
4375                    if (observer != null) {
4376                        try {
4377                            observer.onRemoveCompleted(packageName, false);
4378                        } catch (RemoteException e) {
4379                            Slog.i(TAG, "Observer no longer exists.");
4380                        }
4381                    }
4382                    return false;
4383                }
4384                if (uid == pkgUid || checkComponentPermission(
4385                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4386                        pid, uid, -1, true)
4387                        == PackageManager.PERMISSION_GRANTED) {
4388                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4389                } else {
4390                    throw new SecurityException("PID " + pid + " does not have permission "
4391                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4392                                    + " of package " + packageName);
4393                }
4394            }
4395
4396            try {
4397                // Clear application user data
4398                pm.clearApplicationUserData(packageName, observer, userId);
4399
4400                // Remove all permissions granted from/to this package
4401                removeUriPermissionsForPackageLocked(packageName, userId, true);
4402
4403                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4404                        Uri.fromParts("package", packageName, null));
4405                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4406                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4407                        null, null, 0, null, null, null, false, false, userId);
4408            } catch (RemoteException e) {
4409            }
4410        } finally {
4411            Binder.restoreCallingIdentity(callingId);
4412        }
4413        return true;
4414    }
4415
4416    @Override
4417    public void killBackgroundProcesses(final String packageName, int userId) {
4418        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4419                != PackageManager.PERMISSION_GRANTED &&
4420                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4421                        != PackageManager.PERMISSION_GRANTED) {
4422            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4423                    + Binder.getCallingPid()
4424                    + ", uid=" + Binder.getCallingUid()
4425                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4426            Slog.w(TAG, msg);
4427            throw new SecurityException(msg);
4428        }
4429
4430        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4431                userId, true, true, "killBackgroundProcesses", null);
4432        long callingId = Binder.clearCallingIdentity();
4433        try {
4434            IPackageManager pm = AppGlobals.getPackageManager();
4435            synchronized(this) {
4436                int appId = -1;
4437                try {
4438                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4439                } catch (RemoteException e) {
4440                }
4441                if (appId == -1) {
4442                    Slog.w(TAG, "Invalid packageName: " + packageName);
4443                    return;
4444                }
4445                killPackageProcessesLocked(packageName, appId, userId,
4446                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4447            }
4448        } finally {
4449            Binder.restoreCallingIdentity(callingId);
4450        }
4451    }
4452
4453    @Override
4454    public void killAllBackgroundProcesses() {
4455        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4456                != PackageManager.PERMISSION_GRANTED) {
4457            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4458                    + Binder.getCallingPid()
4459                    + ", uid=" + Binder.getCallingUid()
4460                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4461            Slog.w(TAG, msg);
4462            throw new SecurityException(msg);
4463        }
4464
4465        long callingId = Binder.clearCallingIdentity();
4466        try {
4467            synchronized(this) {
4468                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4469                final int NP = mProcessNames.getMap().size();
4470                for (int ip=0; ip<NP; ip++) {
4471                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4472                    final int NA = apps.size();
4473                    for (int ia=0; ia<NA; ia++) {
4474                        ProcessRecord app = apps.valueAt(ia);
4475                        if (app.persistent) {
4476                            // we don't kill persistent processes
4477                            continue;
4478                        }
4479                        if (app.removed) {
4480                            procs.add(app);
4481                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4482                            app.removed = true;
4483                            procs.add(app);
4484                        }
4485                    }
4486                }
4487
4488                int N = procs.size();
4489                for (int i=0; i<N; i++) {
4490                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4491                }
4492                mAllowLowerMemLevel = true;
4493                updateOomAdjLocked();
4494                doLowMemReportIfNeededLocked(null);
4495            }
4496        } finally {
4497            Binder.restoreCallingIdentity(callingId);
4498        }
4499    }
4500
4501    @Override
4502    public void forceStopPackage(final String packageName, int userId) {
4503        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4504                != PackageManager.PERMISSION_GRANTED) {
4505            String msg = "Permission Denial: forceStopPackage() from pid="
4506                    + Binder.getCallingPid()
4507                    + ", uid=" + Binder.getCallingUid()
4508                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4509            Slog.w(TAG, msg);
4510            throw new SecurityException(msg);
4511        }
4512        final int callingPid = Binder.getCallingPid();
4513        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4514                userId, true, true, "forceStopPackage", null);
4515        long callingId = Binder.clearCallingIdentity();
4516        try {
4517            IPackageManager pm = AppGlobals.getPackageManager();
4518            synchronized(this) {
4519                int[] users = userId == UserHandle.USER_ALL
4520                        ? getUsersLocked() : new int[] { userId };
4521                for (int user : users) {
4522                    int pkgUid = -1;
4523                    try {
4524                        pkgUid = pm.getPackageUid(packageName, user);
4525                    } catch (RemoteException e) {
4526                    }
4527                    if (pkgUid == -1) {
4528                        Slog.w(TAG, "Invalid packageName: " + packageName);
4529                        continue;
4530                    }
4531                    try {
4532                        pm.setPackageStoppedState(packageName, true, user);
4533                    } catch (RemoteException e) {
4534                    } catch (IllegalArgumentException e) {
4535                        Slog.w(TAG, "Failed trying to unstop package "
4536                                + packageName + ": " + e);
4537                    }
4538                    if (isUserRunningLocked(user, false)) {
4539                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4540                    }
4541                }
4542            }
4543        } finally {
4544            Binder.restoreCallingIdentity(callingId);
4545        }
4546    }
4547
4548    /*
4549     * The pkg name and app id have to be specified.
4550     */
4551    @Override
4552    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4553        if (pkg == null) {
4554            return;
4555        }
4556        // Make sure the uid is valid.
4557        if (appid < 0) {
4558            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4559            return;
4560        }
4561        int callerUid = Binder.getCallingUid();
4562        // Only the system server can kill an application
4563        if (callerUid == Process.SYSTEM_UID) {
4564            // Post an aysnc message to kill the application
4565            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4566            msg.arg1 = appid;
4567            msg.arg2 = 0;
4568            Bundle bundle = new Bundle();
4569            bundle.putString("pkg", pkg);
4570            bundle.putString("reason", reason);
4571            msg.obj = bundle;
4572            mHandler.sendMessage(msg);
4573        } else {
4574            throw new SecurityException(callerUid + " cannot kill pkg: " +
4575                    pkg);
4576        }
4577    }
4578
4579    @Override
4580    public void closeSystemDialogs(String reason) {
4581        enforceNotIsolatedCaller("closeSystemDialogs");
4582
4583        final int pid = Binder.getCallingPid();
4584        final int uid = Binder.getCallingUid();
4585        final long origId = Binder.clearCallingIdentity();
4586        try {
4587            synchronized (this) {
4588                // Only allow this from foreground processes, so that background
4589                // applications can't abuse it to prevent system UI from being shown.
4590                if (uid >= Process.FIRST_APPLICATION_UID) {
4591                    ProcessRecord proc;
4592                    synchronized (mPidsSelfLocked) {
4593                        proc = mPidsSelfLocked.get(pid);
4594                    }
4595                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4596                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4597                                + " from background process " + proc);
4598                        return;
4599                    }
4600                }
4601                closeSystemDialogsLocked(reason);
4602            }
4603        } finally {
4604            Binder.restoreCallingIdentity(origId);
4605        }
4606    }
4607
4608    void closeSystemDialogsLocked(String reason) {
4609        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4610        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4611                | Intent.FLAG_RECEIVER_FOREGROUND);
4612        if (reason != null) {
4613            intent.putExtra("reason", reason);
4614        }
4615        mWindowManager.closeSystemDialogs(reason);
4616
4617        mStackSupervisor.closeSystemDialogsLocked();
4618
4619        broadcastIntentLocked(null, null, intent, null,
4620                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4621                Process.SYSTEM_UID, UserHandle.USER_ALL);
4622    }
4623
4624    @Override
4625    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4626        enforceNotIsolatedCaller("getProcessMemoryInfo");
4627        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4628        for (int i=pids.length-1; i>=0; i--) {
4629            ProcessRecord proc;
4630            int oomAdj;
4631            synchronized (this) {
4632                synchronized (mPidsSelfLocked) {
4633                    proc = mPidsSelfLocked.get(pids[i]);
4634                    oomAdj = proc != null ? proc.setAdj : 0;
4635                }
4636            }
4637            infos[i] = new Debug.MemoryInfo();
4638            Debug.getMemoryInfo(pids[i], infos[i]);
4639            if (proc != null) {
4640                synchronized (this) {
4641                    if (proc.thread != null && proc.setAdj == oomAdj) {
4642                        // Record this for posterity if the process has been stable.
4643                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4644                                infos[i].getTotalUss(), false, proc.pkgList);
4645                    }
4646                }
4647            }
4648        }
4649        return infos;
4650    }
4651
4652    @Override
4653    public long[] getProcessPss(int[] pids) {
4654        enforceNotIsolatedCaller("getProcessPss");
4655        long[] pss = new long[pids.length];
4656        for (int i=pids.length-1; i>=0; i--) {
4657            ProcessRecord proc;
4658            int oomAdj;
4659            synchronized (this) {
4660                synchronized (mPidsSelfLocked) {
4661                    proc = mPidsSelfLocked.get(pids[i]);
4662                    oomAdj = proc != null ? proc.setAdj : 0;
4663                }
4664            }
4665            long[] tmpUss = new long[1];
4666            pss[i] = Debug.getPss(pids[i], tmpUss);
4667            if (proc != null) {
4668                synchronized (this) {
4669                    if (proc.thread != null && proc.setAdj == oomAdj) {
4670                        // Record this for posterity if the process has been stable.
4671                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4672                    }
4673                }
4674            }
4675        }
4676        return pss;
4677    }
4678
4679    @Override
4680    public void killApplicationProcess(String processName, int uid) {
4681        if (processName == null) {
4682            return;
4683        }
4684
4685        int callerUid = Binder.getCallingUid();
4686        // Only the system server can kill an application
4687        if (callerUid == Process.SYSTEM_UID) {
4688            synchronized (this) {
4689                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4690                if (app != null && app.thread != null) {
4691                    try {
4692                        app.thread.scheduleSuicide();
4693                    } catch (RemoteException e) {
4694                        // If the other end already died, then our work here is done.
4695                    }
4696                } else {
4697                    Slog.w(TAG, "Process/uid not found attempting kill of "
4698                            + processName + " / " + uid);
4699                }
4700            }
4701        } else {
4702            throw new SecurityException(callerUid + " cannot kill app process: " +
4703                    processName);
4704        }
4705    }
4706
4707    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4708        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4709                false, true, false, false, UserHandle.getUserId(uid), reason);
4710        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4711                Uri.fromParts("package", packageName, null));
4712        if (!mProcessesReady) {
4713            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4714                    | Intent.FLAG_RECEIVER_FOREGROUND);
4715        }
4716        intent.putExtra(Intent.EXTRA_UID, uid);
4717        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4718        broadcastIntentLocked(null, null, intent,
4719                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4720                false, false,
4721                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4722    }
4723
4724    private void forceStopUserLocked(int userId, String reason) {
4725        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4726        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4727        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4728                | Intent.FLAG_RECEIVER_FOREGROUND);
4729        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4730        broadcastIntentLocked(null, null, intent,
4731                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4732                false, false,
4733                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4734    }
4735
4736    private final boolean killPackageProcessesLocked(String packageName, int appId,
4737            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4738            boolean doit, boolean evenPersistent, String reason) {
4739        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4740
4741        // Remove all processes this package may have touched: all with the
4742        // same UID (except for the system or root user), and all whose name
4743        // matches the package name.
4744        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4745        final int NP = mProcessNames.getMap().size();
4746        for (int ip=0; ip<NP; ip++) {
4747            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4748            final int NA = apps.size();
4749            for (int ia=0; ia<NA; ia++) {
4750                ProcessRecord app = apps.valueAt(ia);
4751                if (app.persistent && !evenPersistent) {
4752                    // we don't kill persistent processes
4753                    continue;
4754                }
4755                if (app.removed) {
4756                    if (doit) {
4757                        procs.add(app);
4758                    }
4759                    continue;
4760                }
4761
4762                // Skip process if it doesn't meet our oom adj requirement.
4763                if (app.setAdj < minOomAdj) {
4764                    continue;
4765                }
4766
4767                // If no package is specified, we call all processes under the
4768                // give user id.
4769                if (packageName == null) {
4770                    if (app.userId != userId) {
4771                        continue;
4772                    }
4773                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4774                        continue;
4775                    }
4776                // Package has been specified, we want to hit all processes
4777                // that match it.  We need to qualify this by the processes
4778                // that are running under the specified app and user ID.
4779                } else {
4780                    if (UserHandle.getAppId(app.uid) != appId) {
4781                        continue;
4782                    }
4783                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4784                        continue;
4785                    }
4786                    if (!app.pkgList.containsKey(packageName)) {
4787                        continue;
4788                    }
4789                }
4790
4791                // Process has passed all conditions, kill it!
4792                if (!doit) {
4793                    return true;
4794                }
4795                app.removed = true;
4796                procs.add(app);
4797            }
4798        }
4799
4800        int N = procs.size();
4801        for (int i=0; i<N; i++) {
4802            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4803        }
4804        updateOomAdjLocked();
4805        return N > 0;
4806    }
4807
4808    private final boolean forceStopPackageLocked(String name, int appId,
4809            boolean callerWillRestart, boolean purgeCache, boolean doit,
4810            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4811        int i;
4812        int N;
4813
4814        if (userId == UserHandle.USER_ALL && name == null) {
4815            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4816        }
4817
4818        if (appId < 0 && name != null) {
4819            try {
4820                appId = UserHandle.getAppId(
4821                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4822            } catch (RemoteException e) {
4823            }
4824        }
4825
4826        if (doit) {
4827            if (name != null) {
4828                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4829                        + " user=" + userId + ": " + reason);
4830            } else {
4831                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4832            }
4833
4834            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4835            for (int ip=pmap.size()-1; ip>=0; ip--) {
4836                SparseArray<Long> ba = pmap.valueAt(ip);
4837                for (i=ba.size()-1; i>=0; i--) {
4838                    boolean remove = false;
4839                    final int entUid = ba.keyAt(i);
4840                    if (name != null) {
4841                        if (userId == UserHandle.USER_ALL) {
4842                            if (UserHandle.getAppId(entUid) == appId) {
4843                                remove = true;
4844                            }
4845                        } else {
4846                            if (entUid == UserHandle.getUid(userId, appId)) {
4847                                remove = true;
4848                            }
4849                        }
4850                    } else if (UserHandle.getUserId(entUid) == userId) {
4851                        remove = true;
4852                    }
4853                    if (remove) {
4854                        ba.removeAt(i);
4855                    }
4856                }
4857                if (ba.size() == 0) {
4858                    pmap.removeAt(ip);
4859                }
4860            }
4861        }
4862
4863        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4864                -100, callerWillRestart, true, doit, evenPersistent,
4865                name == null ? ("stop user " + userId) : ("stop " + name));
4866
4867        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4868            if (!doit) {
4869                return true;
4870            }
4871            didSomething = true;
4872        }
4873
4874        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4875            if (!doit) {
4876                return true;
4877            }
4878            didSomething = true;
4879        }
4880
4881        if (name == null) {
4882            // Remove all sticky broadcasts from this user.
4883            mStickyBroadcasts.remove(userId);
4884        }
4885
4886        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4887        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4888                userId, providers)) {
4889            if (!doit) {
4890                return true;
4891            }
4892            didSomething = true;
4893        }
4894        N = providers.size();
4895        for (i=0; i<N; i++) {
4896            removeDyingProviderLocked(null, providers.get(i), true);
4897        }
4898
4899        // Remove transient permissions granted from/to this package/user
4900        removeUriPermissionsForPackageLocked(name, userId, false);
4901
4902        if (name == null || uninstalling) {
4903            // Remove pending intents.  For now we only do this when force
4904            // stopping users, because we have some problems when doing this
4905            // for packages -- app widgets are not currently cleaned up for
4906            // such packages, so they can be left with bad pending intents.
4907            if (mIntentSenderRecords.size() > 0) {
4908                Iterator<WeakReference<PendingIntentRecord>> it
4909                        = mIntentSenderRecords.values().iterator();
4910                while (it.hasNext()) {
4911                    WeakReference<PendingIntentRecord> wpir = it.next();
4912                    if (wpir == null) {
4913                        it.remove();
4914                        continue;
4915                    }
4916                    PendingIntentRecord pir = wpir.get();
4917                    if (pir == null) {
4918                        it.remove();
4919                        continue;
4920                    }
4921                    if (name == null) {
4922                        // Stopping user, remove all objects for the user.
4923                        if (pir.key.userId != userId) {
4924                            // Not the same user, skip it.
4925                            continue;
4926                        }
4927                    } else {
4928                        if (UserHandle.getAppId(pir.uid) != appId) {
4929                            // Different app id, skip it.
4930                            continue;
4931                        }
4932                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4933                            // Different user, skip it.
4934                            continue;
4935                        }
4936                        if (!pir.key.packageName.equals(name)) {
4937                            // Different package, skip it.
4938                            continue;
4939                        }
4940                    }
4941                    if (!doit) {
4942                        return true;
4943                    }
4944                    didSomething = true;
4945                    it.remove();
4946                    pir.canceled = true;
4947                    if (pir.key.activity != null) {
4948                        pir.key.activity.pendingResults.remove(pir.ref);
4949                    }
4950                }
4951            }
4952        }
4953
4954        if (doit) {
4955            if (purgeCache && name != null) {
4956                AttributeCache ac = AttributeCache.instance();
4957                if (ac != null) {
4958                    ac.removePackage(name);
4959                }
4960            }
4961            if (mBooted) {
4962                mStackSupervisor.resumeTopActivitiesLocked();
4963                mStackSupervisor.scheduleIdleLocked();
4964            }
4965        }
4966
4967        return didSomething;
4968    }
4969
4970    private final boolean removeProcessLocked(ProcessRecord app,
4971            boolean callerWillRestart, boolean allowRestart, String reason) {
4972        final String name = app.processName;
4973        final int uid = app.uid;
4974        if (DEBUG_PROCESSES) Slog.d(
4975            TAG, "Force removing proc " + app.toShortString() + " (" + name
4976            + "/" + uid + ")");
4977
4978        mProcessNames.remove(name, uid);
4979        mIsolatedProcesses.remove(app.uid);
4980        if (mHeavyWeightProcess == app) {
4981            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4982                    mHeavyWeightProcess.userId, 0));
4983            mHeavyWeightProcess = null;
4984        }
4985        boolean needRestart = false;
4986        if (app.pid > 0 && app.pid != MY_PID) {
4987            int pid = app.pid;
4988            synchronized (mPidsSelfLocked) {
4989                mPidsSelfLocked.remove(pid);
4990                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4991            }
4992            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4993                    app.processName, app.info.uid);
4994            if (app.isolated) {
4995                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4996            }
4997            killUnneededProcessLocked(app, reason);
4998            handleAppDiedLocked(app, true, allowRestart);
4999            removeLruProcessLocked(app);
5000
5001            if (app.persistent && !app.isolated) {
5002                if (!callerWillRestart) {
5003                    addAppLocked(app.info, false);
5004                } else {
5005                    needRestart = true;
5006                }
5007            }
5008        } else {
5009            mRemovedProcesses.add(app);
5010        }
5011
5012        return needRestart;
5013    }
5014
5015    private final void processStartTimedOutLocked(ProcessRecord app) {
5016        final int pid = app.pid;
5017        boolean gone = false;
5018        synchronized (mPidsSelfLocked) {
5019            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5020            if (knownApp != null && knownApp.thread == null) {
5021                mPidsSelfLocked.remove(pid);
5022                gone = true;
5023            }
5024        }
5025
5026        if (gone) {
5027            Slog.w(TAG, "Process " + app + " failed to attach");
5028            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5029                    pid, app.uid, app.processName);
5030            mProcessNames.remove(app.processName, app.uid);
5031            mIsolatedProcesses.remove(app.uid);
5032            if (mHeavyWeightProcess == app) {
5033                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5034                        mHeavyWeightProcess.userId, 0));
5035                mHeavyWeightProcess = null;
5036            }
5037            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5038                    app.processName, app.info.uid);
5039            if (app.isolated) {
5040                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5041            }
5042            // Take care of any launching providers waiting for this process.
5043            checkAppInLaunchingProvidersLocked(app, true);
5044            // Take care of any services that are waiting for the process.
5045            mServices.processStartTimedOutLocked(app);
5046            killUnneededProcessLocked(app, "start timeout");
5047            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5048                Slog.w(TAG, "Unattached app died before backup, skipping");
5049                try {
5050                    IBackupManager bm = IBackupManager.Stub.asInterface(
5051                            ServiceManager.getService(Context.BACKUP_SERVICE));
5052                    bm.agentDisconnected(app.info.packageName);
5053                } catch (RemoteException e) {
5054                    // Can't happen; the backup manager is local
5055                }
5056            }
5057            if (isPendingBroadcastProcessLocked(pid)) {
5058                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5059                skipPendingBroadcastLocked(pid);
5060            }
5061        } else {
5062            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5063        }
5064    }
5065
5066    private final boolean attachApplicationLocked(IApplicationThread thread,
5067            int pid) {
5068
5069        // Find the application record that is being attached...  either via
5070        // the pid if we are running in multiple processes, or just pull the
5071        // next app record if we are emulating process with anonymous threads.
5072        ProcessRecord app;
5073        if (pid != MY_PID && pid >= 0) {
5074            synchronized (mPidsSelfLocked) {
5075                app = mPidsSelfLocked.get(pid);
5076            }
5077        } else {
5078            app = null;
5079        }
5080
5081        if (app == null) {
5082            Slog.w(TAG, "No pending application record for pid " + pid
5083                    + " (IApplicationThread " + thread + "); dropping process");
5084            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5085            if (pid > 0 && pid != MY_PID) {
5086                Process.killProcessQuiet(pid);
5087            } else {
5088                try {
5089                    thread.scheduleExit();
5090                } catch (Exception e) {
5091                    // Ignore exceptions.
5092                }
5093            }
5094            return false;
5095        }
5096
5097        // If this application record is still attached to a previous
5098        // process, clean it up now.
5099        if (app.thread != null) {
5100            handleAppDiedLocked(app, true, true);
5101        }
5102
5103        // Tell the process all about itself.
5104
5105        if (localLOGV) Slog.v(
5106                TAG, "Binding process pid " + pid + " to record " + app);
5107
5108        final String processName = app.processName;
5109        try {
5110            AppDeathRecipient adr = new AppDeathRecipient(
5111                    app, pid, thread);
5112            thread.asBinder().linkToDeath(adr, 0);
5113            app.deathRecipient = adr;
5114        } catch (RemoteException e) {
5115            app.resetPackageList(mProcessStats);
5116            startProcessLocked(app, "link fail", processName);
5117            return false;
5118        }
5119
5120        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5121
5122        app.makeActive(thread, mProcessStats);
5123        app.curAdj = app.setAdj = -100;
5124        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5125        app.forcingToForeground = null;
5126        updateProcessForegroundLocked(app, false, false);
5127        app.hasShownUi = false;
5128        app.debugging = false;
5129        app.cached = false;
5130
5131        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5132
5133        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5134        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5135
5136        if (!normalMode) {
5137            Slog.i(TAG, "Launching preboot mode app: " + app);
5138        }
5139
5140        if (localLOGV) Slog.v(
5141            TAG, "New app record " + app
5142            + " thread=" + thread.asBinder() + " pid=" + pid);
5143        try {
5144            int testMode = IApplicationThread.DEBUG_OFF;
5145            if (mDebugApp != null && mDebugApp.equals(processName)) {
5146                testMode = mWaitForDebugger
5147                    ? IApplicationThread.DEBUG_WAIT
5148                    : IApplicationThread.DEBUG_ON;
5149                app.debugging = true;
5150                if (mDebugTransient) {
5151                    mDebugApp = mOrigDebugApp;
5152                    mWaitForDebugger = mOrigWaitForDebugger;
5153                }
5154            }
5155            String profileFile = app.instrumentationProfileFile;
5156            ParcelFileDescriptor profileFd = null;
5157            boolean profileAutoStop = false;
5158            if (mProfileApp != null && mProfileApp.equals(processName)) {
5159                mProfileProc = app;
5160                profileFile = mProfileFile;
5161                profileFd = mProfileFd;
5162                profileAutoStop = mAutoStopProfiler;
5163            }
5164            boolean enableOpenGlTrace = false;
5165            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5166                enableOpenGlTrace = true;
5167                mOpenGlTraceApp = null;
5168            }
5169
5170            // If the app is being launched for restore or full backup, set it up specially
5171            boolean isRestrictedBackupMode = false;
5172            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5173                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5174                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5175                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5176            }
5177
5178            ensurePackageDexOpt(app.instrumentationInfo != null
5179                    ? app.instrumentationInfo.packageName
5180                    : app.info.packageName);
5181            if (app.instrumentationClass != null) {
5182                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5183            }
5184            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5185                    + processName + " with config " + mConfiguration);
5186            ApplicationInfo appInfo = app.instrumentationInfo != null
5187                    ? app.instrumentationInfo : app.info;
5188            app.compat = compatibilityInfoForPackageLocked(appInfo);
5189            if (profileFd != null) {
5190                profileFd = profileFd.dup();
5191            }
5192            thread.bindApplication(processName, appInfo, providers,
5193                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5194                    app.instrumentationArguments, app.instrumentationWatcher,
5195                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5196                    isRestrictedBackupMode || !normalMode, app.persistent,
5197                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5198                    mCoreSettingsObserver.getCoreSettingsLocked());
5199            updateLruProcessLocked(app, false, null);
5200            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5201        } catch (Exception e) {
5202            // todo: Yikes!  What should we do?  For now we will try to
5203            // start another process, but that could easily get us in
5204            // an infinite loop of restarting processes...
5205            Slog.w(TAG, "Exception thrown during bind!", e);
5206
5207            app.resetPackageList(mProcessStats);
5208            app.unlinkDeathRecipient();
5209            startProcessLocked(app, "bind fail", processName);
5210            return false;
5211        }
5212
5213        // Remove this record from the list of starting applications.
5214        mPersistentStartingProcesses.remove(app);
5215        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5216                "Attach application locked removing on hold: " + app);
5217        mProcessesOnHold.remove(app);
5218
5219        boolean badApp = false;
5220        boolean didSomething = false;
5221
5222        // See if the top visible activity is waiting to run in this process...
5223        if (normalMode) {
5224            try {
5225                if (mStackSupervisor.attachApplicationLocked(app)) {
5226                    didSomething = true;
5227                }
5228            } catch (Exception e) {
5229                badApp = true;
5230            }
5231        }
5232
5233        // Find any services that should be running in this process...
5234        if (!badApp) {
5235            try {
5236                didSomething |= mServices.attachApplicationLocked(app, processName);
5237            } catch (Exception e) {
5238                badApp = true;
5239            }
5240        }
5241
5242        // Check if a next-broadcast receiver is in this process...
5243        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5244            try {
5245                didSomething |= sendPendingBroadcastsLocked(app);
5246            } catch (Exception e) {
5247                // If the app died trying to launch the receiver we declare it 'bad'
5248                badApp = true;
5249            }
5250        }
5251
5252        // Check whether the next backup agent is in this process...
5253        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5254            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5255            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5256            try {
5257                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5258                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5259                        mBackupTarget.backupMode);
5260            } catch (Exception e) {
5261                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5262                e.printStackTrace();
5263            }
5264        }
5265
5266        if (badApp) {
5267            // todo: Also need to kill application to deal with all
5268            // kinds of exceptions.
5269            handleAppDiedLocked(app, false, true);
5270            return false;
5271        }
5272
5273        if (!didSomething) {
5274            updateOomAdjLocked();
5275        }
5276
5277        return true;
5278    }
5279
5280    @Override
5281    public final void attachApplication(IApplicationThread thread) {
5282        synchronized (this) {
5283            int callingPid = Binder.getCallingPid();
5284            final long origId = Binder.clearCallingIdentity();
5285            attachApplicationLocked(thread, callingPid);
5286            Binder.restoreCallingIdentity(origId);
5287        }
5288    }
5289
5290    @Override
5291    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5292        final long origId = Binder.clearCallingIdentity();
5293        synchronized (this) {
5294            ActivityStack stack = ActivityRecord.getStackLocked(token);
5295            if (stack != null) {
5296                ActivityRecord r =
5297                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5298                if (stopProfiling) {
5299                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5300                        try {
5301                            mProfileFd.close();
5302                        } catch (IOException e) {
5303                        }
5304                        clearProfilerLocked();
5305                    }
5306                }
5307            }
5308        }
5309        Binder.restoreCallingIdentity(origId);
5310    }
5311
5312    void enableScreenAfterBoot() {
5313        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5314                SystemClock.uptimeMillis());
5315        mWindowManager.enableScreenAfterBoot();
5316
5317        synchronized (this) {
5318            updateEventDispatchingLocked();
5319        }
5320    }
5321
5322    @Override
5323    public void showBootMessage(final CharSequence msg, final boolean always) {
5324        enforceNotIsolatedCaller("showBootMessage");
5325        mWindowManager.showBootMessage(msg, always);
5326    }
5327
5328    @Override
5329    public void dismissKeyguardOnNextActivity() {
5330        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5331        final long token = Binder.clearCallingIdentity();
5332        try {
5333            synchronized (this) {
5334                if (DEBUG_LOCKSCREEN) logLockScreen("");
5335                if (mLockScreenShown) {
5336                    mLockScreenShown = false;
5337                    comeOutOfSleepIfNeededLocked();
5338                }
5339                mStackSupervisor.setDismissKeyguard(true);
5340            }
5341        } finally {
5342            Binder.restoreCallingIdentity(token);
5343        }
5344    }
5345
5346    final void finishBooting() {
5347        // Register receivers to handle package update events
5348        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5349
5350        synchronized (this) {
5351            // Ensure that any processes we had put on hold are now started
5352            // up.
5353            final int NP = mProcessesOnHold.size();
5354            if (NP > 0) {
5355                ArrayList<ProcessRecord> procs =
5356                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5357                for (int ip=0; ip<NP; ip++) {
5358                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5359                            + procs.get(ip));
5360                    startProcessLocked(procs.get(ip), "on-hold", null);
5361                }
5362            }
5363
5364            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5365                // Start looking for apps that are abusing wake locks.
5366                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5367                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5368                // Tell anyone interested that we are done booting!
5369                SystemProperties.set("sys.boot_completed", "1");
5370                SystemProperties.set("dev.bootcomplete", "1");
5371                for (int i=0; i<mStartedUsers.size(); i++) {
5372                    UserStartedState uss = mStartedUsers.valueAt(i);
5373                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5374                        uss.mState = UserStartedState.STATE_RUNNING;
5375                        final int userId = mStartedUsers.keyAt(i);
5376                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5377                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5378                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5379                        broadcastIntentLocked(null, null, intent, null,
5380                                new IIntentReceiver.Stub() {
5381                                    @Override
5382                                    public void performReceive(Intent intent, int resultCode,
5383                                            String data, Bundle extras, boolean ordered,
5384                                            boolean sticky, int sendingUser) {
5385                                        synchronized (ActivityManagerService.this) {
5386                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5387                                                    true, false);
5388                                        }
5389                                    }
5390                                },
5391                                0, null, null,
5392                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5393                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5394                                userId);
5395                    }
5396                }
5397                scheduleStartProfilesLocked();
5398            }
5399        }
5400    }
5401
5402    final void ensureBootCompleted() {
5403        boolean booting;
5404        boolean enableScreen;
5405        synchronized (this) {
5406            booting = mBooting;
5407            mBooting = false;
5408            enableScreen = !mBooted;
5409            mBooted = true;
5410        }
5411
5412        if (booting) {
5413            finishBooting();
5414        }
5415
5416        if (enableScreen) {
5417            enableScreenAfterBoot();
5418        }
5419    }
5420
5421    @Override
5422    public final void activityResumed(IBinder token) {
5423        final long origId = Binder.clearCallingIdentity();
5424        synchronized(this) {
5425            ActivityStack stack = ActivityRecord.getStackLocked(token);
5426            if (stack != null) {
5427                ActivityRecord.activityResumedLocked(token);
5428            }
5429        }
5430        Binder.restoreCallingIdentity(origId);
5431    }
5432
5433    @Override
5434    public final void activityPaused(IBinder token) {
5435        final long origId = Binder.clearCallingIdentity();
5436        synchronized(this) {
5437            ActivityStack stack = ActivityRecord.getStackLocked(token);
5438            if (stack != null) {
5439                stack.activityPausedLocked(token, false);
5440            }
5441        }
5442        Binder.restoreCallingIdentity(origId);
5443    }
5444
5445    @Override
5446    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5447            CharSequence description) {
5448        if (localLOGV) Slog.v(
5449            TAG, "Activity stopped: token=" + token);
5450
5451        // Refuse possible leaked file descriptors
5452        if (icicle != null && icicle.hasFileDescriptors()) {
5453            throw new IllegalArgumentException("File descriptors passed in Bundle");
5454        }
5455
5456        ActivityRecord r = null;
5457
5458        final long origId = Binder.clearCallingIdentity();
5459
5460        synchronized (this) {
5461            r = ActivityRecord.isInStackLocked(token);
5462            if (r != null) {
5463                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5464            }
5465        }
5466
5467        if (r != null) {
5468            sendPendingThumbnail(r, null, null, null, false);
5469        }
5470
5471        trimApplications();
5472
5473        Binder.restoreCallingIdentity(origId);
5474    }
5475
5476    @Override
5477    public final void activityDestroyed(IBinder token) {
5478        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5479        synchronized (this) {
5480            ActivityStack stack = ActivityRecord.getStackLocked(token);
5481            if (stack != null) {
5482                stack.activityDestroyedLocked(token);
5483            }
5484        }
5485    }
5486
5487    @Override
5488    public String getCallingPackage(IBinder token) {
5489        synchronized (this) {
5490            ActivityRecord r = getCallingRecordLocked(token);
5491            return r != null ? r.info.packageName : null;
5492        }
5493    }
5494
5495    @Override
5496    public ComponentName getCallingActivity(IBinder token) {
5497        synchronized (this) {
5498            ActivityRecord r = getCallingRecordLocked(token);
5499            return r != null ? r.intent.getComponent() : null;
5500        }
5501    }
5502
5503    private ActivityRecord getCallingRecordLocked(IBinder token) {
5504        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5505        if (r == null) {
5506            return null;
5507        }
5508        return r.resultTo;
5509    }
5510
5511    @Override
5512    public ComponentName getActivityClassForToken(IBinder token) {
5513        synchronized(this) {
5514            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5515            if (r == null) {
5516                return null;
5517            }
5518            return r.intent.getComponent();
5519        }
5520    }
5521
5522    @Override
5523    public String getPackageForToken(IBinder token) {
5524        synchronized(this) {
5525            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5526            if (r == null) {
5527                return null;
5528            }
5529            return r.packageName;
5530        }
5531    }
5532
5533    @Override
5534    public IIntentSender getIntentSender(int type,
5535            String packageName, IBinder token, String resultWho,
5536            int requestCode, Intent[] intents, String[] resolvedTypes,
5537            int flags, Bundle options, int userId) {
5538        enforceNotIsolatedCaller("getIntentSender");
5539        // Refuse possible leaked file descriptors
5540        if (intents != null) {
5541            if (intents.length < 1) {
5542                throw new IllegalArgumentException("Intents array length must be >= 1");
5543            }
5544            for (int i=0; i<intents.length; i++) {
5545                Intent intent = intents[i];
5546                if (intent != null) {
5547                    if (intent.hasFileDescriptors()) {
5548                        throw new IllegalArgumentException("File descriptors passed in Intent");
5549                    }
5550                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5551                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5552                        throw new IllegalArgumentException(
5553                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5554                    }
5555                    intents[i] = new Intent(intent);
5556                }
5557            }
5558            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5559                throw new IllegalArgumentException(
5560                        "Intent array length does not match resolvedTypes length");
5561            }
5562        }
5563        if (options != null) {
5564            if (options.hasFileDescriptors()) {
5565                throw new IllegalArgumentException("File descriptors passed in options");
5566            }
5567        }
5568
5569        synchronized(this) {
5570            int callingUid = Binder.getCallingUid();
5571            int origUserId = userId;
5572            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5573                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5574                    "getIntentSender", null);
5575            if (origUserId == UserHandle.USER_CURRENT) {
5576                // We don't want to evaluate this until the pending intent is
5577                // actually executed.  However, we do want to always do the
5578                // security checking for it above.
5579                userId = UserHandle.USER_CURRENT;
5580            }
5581            try {
5582                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5583                    int uid = AppGlobals.getPackageManager()
5584                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5585                    if (!UserHandle.isSameApp(callingUid, uid)) {
5586                        String msg = "Permission Denial: getIntentSender() from pid="
5587                            + Binder.getCallingPid()
5588                            + ", uid=" + Binder.getCallingUid()
5589                            + ", (need uid=" + uid + ")"
5590                            + " is not allowed to send as package " + packageName;
5591                        Slog.w(TAG, msg);
5592                        throw new SecurityException(msg);
5593                    }
5594                }
5595
5596                return getIntentSenderLocked(type, packageName, callingUid, userId,
5597                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5598
5599            } catch (RemoteException e) {
5600                throw new SecurityException(e);
5601            }
5602        }
5603    }
5604
5605    IIntentSender getIntentSenderLocked(int type, String packageName,
5606            int callingUid, int userId, IBinder token, String resultWho,
5607            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5608            Bundle options) {
5609        if (DEBUG_MU)
5610            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5611        ActivityRecord activity = null;
5612        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5613            activity = ActivityRecord.isInStackLocked(token);
5614            if (activity == null) {
5615                return null;
5616            }
5617            if (activity.finishing) {
5618                return null;
5619            }
5620        }
5621
5622        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5623        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5624        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5625        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5626                |PendingIntent.FLAG_UPDATE_CURRENT);
5627
5628        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5629                type, packageName, activity, resultWho,
5630                requestCode, intents, resolvedTypes, flags, options, userId);
5631        WeakReference<PendingIntentRecord> ref;
5632        ref = mIntentSenderRecords.get(key);
5633        PendingIntentRecord rec = ref != null ? ref.get() : null;
5634        if (rec != null) {
5635            if (!cancelCurrent) {
5636                if (updateCurrent) {
5637                    if (rec.key.requestIntent != null) {
5638                        rec.key.requestIntent.replaceExtras(intents != null ?
5639                                intents[intents.length - 1] : null);
5640                    }
5641                    if (intents != null) {
5642                        intents[intents.length-1] = rec.key.requestIntent;
5643                        rec.key.allIntents = intents;
5644                        rec.key.allResolvedTypes = resolvedTypes;
5645                    } else {
5646                        rec.key.allIntents = null;
5647                        rec.key.allResolvedTypes = null;
5648                    }
5649                }
5650                return rec;
5651            }
5652            rec.canceled = true;
5653            mIntentSenderRecords.remove(key);
5654        }
5655        if (noCreate) {
5656            return rec;
5657        }
5658        rec = new PendingIntentRecord(this, key, callingUid);
5659        mIntentSenderRecords.put(key, rec.ref);
5660        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5661            if (activity.pendingResults == null) {
5662                activity.pendingResults
5663                        = new HashSet<WeakReference<PendingIntentRecord>>();
5664            }
5665            activity.pendingResults.add(rec.ref);
5666        }
5667        return rec;
5668    }
5669
5670    @Override
5671    public void cancelIntentSender(IIntentSender sender) {
5672        if (!(sender instanceof PendingIntentRecord)) {
5673            return;
5674        }
5675        synchronized(this) {
5676            PendingIntentRecord rec = (PendingIntentRecord)sender;
5677            try {
5678                int uid = AppGlobals.getPackageManager()
5679                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5680                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5681                    String msg = "Permission Denial: cancelIntentSender() from pid="
5682                        + Binder.getCallingPid()
5683                        + ", uid=" + Binder.getCallingUid()
5684                        + " is not allowed to cancel packges "
5685                        + rec.key.packageName;
5686                    Slog.w(TAG, msg);
5687                    throw new SecurityException(msg);
5688                }
5689            } catch (RemoteException e) {
5690                throw new SecurityException(e);
5691            }
5692            cancelIntentSenderLocked(rec, true);
5693        }
5694    }
5695
5696    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5697        rec.canceled = true;
5698        mIntentSenderRecords.remove(rec.key);
5699        if (cleanActivity && rec.key.activity != null) {
5700            rec.key.activity.pendingResults.remove(rec.ref);
5701        }
5702    }
5703
5704    @Override
5705    public String getPackageForIntentSender(IIntentSender pendingResult) {
5706        if (!(pendingResult instanceof PendingIntentRecord)) {
5707            return null;
5708        }
5709        try {
5710            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5711            return res.key.packageName;
5712        } catch (ClassCastException e) {
5713        }
5714        return null;
5715    }
5716
5717    @Override
5718    public int getUidForIntentSender(IIntentSender sender) {
5719        if (sender instanceof PendingIntentRecord) {
5720            try {
5721                PendingIntentRecord res = (PendingIntentRecord)sender;
5722                return res.uid;
5723            } catch (ClassCastException e) {
5724            }
5725        }
5726        return -1;
5727    }
5728
5729    @Override
5730    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5731        if (!(pendingResult instanceof PendingIntentRecord)) {
5732            return false;
5733        }
5734        try {
5735            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5736            if (res.key.allIntents == null) {
5737                return false;
5738            }
5739            for (int i=0; i<res.key.allIntents.length; i++) {
5740                Intent intent = res.key.allIntents[i];
5741                if (intent.getPackage() != null && intent.getComponent() != null) {
5742                    return false;
5743                }
5744            }
5745            return true;
5746        } catch (ClassCastException e) {
5747        }
5748        return false;
5749    }
5750
5751    @Override
5752    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5753        if (!(pendingResult instanceof PendingIntentRecord)) {
5754            return false;
5755        }
5756        try {
5757            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5758            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5759                return true;
5760            }
5761            return false;
5762        } catch (ClassCastException e) {
5763        }
5764        return false;
5765    }
5766
5767    @Override
5768    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5769        if (!(pendingResult instanceof PendingIntentRecord)) {
5770            return null;
5771        }
5772        try {
5773            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5774            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5775        } catch (ClassCastException e) {
5776        }
5777        return null;
5778    }
5779
5780    @Override
5781    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5782        if (!(pendingResult instanceof PendingIntentRecord)) {
5783            return null;
5784        }
5785        try {
5786            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5787            Intent intent = res.key.requestIntent;
5788            if (intent != null) {
5789                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5790                        || res.lastTagPrefix.equals(prefix))) {
5791                    return res.lastTag;
5792                }
5793                res.lastTagPrefix = prefix;
5794                StringBuilder sb = new StringBuilder(128);
5795                if (prefix != null) {
5796                    sb.append(prefix);
5797                }
5798                if (intent.getAction() != null) {
5799                    sb.append(intent.getAction());
5800                } else if (intent.getComponent() != null) {
5801                    intent.getComponent().appendShortString(sb);
5802                } else {
5803                    sb.append("?");
5804                }
5805                return res.lastTag = sb.toString();
5806            }
5807        } catch (ClassCastException e) {
5808        }
5809        return null;
5810    }
5811
5812    @Override
5813    public void setProcessLimit(int max) {
5814        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5815                "setProcessLimit()");
5816        synchronized (this) {
5817            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5818            mProcessLimitOverride = max;
5819        }
5820        trimApplications();
5821    }
5822
5823    @Override
5824    public int getProcessLimit() {
5825        synchronized (this) {
5826            return mProcessLimitOverride;
5827        }
5828    }
5829
5830    void foregroundTokenDied(ForegroundToken token) {
5831        synchronized (ActivityManagerService.this) {
5832            synchronized (mPidsSelfLocked) {
5833                ForegroundToken cur
5834                    = mForegroundProcesses.get(token.pid);
5835                if (cur != token) {
5836                    return;
5837                }
5838                mForegroundProcesses.remove(token.pid);
5839                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5840                if (pr == null) {
5841                    return;
5842                }
5843                pr.forcingToForeground = null;
5844                updateProcessForegroundLocked(pr, false, false);
5845            }
5846            updateOomAdjLocked();
5847        }
5848    }
5849
5850    @Override
5851    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5852        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5853                "setProcessForeground()");
5854        synchronized(this) {
5855            boolean changed = false;
5856
5857            synchronized (mPidsSelfLocked) {
5858                ProcessRecord pr = mPidsSelfLocked.get(pid);
5859                if (pr == null && isForeground) {
5860                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5861                    return;
5862                }
5863                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5864                if (oldToken != null) {
5865                    oldToken.token.unlinkToDeath(oldToken, 0);
5866                    mForegroundProcesses.remove(pid);
5867                    if (pr != null) {
5868                        pr.forcingToForeground = null;
5869                    }
5870                    changed = true;
5871                }
5872                if (isForeground && token != null) {
5873                    ForegroundToken newToken = new ForegroundToken() {
5874                        @Override
5875                        public void binderDied() {
5876                            foregroundTokenDied(this);
5877                        }
5878                    };
5879                    newToken.pid = pid;
5880                    newToken.token = token;
5881                    try {
5882                        token.linkToDeath(newToken, 0);
5883                        mForegroundProcesses.put(pid, newToken);
5884                        pr.forcingToForeground = token;
5885                        changed = true;
5886                    } catch (RemoteException e) {
5887                        // If the process died while doing this, we will later
5888                        // do the cleanup with the process death link.
5889                    }
5890                }
5891            }
5892
5893            if (changed) {
5894                updateOomAdjLocked();
5895            }
5896        }
5897    }
5898
5899    // =========================================================
5900    // PERMISSIONS
5901    // =========================================================
5902
5903    static class PermissionController extends IPermissionController.Stub {
5904        ActivityManagerService mActivityManagerService;
5905        PermissionController(ActivityManagerService activityManagerService) {
5906            mActivityManagerService = activityManagerService;
5907        }
5908
5909        @Override
5910        public boolean checkPermission(String permission, int pid, int uid) {
5911            return mActivityManagerService.checkPermission(permission, pid,
5912                    uid) == PackageManager.PERMISSION_GRANTED;
5913        }
5914    }
5915
5916    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5917        @Override
5918        public int checkComponentPermission(String permission, int pid, int uid,
5919                int owningUid, boolean exported) {
5920            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5921                    owningUid, exported);
5922        }
5923
5924        @Override
5925        public Object getAMSLock() {
5926            return ActivityManagerService.this;
5927        }
5928    }
5929
5930    /**
5931     * This can be called with or without the global lock held.
5932     */
5933    int checkComponentPermission(String permission, int pid, int uid,
5934            int owningUid, boolean exported) {
5935        // We might be performing an operation on behalf of an indirect binder
5936        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5937        // client identity accordingly before proceeding.
5938        Identity tlsIdentity = sCallerIdentity.get();
5939        if (tlsIdentity != null) {
5940            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5941                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5942            uid = tlsIdentity.uid;
5943            pid = tlsIdentity.pid;
5944        }
5945
5946        if (pid == MY_PID) {
5947            return PackageManager.PERMISSION_GRANTED;
5948        }
5949
5950        return ActivityManager.checkComponentPermission(permission, uid,
5951                owningUid, exported);
5952    }
5953
5954    /**
5955     * As the only public entry point for permissions checking, this method
5956     * can enforce the semantic that requesting a check on a null global
5957     * permission is automatically denied.  (Internally a null permission
5958     * string is used when calling {@link #checkComponentPermission} in cases
5959     * when only uid-based security is needed.)
5960     *
5961     * This can be called with or without the global lock held.
5962     */
5963    @Override
5964    public int checkPermission(String permission, int pid, int uid) {
5965        if (permission == null) {
5966            return PackageManager.PERMISSION_DENIED;
5967        }
5968        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5969    }
5970
5971    /**
5972     * Binder IPC calls go through the public entry point.
5973     * This can be called with or without the global lock held.
5974     */
5975    int checkCallingPermission(String permission) {
5976        return checkPermission(permission,
5977                Binder.getCallingPid(),
5978                UserHandle.getAppId(Binder.getCallingUid()));
5979    }
5980
5981    /**
5982     * This can be called with or without the global lock held.
5983     */
5984    void enforceCallingPermission(String permission, String func) {
5985        if (checkCallingPermission(permission)
5986                == PackageManager.PERMISSION_GRANTED) {
5987            return;
5988        }
5989
5990        String msg = "Permission Denial: " + func + " from pid="
5991                + Binder.getCallingPid()
5992                + ", uid=" + Binder.getCallingUid()
5993                + " requires " + permission;
5994        Slog.w(TAG, msg);
5995        throw new SecurityException(msg);
5996    }
5997
5998    /**
5999     * Determine if UID is holding permissions required to access {@link Uri} in
6000     * the given {@link ProviderInfo}. Final permission checking is always done
6001     * in {@link ContentProvider}.
6002     */
6003    private final boolean checkHoldingPermissionsLocked(
6004            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
6005        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6006                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
6007
6008        if (pi.applicationInfo.uid == uid) {
6009            return true;
6010        } else if (!pi.exported) {
6011            return false;
6012        }
6013
6014        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6015        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6016        try {
6017            // check if target holds top-level <provider> permissions
6018            if (!readMet && pi.readPermission != null
6019                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6020                readMet = true;
6021            }
6022            if (!writeMet && pi.writePermission != null
6023                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6024                writeMet = true;
6025            }
6026
6027            // track if unprotected read/write is allowed; any denied
6028            // <path-permission> below removes this ability
6029            boolean allowDefaultRead = pi.readPermission == null;
6030            boolean allowDefaultWrite = pi.writePermission == null;
6031
6032            // check if target holds any <path-permission> that match uri
6033            final PathPermission[] pps = pi.pathPermissions;
6034            if (pps != null) {
6035                final String path = uri.getPath();
6036                int i = pps.length;
6037                while (i > 0 && (!readMet || !writeMet)) {
6038                    i--;
6039                    PathPermission pp = pps[i];
6040                    if (pp.match(path)) {
6041                        if (!readMet) {
6042                            final String pprperm = pp.getReadPermission();
6043                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6044                                    + pprperm + " for " + pp.getPath()
6045                                    + ": match=" + pp.match(path)
6046                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6047                            if (pprperm != null) {
6048                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6049                                    readMet = true;
6050                                } else {
6051                                    allowDefaultRead = false;
6052                                }
6053                            }
6054                        }
6055                        if (!writeMet) {
6056                            final String ppwperm = pp.getWritePermission();
6057                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6058                                    + ppwperm + " for " + pp.getPath()
6059                                    + ": match=" + pp.match(path)
6060                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6061                            if (ppwperm != null) {
6062                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6063                                    writeMet = true;
6064                                } else {
6065                                    allowDefaultWrite = false;
6066                                }
6067                            }
6068                        }
6069                    }
6070                }
6071            }
6072
6073            // grant unprotected <provider> read/write, if not blocked by
6074            // <path-permission> above
6075            if (allowDefaultRead) readMet = true;
6076            if (allowDefaultWrite) writeMet = true;
6077
6078        } catch (RemoteException e) {
6079            return false;
6080        }
6081
6082        return readMet && writeMet;
6083    }
6084
6085    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6086        ProviderInfo pi = null;
6087        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6088        if (cpr != null) {
6089            pi = cpr.info;
6090        } else {
6091            try {
6092                pi = AppGlobals.getPackageManager().resolveContentProvider(
6093                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6094            } catch (RemoteException ex) {
6095            }
6096        }
6097        return pi;
6098    }
6099
6100    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6101        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6102        if (targetUris != null) {
6103            return targetUris.get(uri);
6104        }
6105        return null;
6106    }
6107
6108    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6109            String targetPkg, int targetUid, GrantUri uri) {
6110        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6111        if (targetUris == null) {
6112            targetUris = Maps.newArrayMap();
6113            mGrantedUriPermissions.put(targetUid, targetUris);
6114        }
6115
6116        UriPermission perm = targetUris.get(uri);
6117        if (perm == null) {
6118            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6119            targetUris.put(uri, perm);
6120        }
6121
6122        return perm;
6123    }
6124
6125    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6126        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6127        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6128                : UriPermission.STRENGTH_OWNED;
6129
6130        // Root gets to do everything.
6131        if (uid == 0) {
6132            return true;
6133        }
6134
6135        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6136        if (perms == null) return false;
6137
6138        // First look for exact match
6139        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6140        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6141            return true;
6142        }
6143
6144        // No exact match, look for prefixes
6145        final int N = perms.size();
6146        for (int i = 0; i < N; i++) {
6147            final UriPermission perm = perms.valueAt(i);
6148            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6149                    && perm.getStrength(modeFlags) >= minStrength) {
6150                return true;
6151            }
6152        }
6153
6154        return false;
6155    }
6156
6157    @Override
6158    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6159        enforceNotIsolatedCaller("checkUriPermission");
6160
6161        // Another redirected-binder-call permissions check as in
6162        // {@link checkComponentPermission}.
6163        Identity tlsIdentity = sCallerIdentity.get();
6164        if (tlsIdentity != null) {
6165            uid = tlsIdentity.uid;
6166            pid = tlsIdentity.pid;
6167        }
6168
6169        // Our own process gets to do everything.
6170        if (pid == MY_PID) {
6171            return PackageManager.PERMISSION_GRANTED;
6172        }
6173        synchronized (this) {
6174            return checkUriPermissionLocked(uri, uid, modeFlags)
6175                    ? PackageManager.PERMISSION_GRANTED
6176                    : PackageManager.PERMISSION_DENIED;
6177        }
6178    }
6179
6180    /**
6181     * Check if the targetPkg can be granted permission to access uri by
6182     * the callingUid using the given modeFlags.  Throws a security exception
6183     * if callingUid is not allowed to do this.  Returns the uid of the target
6184     * if the URI permission grant should be performed; returns -1 if it is not
6185     * needed (for example targetPkg already has permission to access the URI).
6186     * If you already know the uid of the target, you can supply it in
6187     * lastTargetUid else set that to -1.
6188     */
6189    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6190            Uri uri, final int modeFlags, int lastTargetUid) {
6191        if (!Intent.isAccessUriMode(modeFlags)) {
6192            return -1;
6193        }
6194
6195        if (targetPkg != null) {
6196            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6197                    "Checking grant " + targetPkg + " permission to " + uri);
6198        }
6199
6200        final IPackageManager pm = AppGlobals.getPackageManager();
6201
6202        // If this is not a content: uri, we can't do anything with it.
6203        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6204            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6205                    "Can't grant URI permission for non-content URI: " + uri);
6206            return -1;
6207        }
6208
6209        final String authority = uri.getAuthority();
6210        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6211        if (pi == null) {
6212            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6213            return -1;
6214        }
6215
6216        int targetUid = lastTargetUid;
6217        if (targetUid < 0 && targetPkg != null) {
6218            try {
6219                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6220                if (targetUid < 0) {
6221                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6222                            "Can't grant URI permission no uid for: " + targetPkg);
6223                    return -1;
6224                }
6225            } catch (RemoteException ex) {
6226                return -1;
6227            }
6228        }
6229
6230        if (targetUid >= 0) {
6231            // First...  does the target actually need this permission?
6232            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6233                // No need to grant the target this permission.
6234                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6235                        "Target " + targetPkg + " already has full permission to " + uri);
6236                return -1;
6237            }
6238        } else {
6239            // First...  there is no target package, so can anyone access it?
6240            boolean allowed = pi.exported;
6241            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6242                if (pi.readPermission != null) {
6243                    allowed = false;
6244                }
6245            }
6246            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6247                if (pi.writePermission != null) {
6248                    allowed = false;
6249                }
6250            }
6251            if (allowed) {
6252                return -1;
6253            }
6254        }
6255
6256        // Second...  is the provider allowing granting of URI permissions?
6257        if (!pi.grantUriPermissions) {
6258            throw new SecurityException("Provider " + pi.packageName
6259                    + "/" + pi.name
6260                    + " does not allow granting of Uri permissions (uri "
6261                    + uri + ")");
6262        }
6263        if (pi.uriPermissionPatterns != null) {
6264            final int N = pi.uriPermissionPatterns.length;
6265            boolean allowed = false;
6266            for (int i=0; i<N; i++) {
6267                if (pi.uriPermissionPatterns[i] != null
6268                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6269                    allowed = true;
6270                    break;
6271                }
6272            }
6273            if (!allowed) {
6274                throw new SecurityException("Provider " + pi.packageName
6275                        + "/" + pi.name
6276                        + " does not allow granting of permission to path of Uri "
6277                        + uri);
6278            }
6279        }
6280
6281        // Third...  does the caller itself have permission to access
6282        // this uri?
6283        if (callingUid != Process.myUid()) {
6284            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6285                // Require they hold a strong enough Uri permission
6286                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6287                    throw new SecurityException("Uid " + callingUid
6288                            + " does not have permission to uri " + uri);
6289                }
6290            }
6291        }
6292
6293        return targetUid;
6294    }
6295
6296    @Override
6297    public int checkGrantUriPermission(int callingUid, String targetPkg,
6298            Uri uri, final int modeFlags) {
6299        enforceNotIsolatedCaller("checkGrantUriPermission");
6300        synchronized(this) {
6301            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6302        }
6303    }
6304
6305    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6306            final int modeFlags, UriPermissionOwner owner) {
6307        if (!Intent.isAccessUriMode(modeFlags)) {
6308            return;
6309        }
6310
6311        // So here we are: the caller has the assumed permission
6312        // to the uri, and the target doesn't.  Let's now give this to
6313        // the target.
6314
6315        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6316                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6317
6318        final String authority = uri.getAuthority();
6319        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6320        if (pi == null) {
6321            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6322            return;
6323        }
6324
6325        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6326        final UriPermission perm = findOrCreateUriPermissionLocked(
6327                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6328        perm.grantModes(modeFlags, owner);
6329    }
6330
6331    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6332            final int modeFlags, UriPermissionOwner owner) {
6333        if (targetPkg == null) {
6334            throw new NullPointerException("targetPkg");
6335        }
6336
6337        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6338        if (targetUid < 0) {
6339            return;
6340        }
6341
6342        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6343    }
6344
6345    static class NeededUriGrants extends ArrayList<Uri> {
6346        final String targetPkg;
6347        final int targetUid;
6348        final int flags;
6349
6350        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6351            this.targetPkg = targetPkg;
6352            this.targetUid = targetUid;
6353            this.flags = flags;
6354        }
6355    }
6356
6357    /**
6358     * Like checkGrantUriPermissionLocked, but takes an Intent.
6359     */
6360    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6361            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6362        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6363                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6364                + " clip=" + (intent != null ? intent.getClipData() : null)
6365                + " from " + intent + "; flags=0x"
6366                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6367
6368        if (targetPkg == null) {
6369            throw new NullPointerException("targetPkg");
6370        }
6371
6372        if (intent == null) {
6373            return null;
6374        }
6375        Uri data = intent.getData();
6376        ClipData clip = intent.getClipData();
6377        if (data == null && clip == null) {
6378            return null;
6379        }
6380
6381        if (data != null) {
6382            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6383                mode, needed != null ? needed.targetUid : -1);
6384            if (targetUid > 0) {
6385                if (needed == null) {
6386                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6387                }
6388                needed.add(data);
6389            }
6390        }
6391        if (clip != null) {
6392            for (int i=0; i<clip.getItemCount(); i++) {
6393                Uri uri = clip.getItemAt(i).getUri();
6394                if (uri != null) {
6395                    int targetUid = -1;
6396                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6397                            mode, needed != null ? needed.targetUid : -1);
6398                    if (targetUid > 0) {
6399                        if (needed == null) {
6400                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6401                        }
6402                        needed.add(uri);
6403                    }
6404                } else {
6405                    Intent clipIntent = clip.getItemAt(i).getIntent();
6406                    if (clipIntent != null) {
6407                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6408                                callingUid, targetPkg, clipIntent, mode, needed);
6409                        if (newNeeded != null) {
6410                            needed = newNeeded;
6411                        }
6412                    }
6413                }
6414            }
6415        }
6416
6417        return needed;
6418    }
6419
6420    /**
6421     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6422     */
6423    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6424            UriPermissionOwner owner) {
6425        if (needed != null) {
6426            for (int i=0; i<needed.size(); i++) {
6427                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6428                        needed.get(i), needed.flags, owner);
6429            }
6430        }
6431    }
6432
6433    void grantUriPermissionFromIntentLocked(int callingUid,
6434            String targetPkg, Intent intent, UriPermissionOwner owner) {
6435        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6436                intent, intent != null ? intent.getFlags() : 0, null);
6437        if (needed == null) {
6438            return;
6439        }
6440
6441        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6442    }
6443
6444    @Override
6445    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6446            Uri uri, final int modeFlags) {
6447        enforceNotIsolatedCaller("grantUriPermission");
6448        synchronized(this) {
6449            final ProcessRecord r = getRecordForAppLocked(caller);
6450            if (r == null) {
6451                throw new SecurityException("Unable to find app for caller "
6452                        + caller
6453                        + " when granting permission to uri " + uri);
6454            }
6455            if (targetPkg == null) {
6456                throw new IllegalArgumentException("null target");
6457            }
6458            if (uri == null) {
6459                throw new IllegalArgumentException("null uri");
6460            }
6461
6462            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6463                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6464                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6465                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6466
6467            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6468        }
6469    }
6470
6471    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6472        if (perm.modeFlags == 0) {
6473            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6474                    perm.targetUid);
6475            if (perms != null) {
6476                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6477                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6478
6479                perms.remove(perm.uri);
6480                if (perms.isEmpty()) {
6481                    mGrantedUriPermissions.remove(perm.targetUid);
6482                }
6483            }
6484        }
6485    }
6486
6487    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6488        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6489
6490        final IPackageManager pm = AppGlobals.getPackageManager();
6491        final String authority = uri.getAuthority();
6492        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6493        if (pi == null) {
6494            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6495            return;
6496        }
6497
6498        // Does the caller have this permission on the URI?
6499        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6500            // Right now, if you are not the original owner of the permission,
6501            // you are not allowed to revoke it.
6502            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6503                throw new SecurityException("Uid " + callingUid
6504                        + " does not have permission to uri " + uri);
6505            //}
6506        }
6507
6508        boolean persistChanged = false;
6509
6510        // Go through all of the permissions and remove any that match.
6511        int N = mGrantedUriPermissions.size();
6512        for (int i = 0; i < N; i++) {
6513            final int targetUid = mGrantedUriPermissions.keyAt(i);
6514            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6515
6516            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6517                final UriPermission perm = it.next();
6518                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6519                    if (DEBUG_URI_PERMISSION)
6520                        Slog.v(TAG,
6521                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6522                    persistChanged |= perm.revokeModes(
6523                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6524                    if (perm.modeFlags == 0) {
6525                        it.remove();
6526                    }
6527                }
6528            }
6529
6530            if (perms.isEmpty()) {
6531                mGrantedUriPermissions.remove(targetUid);
6532                N--;
6533                i--;
6534            }
6535        }
6536
6537        if (persistChanged) {
6538            schedulePersistUriGrants();
6539        }
6540    }
6541
6542    @Override
6543    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6544            final int modeFlags) {
6545        enforceNotIsolatedCaller("revokeUriPermission");
6546        synchronized(this) {
6547            final ProcessRecord r = getRecordForAppLocked(caller);
6548            if (r == null) {
6549                throw new SecurityException("Unable to find app for caller "
6550                        + caller
6551                        + " when revoking permission to uri " + uri);
6552            }
6553            if (uri == null) {
6554                Slog.w(TAG, "revokeUriPermission: null uri");
6555                return;
6556            }
6557
6558            if (!Intent.isAccessUriMode(modeFlags)) {
6559                return;
6560            }
6561
6562            final IPackageManager pm = AppGlobals.getPackageManager();
6563            final String authority = uri.getAuthority();
6564            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6565            if (pi == null) {
6566                Slog.w(TAG, "No content provider found for permission revoke: "
6567                        + uri.toSafeString());
6568                return;
6569            }
6570
6571            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6572        }
6573    }
6574
6575    /**
6576     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6577     * given package.
6578     *
6579     * @param packageName Package name to match, or {@code null} to apply to all
6580     *            packages.
6581     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6582     *            to all users.
6583     * @param persistable If persistable grants should be removed.
6584     */
6585    private void removeUriPermissionsForPackageLocked(
6586            String packageName, int userHandle, boolean persistable) {
6587        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6588            throw new IllegalArgumentException("Must narrow by either package or user");
6589        }
6590
6591        boolean persistChanged = false;
6592
6593        int N = mGrantedUriPermissions.size();
6594        for (int i = 0; i < N; i++) {
6595            final int targetUid = mGrantedUriPermissions.keyAt(i);
6596            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6597
6598            // Only inspect grants matching user
6599            if (userHandle == UserHandle.USER_ALL
6600                    || userHandle == UserHandle.getUserId(targetUid)) {
6601                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6602                    final UriPermission perm = it.next();
6603
6604                    // Only inspect grants matching package
6605                    if (packageName == null || perm.sourcePkg.equals(packageName)
6606                            || perm.targetPkg.equals(packageName)) {
6607                        persistChanged |= perm.revokeModes(
6608                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6609
6610                        // Only remove when no modes remain; any persisted grants
6611                        // will keep this alive.
6612                        if (perm.modeFlags == 0) {
6613                            it.remove();
6614                        }
6615                    }
6616                }
6617
6618                if (perms.isEmpty()) {
6619                    mGrantedUriPermissions.remove(targetUid);
6620                    N--;
6621                    i--;
6622                }
6623            }
6624        }
6625
6626        if (persistChanged) {
6627            schedulePersistUriGrants();
6628        }
6629    }
6630
6631    @Override
6632    public IBinder newUriPermissionOwner(String name) {
6633        enforceNotIsolatedCaller("newUriPermissionOwner");
6634        synchronized(this) {
6635            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6636            return owner.getExternalTokenLocked();
6637        }
6638    }
6639
6640    @Override
6641    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6642            Uri uri, final int modeFlags) {
6643        synchronized(this) {
6644            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6645            if (owner == null) {
6646                throw new IllegalArgumentException("Unknown owner: " + token);
6647            }
6648            if (fromUid != Binder.getCallingUid()) {
6649                if (Binder.getCallingUid() != Process.myUid()) {
6650                    // Only system code can grant URI permissions on behalf
6651                    // of other users.
6652                    throw new SecurityException("nice try");
6653                }
6654            }
6655            if (targetPkg == null) {
6656                throw new IllegalArgumentException("null target");
6657            }
6658            if (uri == null) {
6659                throw new IllegalArgumentException("null uri");
6660            }
6661
6662            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6663        }
6664    }
6665
6666    @Override
6667    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6668        synchronized(this) {
6669            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6670            if (owner == null) {
6671                throw new IllegalArgumentException("Unknown owner: " + token);
6672            }
6673
6674            if (uri == null) {
6675                owner.removeUriPermissionsLocked(mode);
6676            } else {
6677                owner.removeUriPermissionLocked(uri, mode);
6678            }
6679        }
6680    }
6681
6682    private void schedulePersistUriGrants() {
6683        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6684            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6685                    10 * DateUtils.SECOND_IN_MILLIS);
6686        }
6687    }
6688
6689    private void writeGrantedUriPermissions() {
6690        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6691
6692        // Snapshot permissions so we can persist without lock
6693        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6694        synchronized (this) {
6695            final int size = mGrantedUriPermissions.size();
6696            for (int i = 0; i < size; i++) {
6697                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6698                for (UriPermission perm : perms.values()) {
6699                    if (perm.persistedModeFlags != 0) {
6700                        persist.add(perm.snapshot());
6701                    }
6702                }
6703            }
6704        }
6705
6706        FileOutputStream fos = null;
6707        try {
6708            fos = mGrantFile.startWrite();
6709
6710            XmlSerializer out = new FastXmlSerializer();
6711            out.setOutput(fos, "utf-8");
6712            out.startDocument(null, true);
6713            out.startTag(null, TAG_URI_GRANTS);
6714            for (UriPermission.Snapshot perm : persist) {
6715                out.startTag(null, TAG_URI_GRANT);
6716                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6717                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6718                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6719                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6720                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6721                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6722                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6723                out.endTag(null, TAG_URI_GRANT);
6724            }
6725            out.endTag(null, TAG_URI_GRANTS);
6726            out.endDocument();
6727
6728            mGrantFile.finishWrite(fos);
6729        } catch (IOException e) {
6730            if (fos != null) {
6731                mGrantFile.failWrite(fos);
6732            }
6733        }
6734    }
6735
6736    private void readGrantedUriPermissionsLocked() {
6737        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6738
6739        final long now = System.currentTimeMillis();
6740
6741        FileInputStream fis = null;
6742        try {
6743            fis = mGrantFile.openRead();
6744            final XmlPullParser in = Xml.newPullParser();
6745            in.setInput(fis, null);
6746
6747            int type;
6748            while ((type = in.next()) != END_DOCUMENT) {
6749                final String tag = in.getName();
6750                if (type == START_TAG) {
6751                    if (TAG_URI_GRANT.equals(tag)) {
6752                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6753                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6754                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6755                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6756                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6757                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6758                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6759
6760                        // Sanity check that provider still belongs to source package
6761                        final ProviderInfo pi = getProviderInfoLocked(
6762                                uri.getAuthority(), userHandle);
6763                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6764                            int targetUid = -1;
6765                            try {
6766                                targetUid = AppGlobals.getPackageManager()
6767                                        .getPackageUid(targetPkg, userHandle);
6768                            } catch (RemoteException e) {
6769                            }
6770                            if (targetUid != -1) {
6771                                final UriPermission perm = findOrCreateUriPermissionLocked(
6772                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6773                                perm.initPersistedModes(modeFlags, createdTime);
6774                            }
6775                        } else {
6776                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6777                                    + " but instead found " + pi);
6778                        }
6779                    }
6780                }
6781            }
6782        } catch (FileNotFoundException e) {
6783            // Missing grants is okay
6784        } catch (IOException e) {
6785            Log.wtf(TAG, "Failed reading Uri grants", e);
6786        } catch (XmlPullParserException e) {
6787            Log.wtf(TAG, "Failed reading Uri grants", e);
6788        } finally {
6789            IoUtils.closeQuietly(fis);
6790        }
6791    }
6792
6793    @Override
6794    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6795        enforceNotIsolatedCaller("takePersistableUriPermission");
6796
6797        Preconditions.checkFlagsArgument(modeFlags,
6798                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6799
6800        synchronized (this) {
6801            final int callingUid = Binder.getCallingUid();
6802            boolean persistChanged = false;
6803
6804            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6805            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6806
6807            final boolean exactValid = (exactPerm != null)
6808                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6809            final boolean prefixValid = (prefixPerm != null)
6810                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6811
6812            if (!(exactValid || prefixValid)) {
6813                throw new SecurityException("No persistable permission grants found for UID "
6814                        + callingUid + " and Uri " + uri.toSafeString());
6815            }
6816
6817            if (exactValid) {
6818                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6819            }
6820            if (prefixValid) {
6821                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6822            }
6823
6824            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6825
6826            if (persistChanged) {
6827                schedulePersistUriGrants();
6828            }
6829        }
6830    }
6831
6832    @Override
6833    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6834        enforceNotIsolatedCaller("releasePersistableUriPermission");
6835
6836        Preconditions.checkFlagsArgument(modeFlags,
6837                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6838
6839        synchronized (this) {
6840            final int callingUid = Binder.getCallingUid();
6841            boolean persistChanged = false;
6842
6843            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6844            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6845            if (exactPerm == null && prefixPerm == null) {
6846                throw new SecurityException("No permission grants found for UID " + callingUid
6847                        + " and Uri " + uri.toSafeString());
6848            }
6849
6850            if (exactPerm != null) {
6851                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6852                removeUriPermissionIfNeededLocked(exactPerm);
6853            }
6854            if (prefixPerm != null) {
6855                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6856                removeUriPermissionIfNeededLocked(prefixPerm);
6857            }
6858
6859            if (persistChanged) {
6860                schedulePersistUriGrants();
6861            }
6862        }
6863    }
6864
6865    /**
6866     * Prune any older {@link UriPermission} for the given UID until outstanding
6867     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6868     *
6869     * @return if any mutations occured that require persisting.
6870     */
6871    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6872        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6873        if (perms == null) return false;
6874        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6875
6876        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6877        for (UriPermission perm : perms.values()) {
6878            if (perm.persistedModeFlags != 0) {
6879                persisted.add(perm);
6880            }
6881        }
6882
6883        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6884        if (trimCount <= 0) return false;
6885
6886        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6887        for (int i = 0; i < trimCount; i++) {
6888            final UriPermission perm = persisted.get(i);
6889
6890            if (DEBUG_URI_PERMISSION) {
6891                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6892            }
6893
6894            perm.releasePersistableModes(~0);
6895            removeUriPermissionIfNeededLocked(perm);
6896        }
6897
6898        return true;
6899    }
6900
6901    @Override
6902    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6903            String packageName, boolean incoming) {
6904        enforceNotIsolatedCaller("getPersistedUriPermissions");
6905        Preconditions.checkNotNull(packageName, "packageName");
6906
6907        final int callingUid = Binder.getCallingUid();
6908        final IPackageManager pm = AppGlobals.getPackageManager();
6909        try {
6910            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6911            if (packageUid != callingUid) {
6912                throw new SecurityException(
6913                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6914            }
6915        } catch (RemoteException e) {
6916            throw new SecurityException("Failed to verify package name ownership");
6917        }
6918
6919        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6920        synchronized (this) {
6921            if (incoming) {
6922                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6923                        callingUid);
6924                if (perms == null) {
6925                    Slog.w(TAG, "No permission grants found for " + packageName);
6926                } else {
6927                    for (UriPermission perm : perms.values()) {
6928                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6929                            result.add(perm.buildPersistedPublicApiObject());
6930                        }
6931                    }
6932                }
6933            } else {
6934                final int size = mGrantedUriPermissions.size();
6935                for (int i = 0; i < size; i++) {
6936                    final ArrayMap<GrantUri, UriPermission> perms =
6937                            mGrantedUriPermissions.valueAt(i);
6938                    for (UriPermission perm : perms.values()) {
6939                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6940                            result.add(perm.buildPersistedPublicApiObject());
6941                        }
6942                    }
6943                }
6944            }
6945        }
6946        return new ParceledListSlice<android.content.UriPermission>(result);
6947    }
6948
6949    @Override
6950    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6951        synchronized (this) {
6952            ProcessRecord app =
6953                who != null ? getRecordForAppLocked(who) : null;
6954            if (app == null) return;
6955
6956            Message msg = Message.obtain();
6957            msg.what = WAIT_FOR_DEBUGGER_MSG;
6958            msg.obj = app;
6959            msg.arg1 = waiting ? 1 : 0;
6960            mHandler.sendMessage(msg);
6961        }
6962    }
6963
6964    @Override
6965    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6966        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6967        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6968        outInfo.availMem = Process.getFreeMemory();
6969        outInfo.totalMem = Process.getTotalMemory();
6970        outInfo.threshold = homeAppMem;
6971        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6972        outInfo.hiddenAppThreshold = cachedAppMem;
6973        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6974                ProcessList.SERVICE_ADJ);
6975        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6976                ProcessList.VISIBLE_APP_ADJ);
6977        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6978                ProcessList.FOREGROUND_APP_ADJ);
6979    }
6980
6981    // =========================================================
6982    // TASK MANAGEMENT
6983    // =========================================================
6984
6985    @Override
6986    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6987                         IThumbnailReceiver receiver) {
6988        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6989
6990        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6991        ActivityRecord topRecord = null;
6992
6993        synchronized(this) {
6994            if (localLOGV) Slog.v(
6995                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6996                + ", receiver=" + receiver);
6997
6998            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6999                    != PackageManager.PERMISSION_GRANTED) {
7000                if (receiver != null) {
7001                    // If the caller wants to wait for pending thumbnails,
7002                    // it ain't gonna get them.
7003                    try {
7004                        receiver.finished();
7005                    } catch (RemoteException ex) {
7006                    }
7007                }
7008                String msg = "Permission Denial: getTasks() from pid="
7009                        + Binder.getCallingPid()
7010                        + ", uid=" + Binder.getCallingUid()
7011                        + " requires " + android.Manifest.permission.GET_TASKS;
7012                Slog.w(TAG, msg);
7013                throw new SecurityException(msg);
7014            }
7015
7016            // TODO: Improve with MRU list from all ActivityStacks.
7017            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
7018
7019            if (!pending.pendingRecords.isEmpty()) {
7020                mPendingThumbnails.add(pending);
7021            }
7022        }
7023
7024        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
7025
7026        if (topRecord != null) {
7027            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
7028            try {
7029                IApplicationThread topThumbnail = topRecord.app.thread;
7030                topThumbnail.requestThumbnail(topRecord.appToken);
7031            } catch (Exception e) {
7032                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
7033                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
7034            }
7035        }
7036
7037        if (pending.pendingRecords.isEmpty() && receiver != null) {
7038            // In this case all thumbnails were available and the client
7039            // is being asked to be told when the remaining ones come in...
7040            // which is unusually, since the top-most currently running
7041            // activity should never have a canned thumbnail!  Oh well.
7042            try {
7043                receiver.finished();
7044            } catch (RemoteException ex) {
7045            }
7046        }
7047
7048        return list;
7049    }
7050
7051    TaskRecord getMostRecentTask() {
7052        return mRecentTasks.get(0);
7053    }
7054
7055    @Override
7056    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7057            int flags, int userId) {
7058        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7059                false, true, "getRecentTasks", null);
7060
7061        synchronized (this) {
7062            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
7063                    "getRecentTasks()");
7064            final boolean detailed = checkCallingPermission(
7065                    android.Manifest.permission.GET_DETAILED_TASKS)
7066                    == PackageManager.PERMISSION_GRANTED;
7067
7068            IPackageManager pm = AppGlobals.getPackageManager();
7069
7070            final int N = mRecentTasks.size();
7071            ArrayList<ActivityManager.RecentTaskInfo> res
7072                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7073                            maxNum < N ? maxNum : N);
7074
7075            final Set<Integer> includedUsers;
7076            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7077                includedUsers = getProfileIdsLocked(userId);
7078            } else {
7079                includedUsers = new HashSet<Integer>();
7080            }
7081            includedUsers.add(Integer.valueOf(userId));
7082            for (int i=0; i<N && maxNum > 0; i++) {
7083                TaskRecord tr = mRecentTasks.get(i);
7084                // Only add calling user or related users recent tasks
7085                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7086
7087                // Return the entry if desired by the caller.  We always return
7088                // the first entry, because callers always expect this to be the
7089                // foreground app.  We may filter others if the caller has
7090                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7091                // we should exclude the entry.
7092
7093                if (i == 0
7094                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7095                        || (tr.intent == null)
7096                        || ((tr.intent.getFlags()
7097                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7098                    ActivityManager.RecentTaskInfo rti
7099                            = new ActivityManager.RecentTaskInfo();
7100                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7101                    rti.persistentId = tr.taskId;
7102                    rti.baseIntent = new Intent(
7103                            tr.intent != null ? tr.intent : tr.affinityIntent);
7104                    if (!detailed) {
7105                        rti.baseIntent.replaceExtras((Bundle)null);
7106                    }
7107                    rti.origActivity = tr.origActivity;
7108                    rti.description = tr.lastDescription;
7109                    rti.stackId = tr.stack.mStackId;
7110                    rti.userId = tr.userId;
7111
7112                    // Traverse upwards looking for any break between main task activities and
7113                    // utility activities.
7114                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7115                    int activityNdx;
7116                    final int numActivities = activities.size();
7117                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7118                            ++activityNdx) {
7119                        final ActivityRecord r = activities.get(activityNdx);
7120                        if (r.intent != null &&
7121                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7122                                        != 0) {
7123                            break;
7124                        }
7125                    }
7126                    // Traverse downwards starting below break looking for set label and icon.
7127                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
7128                        final ActivityRecord r = activities.get(activityNdx);
7129                        if (r.activityLabel != null || r.activityIcon != null) {
7130                            rti.activityLabel = r.activityLabel;
7131                            rti.activityIcon = r.activityIcon;
7132                            break;
7133                        }
7134                    }
7135
7136                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7137                        // Check whether this activity is currently available.
7138                        try {
7139                            if (rti.origActivity != null) {
7140                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7141                                        == null) {
7142                                    continue;
7143                                }
7144                            } else if (rti.baseIntent != null) {
7145                                if (pm.queryIntentActivities(rti.baseIntent,
7146                                        null, 0, userId) == null) {
7147                                    continue;
7148                                }
7149                            }
7150                        } catch (RemoteException e) {
7151                            // Will never happen.
7152                        }
7153                    }
7154
7155                    res.add(rti);
7156                    maxNum--;
7157                }
7158            }
7159            return res;
7160        }
7161    }
7162
7163    private TaskRecord recentTaskForIdLocked(int id) {
7164        final int N = mRecentTasks.size();
7165            for (int i=0; i<N; i++) {
7166                TaskRecord tr = mRecentTasks.get(i);
7167                if (tr.taskId == id) {
7168                    return tr;
7169                }
7170            }
7171            return null;
7172    }
7173
7174    @Override
7175    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7176        synchronized (this) {
7177            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7178                    "getTaskThumbnails()");
7179            TaskRecord tr = recentTaskForIdLocked(id);
7180            if (tr != null) {
7181                return tr.getTaskThumbnailsLocked();
7182            }
7183        }
7184        return null;
7185    }
7186
7187    @Override
7188    public Bitmap getTaskTopThumbnail(int id) {
7189        synchronized (this) {
7190            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7191                    "getTaskTopThumbnail()");
7192            TaskRecord tr = recentTaskForIdLocked(id);
7193            if (tr != null) {
7194                return tr.getTaskTopThumbnailLocked();
7195            }
7196        }
7197        return null;
7198    }
7199
7200    @Override
7201    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7202            Bitmap activityIcon) {
7203        synchronized (this) {
7204            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7205            if (r != null) {
7206                r.activityLabel = activityLabel.toString();
7207                r.activityIcon = activityIcon;
7208            }
7209        }
7210    }
7211
7212    @Override
7213    public boolean removeSubTask(int taskId, int subTaskIndex) {
7214        synchronized (this) {
7215            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7216                    "removeSubTask()");
7217            long ident = Binder.clearCallingIdentity();
7218            try {
7219                TaskRecord tr = recentTaskForIdLocked(taskId);
7220                if (tr != null) {
7221                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7222                }
7223                return false;
7224            } finally {
7225                Binder.restoreCallingIdentity(ident);
7226            }
7227        }
7228    }
7229
7230    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7231        if (!pr.killedByAm) {
7232            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7233            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7234                    pr.processName, pr.setAdj, reason);
7235            pr.killedByAm = true;
7236            Process.killProcessQuiet(pr.pid);
7237        }
7238    }
7239
7240    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7241        tr.disposeThumbnail();
7242        mRecentTasks.remove(tr);
7243        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7244        Intent baseIntent = new Intent(
7245                tr.intent != null ? tr.intent : tr.affinityIntent);
7246        ComponentName component = baseIntent.getComponent();
7247        if (component == null) {
7248            Slog.w(TAG, "Now component for base intent of task: " + tr);
7249            return;
7250        }
7251
7252        // Find any running services associated with this app.
7253        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7254
7255        if (killProcesses) {
7256            // Find any running processes associated with this app.
7257            final String pkg = component.getPackageName();
7258            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7259            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7260            for (int i=0; i<pmap.size(); i++) {
7261                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7262                for (int j=0; j<uids.size(); j++) {
7263                    ProcessRecord proc = uids.valueAt(j);
7264                    if (proc.userId != tr.userId) {
7265                        continue;
7266                    }
7267                    if (!proc.pkgList.containsKey(pkg)) {
7268                        continue;
7269                    }
7270                    procs.add(proc);
7271                }
7272            }
7273
7274            // Kill the running processes.
7275            for (int i=0; i<procs.size(); i++) {
7276                ProcessRecord pr = procs.get(i);
7277                if (pr == mHomeProcess) {
7278                    // Don't kill the home process along with tasks from the same package.
7279                    continue;
7280                }
7281                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7282                    killUnneededProcessLocked(pr, "remove task");
7283                } else {
7284                    pr.waitingToKill = "remove task";
7285                }
7286            }
7287        }
7288    }
7289
7290    /**
7291     * Removes the task with the specified task id.
7292     *
7293     * @param taskId Identifier of the task to be removed.
7294     * @param flags Additional operational flags.  May be 0 or
7295     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7296     * @return Returns true if the given task was found and removed.
7297     */
7298    private boolean removeTaskByIdLocked(int taskId, int flags) {
7299        TaskRecord tr = recentTaskForIdLocked(taskId);
7300        if (tr != null) {
7301            tr.removeTaskActivitiesLocked(-1, false);
7302            cleanUpRemovedTaskLocked(tr, flags);
7303            return true;
7304        }
7305        return false;
7306    }
7307
7308    @Override
7309    public boolean removeTask(int taskId, int flags) {
7310        synchronized (this) {
7311            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7312                    "removeTask()");
7313            long ident = Binder.clearCallingIdentity();
7314            try {
7315                return removeTaskByIdLocked(taskId, flags);
7316            } finally {
7317                Binder.restoreCallingIdentity(ident);
7318            }
7319        }
7320    }
7321
7322    /**
7323     * TODO: Add mController hook
7324     */
7325    @Override
7326    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7327        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7328                "moveTaskToFront()");
7329
7330        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7331        synchronized(this) {
7332            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7333                    Binder.getCallingUid(), "Task to front")) {
7334                ActivityOptions.abort(options);
7335                return;
7336            }
7337            final long origId = Binder.clearCallingIdentity();
7338            try {
7339                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7340                if (task == null) {
7341                    return;
7342                }
7343                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7344                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7345                    return;
7346                }
7347                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7348            } finally {
7349                Binder.restoreCallingIdentity(origId);
7350            }
7351            ActivityOptions.abort(options);
7352        }
7353    }
7354
7355    @Override
7356    public void moveTaskToBack(int taskId) {
7357        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7358                "moveTaskToBack()");
7359
7360        synchronized(this) {
7361            TaskRecord tr = recentTaskForIdLocked(taskId);
7362            if (tr != null) {
7363                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7364                ActivityStack stack = tr.stack;
7365                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7366                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7367                            Binder.getCallingUid(), "Task to back")) {
7368                        return;
7369                    }
7370                }
7371                final long origId = Binder.clearCallingIdentity();
7372                try {
7373                    stack.moveTaskToBackLocked(taskId, null);
7374                } finally {
7375                    Binder.restoreCallingIdentity(origId);
7376                }
7377            }
7378        }
7379    }
7380
7381    /**
7382     * Moves an activity, and all of the other activities within the same task, to the bottom
7383     * of the history stack.  The activity's order within the task is unchanged.
7384     *
7385     * @param token A reference to the activity we wish to move
7386     * @param nonRoot If false then this only works if the activity is the root
7387     *                of a task; if true it will work for any activity in a task.
7388     * @return Returns true if the move completed, false if not.
7389     */
7390    @Override
7391    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7392        enforceNotIsolatedCaller("moveActivityTaskToBack");
7393        synchronized(this) {
7394            final long origId = Binder.clearCallingIdentity();
7395            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7396            if (taskId >= 0) {
7397                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7398            }
7399            Binder.restoreCallingIdentity(origId);
7400        }
7401        return false;
7402    }
7403
7404    @Override
7405    public void moveTaskBackwards(int task) {
7406        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7407                "moveTaskBackwards()");
7408
7409        synchronized(this) {
7410            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7411                    Binder.getCallingUid(), "Task backwards")) {
7412                return;
7413            }
7414            final long origId = Binder.clearCallingIdentity();
7415            moveTaskBackwardsLocked(task);
7416            Binder.restoreCallingIdentity(origId);
7417        }
7418    }
7419
7420    private final void moveTaskBackwardsLocked(int task) {
7421        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7422    }
7423
7424    @Override
7425    public IBinder getHomeActivityToken() throws RemoteException {
7426        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7427                "getHomeActivityToken()");
7428        synchronized (this) {
7429            return mStackSupervisor.getHomeActivityToken();
7430        }
7431    }
7432
7433    @Override
7434    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7435            IActivityContainerCallback callback) throws RemoteException {
7436        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7437                "createActivityContainer()");
7438        synchronized (this) {
7439            if (parentActivityToken == null) {
7440                throw new IllegalArgumentException("parent token must not be null");
7441            }
7442            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7443            if (r == null) {
7444                return null;
7445            }
7446            if (callback == null) {
7447                throw new IllegalArgumentException("callback must not be null");
7448            }
7449            return mStackSupervisor.createActivityContainer(r, callback);
7450        }
7451    }
7452
7453    @Override
7454    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7455        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7456                "deleteActivityContainer()");
7457        synchronized (this) {
7458            mStackSupervisor.deleteActivityContainer(container);
7459        }
7460    }
7461
7462    @Override
7463    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7464            throws RemoteException {
7465        synchronized (this) {
7466            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7467            if (stack != null) {
7468                return stack.mActivityContainer;
7469            }
7470            return null;
7471        }
7472    }
7473
7474    @Override
7475    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7476        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7477                "moveTaskToStack()");
7478        if (stackId == HOME_STACK_ID) {
7479            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7480                    new RuntimeException("here").fillInStackTrace());
7481        }
7482        synchronized (this) {
7483            long ident = Binder.clearCallingIdentity();
7484            try {
7485                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7486                        + stackId + " toTop=" + toTop);
7487                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7488            } finally {
7489                Binder.restoreCallingIdentity(ident);
7490            }
7491        }
7492    }
7493
7494    @Override
7495    public void resizeStack(int stackBoxId, Rect bounds) {
7496        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7497                "resizeStackBox()");
7498        long ident = Binder.clearCallingIdentity();
7499        try {
7500            mWindowManager.resizeStack(stackBoxId, bounds);
7501        } finally {
7502            Binder.restoreCallingIdentity(ident);
7503        }
7504    }
7505
7506    @Override
7507    public List<StackInfo> getAllStackInfos() {
7508        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7509                "getAllStackInfos()");
7510        long ident = Binder.clearCallingIdentity();
7511        try {
7512            synchronized (this) {
7513                return mStackSupervisor.getAllStackInfosLocked();
7514            }
7515        } finally {
7516            Binder.restoreCallingIdentity(ident);
7517        }
7518    }
7519
7520    @Override
7521    public StackInfo getStackInfo(int stackId) {
7522        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7523                "getStackInfo()");
7524        long ident = Binder.clearCallingIdentity();
7525        try {
7526            synchronized (this) {
7527                return mStackSupervisor.getStackInfoLocked(stackId);
7528            }
7529        } finally {
7530            Binder.restoreCallingIdentity(ident);
7531        }
7532    }
7533
7534    @Override
7535    public boolean isInHomeStack(int taskId) {
7536        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7537                "getStackInfo()");
7538        long ident = Binder.clearCallingIdentity();
7539        try {
7540            synchronized (this) {
7541                TaskRecord tr = recentTaskForIdLocked(taskId);
7542                if (tr != null) {
7543                    return tr.stack.isHomeStack();
7544                }
7545            }
7546        } finally {
7547            Binder.restoreCallingIdentity(ident);
7548        }
7549        return false;
7550    }
7551
7552    @Override
7553    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7554        synchronized(this) {
7555            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7556        }
7557    }
7558
7559    private boolean isLockTaskAuthorized(ComponentName name) {
7560//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7561//                "startLockTaskMode()");
7562//        DevicePolicyManager dpm = (DevicePolicyManager)
7563//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7564//        return dpm != null && dpm.isLockTaskPermitted(name);
7565        return true;
7566    }
7567
7568    private void startLockTaskMode(TaskRecord task) {
7569        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7570            return;
7571        }
7572        long ident = Binder.clearCallingIdentity();
7573        try {
7574            synchronized (this) {
7575                // Since we lost lock on task, make sure it is still there.
7576                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7577                if (task != null) {
7578                    mStackSupervisor.setLockTaskModeLocked(task);
7579                }
7580            }
7581        } finally {
7582            Binder.restoreCallingIdentity(ident);
7583        }
7584    }
7585
7586    @Override
7587    public void startLockTaskMode(int taskId) {
7588        long ident = Binder.clearCallingIdentity();
7589        try {
7590            final TaskRecord task;
7591            synchronized (this) {
7592                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7593            }
7594            if (task != null) {
7595                startLockTaskMode(task);
7596            }
7597        } finally {
7598            Binder.restoreCallingIdentity(ident);
7599        }
7600    }
7601
7602    @Override
7603    public void startLockTaskMode(IBinder token) {
7604        long ident = Binder.clearCallingIdentity();
7605        try {
7606            final TaskRecord task;
7607            synchronized (this) {
7608                final ActivityRecord r = ActivityRecord.forToken(token);
7609                if (r == null) {
7610                    return;
7611                }
7612                task = r.task;
7613            }
7614            if (task != null) {
7615                startLockTaskMode(task);
7616            }
7617        } finally {
7618            Binder.restoreCallingIdentity(ident);
7619        }
7620    }
7621
7622    @Override
7623    public void stopLockTaskMode() {
7624//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7625//                "stopLockTaskMode()");
7626        synchronized (this) {
7627            mStackSupervisor.setLockTaskModeLocked(null);
7628        }
7629    }
7630
7631    @Override
7632    public boolean isInLockTaskMode() {
7633        synchronized (this) {
7634            return mStackSupervisor.isInLockTaskMode();
7635        }
7636    }
7637
7638    // =========================================================
7639    // THUMBNAILS
7640    // =========================================================
7641
7642    public void reportThumbnail(IBinder token,
7643            Bitmap thumbnail, CharSequence description) {
7644        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7645        final long origId = Binder.clearCallingIdentity();
7646        sendPendingThumbnail(null, token, thumbnail, description, true);
7647        Binder.restoreCallingIdentity(origId);
7648    }
7649
7650    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7651            Bitmap thumbnail, CharSequence description, boolean always) {
7652        TaskRecord task;
7653        ArrayList<PendingThumbnailsRecord> receivers = null;
7654
7655        //System.out.println("Send pending thumbnail: " + r);
7656
7657        synchronized(this) {
7658            if (r == null) {
7659                r = ActivityRecord.isInStackLocked(token);
7660                if (r == null) {
7661                    return;
7662                }
7663            }
7664            if (thumbnail == null && r.thumbHolder != null) {
7665                thumbnail = r.thumbHolder.lastThumbnail;
7666                description = r.thumbHolder.lastDescription;
7667            }
7668            if (thumbnail == null && !always) {
7669                // If there is no thumbnail, and this entry is not actually
7670                // going away, then abort for now and pick up the next
7671                // thumbnail we get.
7672                return;
7673            }
7674            task = r.task;
7675
7676            int N = mPendingThumbnails.size();
7677            int i=0;
7678            while (i<N) {
7679                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7680                //System.out.println("Looking in " + pr.pendingRecords);
7681                if (pr.pendingRecords.remove(r)) {
7682                    if (receivers == null) {
7683                        receivers = new ArrayList<PendingThumbnailsRecord>();
7684                    }
7685                    receivers.add(pr);
7686                    if (pr.pendingRecords.size() == 0) {
7687                        pr.finished = true;
7688                        mPendingThumbnails.remove(i);
7689                        N--;
7690                        continue;
7691                    }
7692                }
7693                i++;
7694            }
7695        }
7696
7697        if (receivers != null) {
7698            final int N = receivers.size();
7699            for (int i=0; i<N; i++) {
7700                try {
7701                    PendingThumbnailsRecord pr = receivers.get(i);
7702                    pr.receiver.newThumbnail(
7703                        task != null ? task.taskId : -1, thumbnail, description);
7704                    if (pr.finished) {
7705                        pr.receiver.finished();
7706                    }
7707                } catch (Exception e) {
7708                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7709                }
7710            }
7711        }
7712    }
7713
7714    // =========================================================
7715    // CONTENT PROVIDERS
7716    // =========================================================
7717
7718    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7719        List<ProviderInfo> providers = null;
7720        try {
7721            providers = AppGlobals.getPackageManager().
7722                queryContentProviders(app.processName, app.uid,
7723                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7724        } catch (RemoteException ex) {
7725        }
7726        if (DEBUG_MU)
7727            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7728        int userId = app.userId;
7729        if (providers != null) {
7730            int N = providers.size();
7731            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7732            for (int i=0; i<N; i++) {
7733                ProviderInfo cpi =
7734                    (ProviderInfo)providers.get(i);
7735                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7736                        cpi.name, cpi.flags);
7737                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7738                    // This is a singleton provider, but a user besides the
7739                    // default user is asking to initialize a process it runs
7740                    // in...  well, no, it doesn't actually run in this process,
7741                    // it runs in the process of the default user.  Get rid of it.
7742                    providers.remove(i);
7743                    N--;
7744                    i--;
7745                    continue;
7746                }
7747
7748                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7749                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7750                if (cpr == null) {
7751                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7752                    mProviderMap.putProviderByClass(comp, cpr);
7753                }
7754                if (DEBUG_MU)
7755                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7756                app.pubProviders.put(cpi.name, cpr);
7757                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7758                    // Don't add this if it is a platform component that is marked
7759                    // to run in multiple processes, because this is actually
7760                    // part of the framework so doesn't make sense to track as a
7761                    // separate apk in the process.
7762                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7763                }
7764                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7765            }
7766        }
7767        return providers;
7768    }
7769
7770    /**
7771     * Check if {@link ProcessRecord} has a possible chance at accessing the
7772     * given {@link ProviderInfo}. Final permission checking is always done
7773     * in {@link ContentProvider}.
7774     */
7775    private final String checkContentProviderPermissionLocked(
7776            ProviderInfo cpi, ProcessRecord r) {
7777        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7778        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7779        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7780                cpi.applicationInfo.uid, cpi.exported)
7781                == PackageManager.PERMISSION_GRANTED) {
7782            return null;
7783        }
7784        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7785                cpi.applicationInfo.uid, cpi.exported)
7786                == PackageManager.PERMISSION_GRANTED) {
7787            return null;
7788        }
7789
7790        PathPermission[] pps = cpi.pathPermissions;
7791        if (pps != null) {
7792            int i = pps.length;
7793            while (i > 0) {
7794                i--;
7795                PathPermission pp = pps[i];
7796                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7797                        cpi.applicationInfo.uid, cpi.exported)
7798                        == PackageManager.PERMISSION_GRANTED) {
7799                    return null;
7800                }
7801                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7802                        cpi.applicationInfo.uid, cpi.exported)
7803                        == PackageManager.PERMISSION_GRANTED) {
7804                    return null;
7805                }
7806            }
7807        }
7808
7809        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7810        if (perms != null) {
7811            for (GrantUri uri : perms.keySet()) {
7812                if (uri.uri.getAuthority().equals(cpi.authority)) {
7813                    return null;
7814                }
7815            }
7816        }
7817
7818        String msg;
7819        if (!cpi.exported) {
7820            msg = "Permission Denial: opening provider " + cpi.name
7821                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7822                    + ", uid=" + callingUid + ") that is not exported from uid "
7823                    + cpi.applicationInfo.uid;
7824        } else {
7825            msg = "Permission Denial: opening provider " + cpi.name
7826                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7827                    + ", uid=" + callingUid + ") requires "
7828                    + cpi.readPermission + " or " + cpi.writePermission;
7829        }
7830        Slog.w(TAG, msg);
7831        return msg;
7832    }
7833
7834    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7835            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7836        if (r != null) {
7837            for (int i=0; i<r.conProviders.size(); i++) {
7838                ContentProviderConnection conn = r.conProviders.get(i);
7839                if (conn.provider == cpr) {
7840                    if (DEBUG_PROVIDER) Slog.v(TAG,
7841                            "Adding provider requested by "
7842                            + r.processName + " from process "
7843                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7844                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7845                    if (stable) {
7846                        conn.stableCount++;
7847                        conn.numStableIncs++;
7848                    } else {
7849                        conn.unstableCount++;
7850                        conn.numUnstableIncs++;
7851                    }
7852                    return conn;
7853                }
7854            }
7855            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7856            if (stable) {
7857                conn.stableCount = 1;
7858                conn.numStableIncs = 1;
7859            } else {
7860                conn.unstableCount = 1;
7861                conn.numUnstableIncs = 1;
7862            }
7863            cpr.connections.add(conn);
7864            r.conProviders.add(conn);
7865            return conn;
7866        }
7867        cpr.addExternalProcessHandleLocked(externalProcessToken);
7868        return null;
7869    }
7870
7871    boolean decProviderCountLocked(ContentProviderConnection conn,
7872            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7873        if (conn != null) {
7874            cpr = conn.provider;
7875            if (DEBUG_PROVIDER) Slog.v(TAG,
7876                    "Removing provider requested by "
7877                    + conn.client.processName + " from process "
7878                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7879                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7880            if (stable) {
7881                conn.stableCount--;
7882            } else {
7883                conn.unstableCount--;
7884            }
7885            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7886                cpr.connections.remove(conn);
7887                conn.client.conProviders.remove(conn);
7888                return true;
7889            }
7890            return false;
7891        }
7892        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7893        return false;
7894    }
7895
7896    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7897            String name, IBinder token, boolean stable, int userId) {
7898        ContentProviderRecord cpr;
7899        ContentProviderConnection conn = null;
7900        ProviderInfo cpi = null;
7901
7902        synchronized(this) {
7903            ProcessRecord r = null;
7904            if (caller != null) {
7905                r = getRecordForAppLocked(caller);
7906                if (r == null) {
7907                    throw new SecurityException(
7908                            "Unable to find app for caller " + caller
7909                          + " (pid=" + Binder.getCallingPid()
7910                          + ") when getting content provider " + name);
7911                }
7912            }
7913
7914            // First check if this content provider has been published...
7915            cpr = mProviderMap.getProviderByName(name, userId);
7916            boolean providerRunning = cpr != null;
7917            if (providerRunning) {
7918                cpi = cpr.info;
7919                String msg;
7920                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7921                    throw new SecurityException(msg);
7922                }
7923
7924                if (r != null && cpr.canRunHere(r)) {
7925                    // This provider has been published or is in the process
7926                    // of being published...  but it is also allowed to run
7927                    // in the caller's process, so don't make a connection
7928                    // and just let the caller instantiate its own instance.
7929                    ContentProviderHolder holder = cpr.newHolder(null);
7930                    // don't give caller the provider object, it needs
7931                    // to make its own.
7932                    holder.provider = null;
7933                    return holder;
7934                }
7935
7936                final long origId = Binder.clearCallingIdentity();
7937
7938                // In this case the provider instance already exists, so we can
7939                // return it right away.
7940                conn = incProviderCountLocked(r, cpr, token, stable);
7941                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7942                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7943                        // If this is a perceptible app accessing the provider,
7944                        // make sure to count it as being accessed and thus
7945                        // back up on the LRU list.  This is good because
7946                        // content providers are often expensive to start.
7947                        updateLruProcessLocked(cpr.proc, false, null);
7948                    }
7949                }
7950
7951                if (cpr.proc != null) {
7952                    if (false) {
7953                        if (cpr.name.flattenToShortString().equals(
7954                                "com.android.providers.calendar/.CalendarProvider2")) {
7955                            Slog.v(TAG, "****************** KILLING "
7956                                + cpr.name.flattenToShortString());
7957                            Process.killProcess(cpr.proc.pid);
7958                        }
7959                    }
7960                    boolean success = updateOomAdjLocked(cpr.proc);
7961                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7962                    // NOTE: there is still a race here where a signal could be
7963                    // pending on the process even though we managed to update its
7964                    // adj level.  Not sure what to do about this, but at least
7965                    // the race is now smaller.
7966                    if (!success) {
7967                        // Uh oh...  it looks like the provider's process
7968                        // has been killed on us.  We need to wait for a new
7969                        // process to be started, and make sure its death
7970                        // doesn't kill our process.
7971                        Slog.i(TAG,
7972                                "Existing provider " + cpr.name.flattenToShortString()
7973                                + " is crashing; detaching " + r);
7974                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7975                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7976                        if (!lastRef) {
7977                            // This wasn't the last ref our process had on
7978                            // the provider...  we have now been killed, bail.
7979                            return null;
7980                        }
7981                        providerRunning = false;
7982                        conn = null;
7983                    }
7984                }
7985
7986                Binder.restoreCallingIdentity(origId);
7987            }
7988
7989            boolean singleton;
7990            if (!providerRunning) {
7991                try {
7992                    cpi = AppGlobals.getPackageManager().
7993                        resolveContentProvider(name,
7994                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7995                } catch (RemoteException ex) {
7996                }
7997                if (cpi == null) {
7998                    return null;
7999                }
8000                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8001                        cpi.name, cpi.flags);
8002                if (singleton) {
8003                    userId = 0;
8004                }
8005                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8006
8007                String msg;
8008                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
8009                    throw new SecurityException(msg);
8010                }
8011
8012                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8013                        && !cpi.processName.equals("system")) {
8014                    // If this content provider does not run in the system
8015                    // process, and the system is not yet ready to run other
8016                    // processes, then fail fast instead of hanging.
8017                    throw new IllegalArgumentException(
8018                            "Attempt to launch content provider before system ready");
8019                }
8020
8021                // Make sure that the user who owns this provider is started.  If not,
8022                // we don't want to allow it to run.
8023                if (mStartedUsers.get(userId) == null) {
8024                    Slog.w(TAG, "Unable to launch app "
8025                            + cpi.applicationInfo.packageName + "/"
8026                            + cpi.applicationInfo.uid + " for provider "
8027                            + name + ": user " + userId + " is stopped");
8028                    return null;
8029                }
8030
8031                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8032                cpr = mProviderMap.getProviderByClass(comp, userId);
8033                final boolean firstClass = cpr == null;
8034                if (firstClass) {
8035                    try {
8036                        ApplicationInfo ai =
8037                            AppGlobals.getPackageManager().
8038                                getApplicationInfo(
8039                                        cpi.applicationInfo.packageName,
8040                                        STOCK_PM_FLAGS, userId);
8041                        if (ai == null) {
8042                            Slog.w(TAG, "No package info for content provider "
8043                                    + cpi.name);
8044                            return null;
8045                        }
8046                        ai = getAppInfoForUser(ai, userId);
8047                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8048                    } catch (RemoteException ex) {
8049                        // pm is in same process, this will never happen.
8050                    }
8051                }
8052
8053                if (r != null && cpr.canRunHere(r)) {
8054                    // If this is a multiprocess provider, then just return its
8055                    // info and allow the caller to instantiate it.  Only do
8056                    // this if the provider is the same user as the caller's
8057                    // process, or can run as root (so can be in any process).
8058                    return cpr.newHolder(null);
8059                }
8060
8061                if (DEBUG_PROVIDER) {
8062                    RuntimeException e = new RuntimeException("here");
8063                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8064                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8065                }
8066
8067                // This is single process, and our app is now connecting to it.
8068                // See if we are already in the process of launching this
8069                // provider.
8070                final int N = mLaunchingProviders.size();
8071                int i;
8072                for (i=0; i<N; i++) {
8073                    if (mLaunchingProviders.get(i) == cpr) {
8074                        break;
8075                    }
8076                }
8077
8078                // If the provider is not already being launched, then get it
8079                // started.
8080                if (i >= N) {
8081                    final long origId = Binder.clearCallingIdentity();
8082
8083                    try {
8084                        // Content provider is now in use, its package can't be stopped.
8085                        try {
8086                            AppGlobals.getPackageManager().setPackageStoppedState(
8087                                    cpr.appInfo.packageName, false, userId);
8088                        } catch (RemoteException e) {
8089                        } catch (IllegalArgumentException e) {
8090                            Slog.w(TAG, "Failed trying to unstop package "
8091                                    + cpr.appInfo.packageName + ": " + e);
8092                        }
8093
8094                        // Use existing process if already started
8095                        ProcessRecord proc = getProcessRecordLocked(
8096                                cpi.processName, cpr.appInfo.uid, false);
8097                        if (proc != null && proc.thread != null) {
8098                            if (DEBUG_PROVIDER) {
8099                                Slog.d(TAG, "Installing in existing process " + proc);
8100                            }
8101                            proc.pubProviders.put(cpi.name, cpr);
8102                            try {
8103                                proc.thread.scheduleInstallProvider(cpi);
8104                            } catch (RemoteException e) {
8105                            }
8106                        } else {
8107                            proc = startProcessLocked(cpi.processName,
8108                                    cpr.appInfo, false, 0, "content provider",
8109                                    new ComponentName(cpi.applicationInfo.packageName,
8110                                            cpi.name), false, false, false);
8111                            if (proc == null) {
8112                                Slog.w(TAG, "Unable to launch app "
8113                                        + cpi.applicationInfo.packageName + "/"
8114                                        + cpi.applicationInfo.uid + " for provider "
8115                                        + name + ": process is bad");
8116                                return null;
8117                            }
8118                        }
8119                        cpr.launchingApp = proc;
8120                        mLaunchingProviders.add(cpr);
8121                    } finally {
8122                        Binder.restoreCallingIdentity(origId);
8123                    }
8124                }
8125
8126                // Make sure the provider is published (the same provider class
8127                // may be published under multiple names).
8128                if (firstClass) {
8129                    mProviderMap.putProviderByClass(comp, cpr);
8130                }
8131
8132                mProviderMap.putProviderByName(name, cpr);
8133                conn = incProviderCountLocked(r, cpr, token, stable);
8134                if (conn != null) {
8135                    conn.waiting = true;
8136                }
8137            }
8138        }
8139
8140        // Wait for the provider to be published...
8141        synchronized (cpr) {
8142            while (cpr.provider == null) {
8143                if (cpr.launchingApp == null) {
8144                    Slog.w(TAG, "Unable to launch app "
8145                            + cpi.applicationInfo.packageName + "/"
8146                            + cpi.applicationInfo.uid + " for provider "
8147                            + name + ": launching app became null");
8148                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8149                            UserHandle.getUserId(cpi.applicationInfo.uid),
8150                            cpi.applicationInfo.packageName,
8151                            cpi.applicationInfo.uid, name);
8152                    return null;
8153                }
8154                try {
8155                    if (DEBUG_MU) {
8156                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8157                                + cpr.launchingApp);
8158                    }
8159                    if (conn != null) {
8160                        conn.waiting = true;
8161                    }
8162                    cpr.wait();
8163                } catch (InterruptedException ex) {
8164                } finally {
8165                    if (conn != null) {
8166                        conn.waiting = false;
8167                    }
8168                }
8169            }
8170        }
8171        return cpr != null ? cpr.newHolder(conn) : null;
8172    }
8173
8174    public final ContentProviderHolder getContentProvider(
8175            IApplicationThread caller, String name, int userId, boolean stable) {
8176        enforceNotIsolatedCaller("getContentProvider");
8177        if (caller == null) {
8178            String msg = "null IApplicationThread when getting content provider "
8179                    + name;
8180            Slog.w(TAG, msg);
8181            throw new SecurityException(msg);
8182        }
8183
8184        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8185                false, true, "getContentProvider", null);
8186        return getContentProviderImpl(caller, name, null, stable, userId);
8187    }
8188
8189    public ContentProviderHolder getContentProviderExternal(
8190            String name, int userId, IBinder token) {
8191        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8192            "Do not have permission in call getContentProviderExternal()");
8193        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8194                false, true, "getContentProvider", null);
8195        return getContentProviderExternalUnchecked(name, token, userId);
8196    }
8197
8198    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8199            IBinder token, int userId) {
8200        return getContentProviderImpl(null, name, token, true, userId);
8201    }
8202
8203    /**
8204     * Drop a content provider from a ProcessRecord's bookkeeping
8205     */
8206    public void removeContentProvider(IBinder connection, boolean stable) {
8207        enforceNotIsolatedCaller("removeContentProvider");
8208        long ident = Binder.clearCallingIdentity();
8209        try {
8210            synchronized (this) {
8211                ContentProviderConnection conn;
8212                try {
8213                    conn = (ContentProviderConnection)connection;
8214                } catch (ClassCastException e) {
8215                    String msg ="removeContentProvider: " + connection
8216                            + " not a ContentProviderConnection";
8217                    Slog.w(TAG, msg);
8218                    throw new IllegalArgumentException(msg);
8219                }
8220                if (conn == null) {
8221                    throw new NullPointerException("connection is null");
8222                }
8223                if (decProviderCountLocked(conn, null, null, stable)) {
8224                    updateOomAdjLocked();
8225                }
8226            }
8227        } finally {
8228            Binder.restoreCallingIdentity(ident);
8229        }
8230    }
8231
8232    public void removeContentProviderExternal(String name, IBinder token) {
8233        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8234            "Do not have permission in call removeContentProviderExternal()");
8235        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8236    }
8237
8238    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8239        synchronized (this) {
8240            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8241            if(cpr == null) {
8242                //remove from mProvidersByClass
8243                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8244                return;
8245            }
8246
8247            //update content provider record entry info
8248            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8249            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8250            if (localCpr.hasExternalProcessHandles()) {
8251                if (localCpr.removeExternalProcessHandleLocked(token)) {
8252                    updateOomAdjLocked();
8253                } else {
8254                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8255                            + " with no external reference for token: "
8256                            + token + ".");
8257                }
8258            } else {
8259                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8260                        + " with no external references.");
8261            }
8262        }
8263    }
8264
8265    public final void publishContentProviders(IApplicationThread caller,
8266            List<ContentProviderHolder> providers) {
8267        if (providers == null) {
8268            return;
8269        }
8270
8271        enforceNotIsolatedCaller("publishContentProviders");
8272        synchronized (this) {
8273            final ProcessRecord r = getRecordForAppLocked(caller);
8274            if (DEBUG_MU)
8275                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8276            if (r == null) {
8277                throw new SecurityException(
8278                        "Unable to find app for caller " + caller
8279                      + " (pid=" + Binder.getCallingPid()
8280                      + ") when publishing content providers");
8281            }
8282
8283            final long origId = Binder.clearCallingIdentity();
8284
8285            final int N = providers.size();
8286            for (int i=0; i<N; i++) {
8287                ContentProviderHolder src = providers.get(i);
8288                if (src == null || src.info == null || src.provider == null) {
8289                    continue;
8290                }
8291                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8292                if (DEBUG_MU)
8293                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8294                if (dst != null) {
8295                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8296                    mProviderMap.putProviderByClass(comp, dst);
8297                    String names[] = dst.info.authority.split(";");
8298                    for (int j = 0; j < names.length; j++) {
8299                        mProviderMap.putProviderByName(names[j], dst);
8300                    }
8301
8302                    int NL = mLaunchingProviders.size();
8303                    int j;
8304                    for (j=0; j<NL; j++) {
8305                        if (mLaunchingProviders.get(j) == dst) {
8306                            mLaunchingProviders.remove(j);
8307                            j--;
8308                            NL--;
8309                        }
8310                    }
8311                    synchronized (dst) {
8312                        dst.provider = src.provider;
8313                        dst.proc = r;
8314                        dst.notifyAll();
8315                    }
8316                    updateOomAdjLocked(r);
8317                }
8318            }
8319
8320            Binder.restoreCallingIdentity(origId);
8321        }
8322    }
8323
8324    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8325        ContentProviderConnection conn;
8326        try {
8327            conn = (ContentProviderConnection)connection;
8328        } catch (ClassCastException e) {
8329            String msg ="refContentProvider: " + connection
8330                    + " not a ContentProviderConnection";
8331            Slog.w(TAG, msg);
8332            throw new IllegalArgumentException(msg);
8333        }
8334        if (conn == null) {
8335            throw new NullPointerException("connection is null");
8336        }
8337
8338        synchronized (this) {
8339            if (stable > 0) {
8340                conn.numStableIncs += stable;
8341            }
8342            stable = conn.stableCount + stable;
8343            if (stable < 0) {
8344                throw new IllegalStateException("stableCount < 0: " + stable);
8345            }
8346
8347            if (unstable > 0) {
8348                conn.numUnstableIncs += unstable;
8349            }
8350            unstable = conn.unstableCount + unstable;
8351            if (unstable < 0) {
8352                throw new IllegalStateException("unstableCount < 0: " + unstable);
8353            }
8354
8355            if ((stable+unstable) <= 0) {
8356                throw new IllegalStateException("ref counts can't go to zero here: stable="
8357                        + stable + " unstable=" + unstable);
8358            }
8359            conn.stableCount = stable;
8360            conn.unstableCount = unstable;
8361            return !conn.dead;
8362        }
8363    }
8364
8365    public void unstableProviderDied(IBinder connection) {
8366        ContentProviderConnection conn;
8367        try {
8368            conn = (ContentProviderConnection)connection;
8369        } catch (ClassCastException e) {
8370            String msg ="refContentProvider: " + connection
8371                    + " not a ContentProviderConnection";
8372            Slog.w(TAG, msg);
8373            throw new IllegalArgumentException(msg);
8374        }
8375        if (conn == null) {
8376            throw new NullPointerException("connection is null");
8377        }
8378
8379        // Safely retrieve the content provider associated with the connection.
8380        IContentProvider provider;
8381        synchronized (this) {
8382            provider = conn.provider.provider;
8383        }
8384
8385        if (provider == null) {
8386            // Um, yeah, we're way ahead of you.
8387            return;
8388        }
8389
8390        // Make sure the caller is being honest with us.
8391        if (provider.asBinder().pingBinder()) {
8392            // Er, no, still looks good to us.
8393            synchronized (this) {
8394                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8395                        + " says " + conn + " died, but we don't agree");
8396                return;
8397            }
8398        }
8399
8400        // Well look at that!  It's dead!
8401        synchronized (this) {
8402            if (conn.provider.provider != provider) {
8403                // But something changed...  good enough.
8404                return;
8405            }
8406
8407            ProcessRecord proc = conn.provider.proc;
8408            if (proc == null || proc.thread == null) {
8409                // Seems like the process is already cleaned up.
8410                return;
8411            }
8412
8413            // As far as we're concerned, this is just like receiving a
8414            // death notification...  just a bit prematurely.
8415            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8416                    + ") early provider death");
8417            final long ident = Binder.clearCallingIdentity();
8418            try {
8419                appDiedLocked(proc, proc.pid, proc.thread);
8420            } finally {
8421                Binder.restoreCallingIdentity(ident);
8422            }
8423        }
8424    }
8425
8426    @Override
8427    public void appNotRespondingViaProvider(IBinder connection) {
8428        enforceCallingPermission(
8429                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8430
8431        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8432        if (conn == null) {
8433            Slog.w(TAG, "ContentProviderConnection is null");
8434            return;
8435        }
8436
8437        final ProcessRecord host = conn.provider.proc;
8438        if (host == null) {
8439            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8440            return;
8441        }
8442
8443        final long token = Binder.clearCallingIdentity();
8444        try {
8445            appNotResponding(host, null, null, false, "ContentProvider not responding");
8446        } finally {
8447            Binder.restoreCallingIdentity(token);
8448        }
8449    }
8450
8451    public final void installSystemProviders() {
8452        List<ProviderInfo> providers;
8453        synchronized (this) {
8454            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8455            providers = generateApplicationProvidersLocked(app);
8456            if (providers != null) {
8457                for (int i=providers.size()-1; i>=0; i--) {
8458                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8459                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8460                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8461                                + ": not system .apk");
8462                        providers.remove(i);
8463                    }
8464                }
8465            }
8466        }
8467        if (providers != null) {
8468            mSystemThread.installSystemProviders(providers);
8469        }
8470
8471        mCoreSettingsObserver = new CoreSettingsObserver(this);
8472
8473        mUsageStatsService.monitorPackages();
8474    }
8475
8476    /**
8477     * Allows app to retrieve the MIME type of a URI without having permission
8478     * to access its content provider.
8479     *
8480     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8481     *
8482     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8483     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8484     */
8485    public String getProviderMimeType(Uri uri, int userId) {
8486        enforceNotIsolatedCaller("getProviderMimeType");
8487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8488                userId, false, true, "getProviderMimeType", null);
8489        final String name = uri.getAuthority();
8490        final long ident = Binder.clearCallingIdentity();
8491        ContentProviderHolder holder = null;
8492
8493        try {
8494            holder = getContentProviderExternalUnchecked(name, null, userId);
8495            if (holder != null) {
8496                return holder.provider.getType(uri);
8497            }
8498        } catch (RemoteException e) {
8499            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8500            return null;
8501        } finally {
8502            if (holder != null) {
8503                removeContentProviderExternalUnchecked(name, null, userId);
8504            }
8505            Binder.restoreCallingIdentity(ident);
8506        }
8507
8508        return null;
8509    }
8510
8511    // =========================================================
8512    // GLOBAL MANAGEMENT
8513    // =========================================================
8514
8515    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8516            boolean isolated) {
8517        String proc = customProcess != null ? customProcess : info.processName;
8518        BatteryStatsImpl.Uid.Proc ps = null;
8519        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8520        int uid = info.uid;
8521        if (isolated) {
8522            int userId = UserHandle.getUserId(uid);
8523            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8524            while (true) {
8525                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8526                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8527                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8528                }
8529                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8530                mNextIsolatedProcessUid++;
8531                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8532                    // No process for this uid, use it.
8533                    break;
8534                }
8535                stepsLeft--;
8536                if (stepsLeft <= 0) {
8537                    return null;
8538                }
8539            }
8540        }
8541        return new ProcessRecord(stats, info, proc, uid);
8542    }
8543
8544    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8545        ProcessRecord app;
8546        if (!isolated) {
8547            app = getProcessRecordLocked(info.processName, info.uid, true);
8548        } else {
8549            app = null;
8550        }
8551
8552        if (app == null) {
8553            app = newProcessRecordLocked(info, null, isolated);
8554            mProcessNames.put(info.processName, app.uid, app);
8555            if (isolated) {
8556                mIsolatedProcesses.put(app.uid, app);
8557            }
8558            updateLruProcessLocked(app, false, null);
8559            updateOomAdjLocked();
8560        }
8561
8562        // This package really, really can not be stopped.
8563        try {
8564            AppGlobals.getPackageManager().setPackageStoppedState(
8565                    info.packageName, false, UserHandle.getUserId(app.uid));
8566        } catch (RemoteException e) {
8567        } catch (IllegalArgumentException e) {
8568            Slog.w(TAG, "Failed trying to unstop package "
8569                    + info.packageName + ": " + e);
8570        }
8571
8572        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8573                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8574            app.persistent = true;
8575            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8576        }
8577        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8578            mPersistentStartingProcesses.add(app);
8579            startProcessLocked(app, "added application", app.processName);
8580        }
8581
8582        return app;
8583    }
8584
8585    public void unhandledBack() {
8586        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8587                "unhandledBack()");
8588
8589        synchronized(this) {
8590            final long origId = Binder.clearCallingIdentity();
8591            try {
8592                getFocusedStack().unhandledBackLocked();
8593            } finally {
8594                Binder.restoreCallingIdentity(origId);
8595            }
8596        }
8597    }
8598
8599    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8600        enforceNotIsolatedCaller("openContentUri");
8601        final int userId = UserHandle.getCallingUserId();
8602        String name = uri.getAuthority();
8603        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8604        ParcelFileDescriptor pfd = null;
8605        if (cph != null) {
8606            // We record the binder invoker's uid in thread-local storage before
8607            // going to the content provider to open the file.  Later, in the code
8608            // that handles all permissions checks, we look for this uid and use
8609            // that rather than the Activity Manager's own uid.  The effect is that
8610            // we do the check against the caller's permissions even though it looks
8611            // to the content provider like the Activity Manager itself is making
8612            // the request.
8613            sCallerIdentity.set(new Identity(
8614                    Binder.getCallingPid(), Binder.getCallingUid()));
8615            try {
8616                pfd = cph.provider.openFile(null, uri, "r", null);
8617            } catch (FileNotFoundException e) {
8618                // do nothing; pfd will be returned null
8619            } finally {
8620                // Ensure that whatever happens, we clean up the identity state
8621                sCallerIdentity.remove();
8622            }
8623
8624            // We've got the fd now, so we're done with the provider.
8625            removeContentProviderExternalUnchecked(name, null, userId);
8626        } else {
8627            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8628        }
8629        return pfd;
8630    }
8631
8632    // Actually is sleeping or shutting down or whatever else in the future
8633    // is an inactive state.
8634    public boolean isSleepingOrShuttingDown() {
8635        return mSleeping || mShuttingDown;
8636    }
8637
8638    public boolean isSleeping() {
8639        return mSleeping;
8640    }
8641
8642    void goingToSleep() {
8643        synchronized(this) {
8644            mWentToSleep = true;
8645            updateEventDispatchingLocked();
8646            goToSleepIfNeededLocked();
8647        }
8648    }
8649
8650    void finishRunningVoiceLocked() {
8651        if (mRunningVoice) {
8652            mRunningVoice = false;
8653            goToSleepIfNeededLocked();
8654        }
8655    }
8656
8657    void goToSleepIfNeededLocked() {
8658        if (mWentToSleep && !mRunningVoice) {
8659            if (!mSleeping) {
8660                mSleeping = true;
8661                mStackSupervisor.goingToSleepLocked();
8662
8663                // Initialize the wake times of all processes.
8664                checkExcessivePowerUsageLocked(false);
8665                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8666                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8667                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8668            }
8669        }
8670    }
8671
8672    @Override
8673    public boolean shutdown(int timeout) {
8674        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8675                != PackageManager.PERMISSION_GRANTED) {
8676            throw new SecurityException("Requires permission "
8677                    + android.Manifest.permission.SHUTDOWN);
8678        }
8679
8680        boolean timedout = false;
8681
8682        synchronized(this) {
8683            mShuttingDown = true;
8684            updateEventDispatchingLocked();
8685            timedout = mStackSupervisor.shutdownLocked(timeout);
8686        }
8687
8688        mAppOpsService.shutdown();
8689        mUsageStatsService.shutdown();
8690        mBatteryStatsService.shutdown();
8691        synchronized (this) {
8692            mProcessStats.shutdownLocked();
8693        }
8694
8695        return timedout;
8696    }
8697
8698    public final void activitySlept(IBinder token) {
8699        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8700
8701        final long origId = Binder.clearCallingIdentity();
8702
8703        synchronized (this) {
8704            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8705            if (r != null) {
8706                mStackSupervisor.activitySleptLocked(r);
8707            }
8708        }
8709
8710        Binder.restoreCallingIdentity(origId);
8711    }
8712
8713    void logLockScreen(String msg) {
8714        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8715                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8716                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8717                mStackSupervisor.mDismissKeyguardOnNextActivity);
8718    }
8719
8720    private void comeOutOfSleepIfNeededLocked() {
8721        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8722            if (mSleeping) {
8723                mSleeping = false;
8724                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8725            }
8726        }
8727    }
8728
8729    void wakingUp() {
8730        synchronized(this) {
8731            mWentToSleep = false;
8732            updateEventDispatchingLocked();
8733            comeOutOfSleepIfNeededLocked();
8734        }
8735    }
8736
8737    void startRunningVoiceLocked() {
8738        if (!mRunningVoice) {
8739            mRunningVoice = true;
8740            comeOutOfSleepIfNeededLocked();
8741        }
8742    }
8743
8744    private void updateEventDispatchingLocked() {
8745        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8746    }
8747
8748    public void setLockScreenShown(boolean shown) {
8749        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8750                != PackageManager.PERMISSION_GRANTED) {
8751            throw new SecurityException("Requires permission "
8752                    + android.Manifest.permission.DEVICE_POWER);
8753        }
8754
8755        synchronized(this) {
8756            long ident = Binder.clearCallingIdentity();
8757            try {
8758                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8759                mLockScreenShown = shown;
8760                comeOutOfSleepIfNeededLocked();
8761            } finally {
8762                Binder.restoreCallingIdentity(ident);
8763            }
8764        }
8765    }
8766
8767    public void stopAppSwitches() {
8768        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8769                != PackageManager.PERMISSION_GRANTED) {
8770            throw new SecurityException("Requires permission "
8771                    + android.Manifest.permission.STOP_APP_SWITCHES);
8772        }
8773
8774        synchronized(this) {
8775            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8776                    + APP_SWITCH_DELAY_TIME;
8777            mDidAppSwitch = false;
8778            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8779            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8780            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8781        }
8782    }
8783
8784    public void resumeAppSwitches() {
8785        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8786                != PackageManager.PERMISSION_GRANTED) {
8787            throw new SecurityException("Requires permission "
8788                    + android.Manifest.permission.STOP_APP_SWITCHES);
8789        }
8790
8791        synchronized(this) {
8792            // Note that we don't execute any pending app switches... we will
8793            // let those wait until either the timeout, or the next start
8794            // activity request.
8795            mAppSwitchesAllowedTime = 0;
8796        }
8797    }
8798
8799    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8800            String name) {
8801        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8802            return true;
8803        }
8804
8805        final int perm = checkComponentPermission(
8806                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8807                callingUid, -1, true);
8808        if (perm == PackageManager.PERMISSION_GRANTED) {
8809            return true;
8810        }
8811
8812        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8813        return false;
8814    }
8815
8816    public void setDebugApp(String packageName, boolean waitForDebugger,
8817            boolean persistent) {
8818        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8819                "setDebugApp()");
8820
8821        long ident = Binder.clearCallingIdentity();
8822        try {
8823            // Note that this is not really thread safe if there are multiple
8824            // callers into it at the same time, but that's not a situation we
8825            // care about.
8826            if (persistent) {
8827                final ContentResolver resolver = mContext.getContentResolver();
8828                Settings.Global.putString(
8829                    resolver, Settings.Global.DEBUG_APP,
8830                    packageName);
8831                Settings.Global.putInt(
8832                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8833                    waitForDebugger ? 1 : 0);
8834            }
8835
8836            synchronized (this) {
8837                if (!persistent) {
8838                    mOrigDebugApp = mDebugApp;
8839                    mOrigWaitForDebugger = mWaitForDebugger;
8840                }
8841                mDebugApp = packageName;
8842                mWaitForDebugger = waitForDebugger;
8843                mDebugTransient = !persistent;
8844                if (packageName != null) {
8845                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8846                            false, UserHandle.USER_ALL, "set debug app");
8847                }
8848            }
8849        } finally {
8850            Binder.restoreCallingIdentity(ident);
8851        }
8852    }
8853
8854    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8855        synchronized (this) {
8856            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8857            if (!isDebuggable) {
8858                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8859                    throw new SecurityException("Process not debuggable: " + app.packageName);
8860                }
8861            }
8862
8863            mOpenGlTraceApp = processName;
8864        }
8865    }
8866
8867    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8868            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8869        synchronized (this) {
8870            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8871            if (!isDebuggable) {
8872                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8873                    throw new SecurityException("Process not debuggable: " + app.packageName);
8874                }
8875            }
8876            mProfileApp = processName;
8877            mProfileFile = profileFile;
8878            if (mProfileFd != null) {
8879                try {
8880                    mProfileFd.close();
8881                } catch (IOException e) {
8882                }
8883                mProfileFd = null;
8884            }
8885            mProfileFd = profileFd;
8886            mProfileType = 0;
8887            mAutoStopProfiler = autoStopProfiler;
8888        }
8889    }
8890
8891    @Override
8892    public void setAlwaysFinish(boolean enabled) {
8893        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8894                "setAlwaysFinish()");
8895
8896        Settings.Global.putInt(
8897                mContext.getContentResolver(),
8898                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8899
8900        synchronized (this) {
8901            mAlwaysFinishActivities = enabled;
8902        }
8903    }
8904
8905    @Override
8906    public void setActivityController(IActivityController controller) {
8907        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8908                "setActivityController()");
8909        synchronized (this) {
8910            mController = controller;
8911            Watchdog.getInstance().setActivityController(controller);
8912        }
8913    }
8914
8915    @Override
8916    public void setUserIsMonkey(boolean userIsMonkey) {
8917        synchronized (this) {
8918            synchronized (mPidsSelfLocked) {
8919                final int callingPid = Binder.getCallingPid();
8920                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8921                if (precessRecord == null) {
8922                    throw new SecurityException("Unknown process: " + callingPid);
8923                }
8924                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8925                    throw new SecurityException("Only an instrumentation process "
8926                            + "with a UiAutomation can call setUserIsMonkey");
8927                }
8928            }
8929            mUserIsMonkey = userIsMonkey;
8930        }
8931    }
8932
8933    @Override
8934    public boolean isUserAMonkey() {
8935        synchronized (this) {
8936            // If there is a controller also implies the user is a monkey.
8937            return (mUserIsMonkey || mController != null);
8938        }
8939    }
8940
8941    public void requestBugReport() {
8942        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8943        SystemProperties.set("ctl.start", "bugreport");
8944    }
8945
8946    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8947        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8948    }
8949
8950    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8951        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8952            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8953        }
8954        return KEY_DISPATCHING_TIMEOUT;
8955    }
8956
8957    @Override
8958    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8959        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8960                != PackageManager.PERMISSION_GRANTED) {
8961            throw new SecurityException("Requires permission "
8962                    + android.Manifest.permission.FILTER_EVENTS);
8963        }
8964        ProcessRecord proc;
8965        long timeout;
8966        synchronized (this) {
8967            synchronized (mPidsSelfLocked) {
8968                proc = mPidsSelfLocked.get(pid);
8969            }
8970            timeout = getInputDispatchingTimeoutLocked(proc);
8971        }
8972
8973        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8974            return -1;
8975        }
8976
8977        return timeout;
8978    }
8979
8980    /**
8981     * Handle input dispatching timeouts.
8982     * Returns whether input dispatching should be aborted or not.
8983     */
8984    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8985            final ActivityRecord activity, final ActivityRecord parent,
8986            final boolean aboveSystem, String reason) {
8987        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8988                != PackageManager.PERMISSION_GRANTED) {
8989            throw new SecurityException("Requires permission "
8990                    + android.Manifest.permission.FILTER_EVENTS);
8991        }
8992
8993        final String annotation;
8994        if (reason == null) {
8995            annotation = "Input dispatching timed out";
8996        } else {
8997            annotation = "Input dispatching timed out (" + reason + ")";
8998        }
8999
9000        if (proc != null) {
9001            synchronized (this) {
9002                if (proc.debugging) {
9003                    return false;
9004                }
9005
9006                if (mDidDexOpt) {
9007                    // Give more time since we were dexopting.
9008                    mDidDexOpt = false;
9009                    return false;
9010                }
9011
9012                if (proc.instrumentationClass != null) {
9013                    Bundle info = new Bundle();
9014                    info.putString("shortMsg", "keyDispatchingTimedOut");
9015                    info.putString("longMsg", annotation);
9016                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9017                    return true;
9018                }
9019            }
9020            mHandler.post(new Runnable() {
9021                @Override
9022                public void run() {
9023                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9024                }
9025            });
9026        }
9027
9028        return true;
9029    }
9030
9031    public Bundle getAssistContextExtras(int requestType) {
9032        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9033                "getAssistContextExtras()");
9034        PendingAssistExtras pae;
9035        Bundle extras = new Bundle();
9036        synchronized (this) {
9037            ActivityRecord activity = getFocusedStack().mResumedActivity;
9038            if (activity == null) {
9039                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9040                return null;
9041            }
9042            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9043            if (activity.app == null || activity.app.thread == null) {
9044                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9045                return extras;
9046            }
9047            if (activity.app.pid == Binder.getCallingPid()) {
9048                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9049                return extras;
9050            }
9051            pae = new PendingAssistExtras(activity);
9052            try {
9053                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9054                        requestType);
9055                mPendingAssistExtras.add(pae);
9056                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9057            } catch (RemoteException e) {
9058                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9059                return extras;
9060            }
9061        }
9062        synchronized (pae) {
9063            while (!pae.haveResult) {
9064                try {
9065                    pae.wait();
9066                } catch (InterruptedException e) {
9067                }
9068            }
9069            if (pae.result != null) {
9070                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9071            }
9072        }
9073        synchronized (this) {
9074            mPendingAssistExtras.remove(pae);
9075            mHandler.removeCallbacks(pae);
9076        }
9077        return extras;
9078    }
9079
9080    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9081        PendingAssistExtras pae = (PendingAssistExtras)token;
9082        synchronized (pae) {
9083            pae.result = extras;
9084            pae.haveResult = true;
9085            pae.notifyAll();
9086        }
9087    }
9088
9089    public void registerProcessObserver(IProcessObserver observer) {
9090        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9091                "registerProcessObserver()");
9092        synchronized (this) {
9093            mProcessObservers.register(observer);
9094        }
9095    }
9096
9097    @Override
9098    public void unregisterProcessObserver(IProcessObserver observer) {
9099        synchronized (this) {
9100            mProcessObservers.unregister(observer);
9101        }
9102    }
9103
9104    @Override
9105    public boolean convertFromTranslucent(IBinder token) {
9106        final long origId = Binder.clearCallingIdentity();
9107        try {
9108            synchronized (this) {
9109                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9110                if (r == null) {
9111                    return false;
9112                }
9113                if (r.changeWindowTranslucency(true)) {
9114                    mWindowManager.setAppFullscreen(token, true);
9115                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9116                    return true;
9117                }
9118                return false;
9119            }
9120        } finally {
9121            Binder.restoreCallingIdentity(origId);
9122        }
9123    }
9124
9125    @Override
9126    public boolean convertToTranslucent(IBinder token) {
9127        final long origId = Binder.clearCallingIdentity();
9128        try {
9129            synchronized (this) {
9130                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9131                if (r == null) {
9132                    return false;
9133                }
9134                if (r.changeWindowTranslucency(false)) {
9135                    r.task.stack.convertToTranslucent(r);
9136                    mWindowManager.setAppFullscreen(token, false);
9137                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9138                    return true;
9139                }
9140                return false;
9141            }
9142        } finally {
9143            Binder.restoreCallingIdentity(origId);
9144        }
9145    }
9146
9147    @Override
9148    public void setImmersive(IBinder token, boolean immersive) {
9149        synchronized(this) {
9150            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9151            if (r == null) {
9152                throw new IllegalArgumentException();
9153            }
9154            r.immersive = immersive;
9155
9156            // update associated state if we're frontmost
9157            if (r == mFocusedActivity) {
9158                if (DEBUG_IMMERSIVE) {
9159                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9160                }
9161                applyUpdateLockStateLocked(r);
9162            }
9163        }
9164    }
9165
9166    @Override
9167    public boolean isImmersive(IBinder token) {
9168        synchronized (this) {
9169            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9170            if (r == null) {
9171                throw new IllegalArgumentException();
9172            }
9173            return r.immersive;
9174        }
9175    }
9176
9177    public boolean isTopActivityImmersive() {
9178        enforceNotIsolatedCaller("startActivity");
9179        synchronized (this) {
9180            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9181            return (r != null) ? r.immersive : false;
9182        }
9183    }
9184
9185    public final void enterSafeMode() {
9186        synchronized(this) {
9187            // It only makes sense to do this before the system is ready
9188            // and started launching other packages.
9189            if (!mSystemReady) {
9190                try {
9191                    AppGlobals.getPackageManager().enterSafeMode();
9192                } catch (RemoteException e) {
9193                }
9194            }
9195
9196            mSafeMode = true;
9197        }
9198    }
9199
9200    public final void showSafeModeOverlay() {
9201        View v = LayoutInflater.from(mContext).inflate(
9202                com.android.internal.R.layout.safe_mode, null);
9203        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9204        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9205        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9206        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9207        lp.gravity = Gravity.BOTTOM | Gravity.START;
9208        lp.format = v.getBackground().getOpacity();
9209        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9210                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9211        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9212        ((WindowManager)mContext.getSystemService(
9213                Context.WINDOW_SERVICE)).addView(v, lp);
9214    }
9215
9216    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9217        if (!(sender instanceof PendingIntentRecord)) {
9218            return;
9219        }
9220        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9221        synchronized (stats) {
9222            if (mBatteryStatsService.isOnBattery()) {
9223                mBatteryStatsService.enforceCallingPermission();
9224                PendingIntentRecord rec = (PendingIntentRecord)sender;
9225                int MY_UID = Binder.getCallingUid();
9226                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9227                BatteryStatsImpl.Uid.Pkg pkg =
9228                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9229                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9230                pkg.incWakeupsLocked();
9231            }
9232        }
9233    }
9234
9235    public boolean killPids(int[] pids, String pReason, boolean secure) {
9236        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9237            throw new SecurityException("killPids only available to the system");
9238        }
9239        String reason = (pReason == null) ? "Unknown" : pReason;
9240        // XXX Note: don't acquire main activity lock here, because the window
9241        // manager calls in with its locks held.
9242
9243        boolean killed = false;
9244        synchronized (mPidsSelfLocked) {
9245            int[] types = new int[pids.length];
9246            int worstType = 0;
9247            for (int i=0; i<pids.length; i++) {
9248                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9249                if (proc != null) {
9250                    int type = proc.setAdj;
9251                    types[i] = type;
9252                    if (type > worstType) {
9253                        worstType = type;
9254                    }
9255                }
9256            }
9257
9258            // If the worst oom_adj is somewhere in the cached proc LRU range,
9259            // then constrain it so we will kill all cached procs.
9260            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9261                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9262                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9263            }
9264
9265            // If this is not a secure call, don't let it kill processes that
9266            // are important.
9267            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9268                worstType = ProcessList.SERVICE_ADJ;
9269            }
9270
9271            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9272            for (int i=0; i<pids.length; i++) {
9273                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9274                if (proc == null) {
9275                    continue;
9276                }
9277                int adj = proc.setAdj;
9278                if (adj >= worstType && !proc.killedByAm) {
9279                    killUnneededProcessLocked(proc, reason);
9280                    killed = true;
9281                }
9282            }
9283        }
9284        return killed;
9285    }
9286
9287    @Override
9288    public void killUid(int uid, String reason) {
9289        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9290            throw new SecurityException("killUid only available to the system");
9291        }
9292        synchronized (this) {
9293            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9294                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9295                    reason != null ? reason : "kill uid");
9296        }
9297    }
9298
9299    @Override
9300    public boolean killProcessesBelowForeground(String reason) {
9301        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9302            throw new SecurityException("killProcessesBelowForeground() only available to system");
9303        }
9304
9305        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9306    }
9307
9308    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9309        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9310            throw new SecurityException("killProcessesBelowAdj() only available to system");
9311        }
9312
9313        boolean killed = false;
9314        synchronized (mPidsSelfLocked) {
9315            final int size = mPidsSelfLocked.size();
9316            for (int i = 0; i < size; i++) {
9317                final int pid = mPidsSelfLocked.keyAt(i);
9318                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9319                if (proc == null) continue;
9320
9321                final int adj = proc.setAdj;
9322                if (adj > belowAdj && !proc.killedByAm) {
9323                    killUnneededProcessLocked(proc, reason);
9324                    killed = true;
9325                }
9326            }
9327        }
9328        return killed;
9329    }
9330
9331    @Override
9332    public void hang(final IBinder who, boolean allowRestart) {
9333        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9334                != PackageManager.PERMISSION_GRANTED) {
9335            throw new SecurityException("Requires permission "
9336                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9337        }
9338
9339        final IBinder.DeathRecipient death = new DeathRecipient() {
9340            @Override
9341            public void binderDied() {
9342                synchronized (this) {
9343                    notifyAll();
9344                }
9345            }
9346        };
9347
9348        try {
9349            who.linkToDeath(death, 0);
9350        } catch (RemoteException e) {
9351            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9352            return;
9353        }
9354
9355        synchronized (this) {
9356            Watchdog.getInstance().setAllowRestart(allowRestart);
9357            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9358            synchronized (death) {
9359                while (who.isBinderAlive()) {
9360                    try {
9361                        death.wait();
9362                    } catch (InterruptedException e) {
9363                    }
9364                }
9365            }
9366            Watchdog.getInstance().setAllowRestart(true);
9367        }
9368    }
9369
9370    @Override
9371    public void restart() {
9372        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9373                != PackageManager.PERMISSION_GRANTED) {
9374            throw new SecurityException("Requires permission "
9375                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9376        }
9377
9378        Log.i(TAG, "Sending shutdown broadcast...");
9379
9380        BroadcastReceiver br = new BroadcastReceiver() {
9381            @Override public void onReceive(Context context, Intent intent) {
9382                // Now the broadcast is done, finish up the low-level shutdown.
9383                Log.i(TAG, "Shutting down activity manager...");
9384                shutdown(10000);
9385                Log.i(TAG, "Shutdown complete, restarting!");
9386                Process.killProcess(Process.myPid());
9387                System.exit(10);
9388            }
9389        };
9390
9391        // First send the high-level shut down broadcast.
9392        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9393        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9394        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9395        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9396        mContext.sendOrderedBroadcastAsUser(intent,
9397                UserHandle.ALL, null, br, mHandler, 0, null, null);
9398        */
9399        br.onReceive(mContext, intent);
9400    }
9401
9402    private long getLowRamTimeSinceIdle(long now) {
9403        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9404    }
9405
9406    @Override
9407    public void performIdleMaintenance() {
9408        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9409                != PackageManager.PERMISSION_GRANTED) {
9410            throw new SecurityException("Requires permission "
9411                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9412        }
9413
9414        synchronized (this) {
9415            final long now = SystemClock.uptimeMillis();
9416            final long timeSinceLastIdle = now - mLastIdleTime;
9417            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9418            mLastIdleTime = now;
9419            mLowRamTimeSinceLastIdle = 0;
9420            if (mLowRamStartTime != 0) {
9421                mLowRamStartTime = now;
9422            }
9423
9424            StringBuilder sb = new StringBuilder(128);
9425            sb.append("Idle maintenance over ");
9426            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9427            sb.append(" low RAM for ");
9428            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9429            Slog.i(TAG, sb.toString());
9430
9431            // If at least 1/3 of our time since the last idle period has been spent
9432            // with RAM low, then we want to kill processes.
9433            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9434
9435            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9436                ProcessRecord proc = mLruProcesses.get(i);
9437                if (proc.notCachedSinceIdle) {
9438                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9439                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9440                        if (doKilling && proc.initialIdlePss != 0
9441                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9442                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9443                                    + " from " + proc.initialIdlePss + ")");
9444                        }
9445                    }
9446                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9447                    proc.notCachedSinceIdle = true;
9448                    proc.initialIdlePss = 0;
9449                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9450                            isSleeping(), now);
9451                }
9452            }
9453
9454            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9455            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9456        }
9457    }
9458
9459    private void retrieveSettings() {
9460        final ContentResolver resolver = mContext.getContentResolver();
9461        String debugApp = Settings.Global.getString(
9462            resolver, Settings.Global.DEBUG_APP);
9463        boolean waitForDebugger = Settings.Global.getInt(
9464            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9465        boolean alwaysFinishActivities = Settings.Global.getInt(
9466            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9467        boolean forceRtl = Settings.Global.getInt(
9468                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9469        // Transfer any global setting for forcing RTL layout, into a System Property
9470        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9471
9472        Configuration configuration = new Configuration();
9473        Settings.System.getConfiguration(resolver, configuration);
9474        if (forceRtl) {
9475            // This will take care of setting the correct layout direction flags
9476            configuration.setLayoutDirection(configuration.locale);
9477        }
9478
9479        synchronized (this) {
9480            mDebugApp = mOrigDebugApp = debugApp;
9481            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9482            mAlwaysFinishActivities = alwaysFinishActivities;
9483            // This happens before any activities are started, so we can
9484            // change mConfiguration in-place.
9485            updateConfigurationLocked(configuration, null, false, true);
9486            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9487        }
9488    }
9489
9490    public boolean testIsSystemReady() {
9491        // no need to synchronize(this) just to read & return the value
9492        return mSystemReady;
9493    }
9494
9495    private static File getCalledPreBootReceiversFile() {
9496        File dataDir = Environment.getDataDirectory();
9497        File systemDir = new File(dataDir, "system");
9498        File fname = new File(systemDir, "called_pre_boots.dat");
9499        return fname;
9500    }
9501
9502    static final int LAST_DONE_VERSION = 10000;
9503
9504    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9505        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9506        File file = getCalledPreBootReceiversFile();
9507        FileInputStream fis = null;
9508        try {
9509            fis = new FileInputStream(file);
9510            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9511            int fvers = dis.readInt();
9512            if (fvers == LAST_DONE_VERSION) {
9513                String vers = dis.readUTF();
9514                String codename = dis.readUTF();
9515                String build = dis.readUTF();
9516                if (android.os.Build.VERSION.RELEASE.equals(vers)
9517                        && android.os.Build.VERSION.CODENAME.equals(codename)
9518                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9519                    int num = dis.readInt();
9520                    while (num > 0) {
9521                        num--;
9522                        String pkg = dis.readUTF();
9523                        String cls = dis.readUTF();
9524                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9525                    }
9526                }
9527            }
9528        } catch (FileNotFoundException e) {
9529        } catch (IOException e) {
9530            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9531        } finally {
9532            if (fis != null) {
9533                try {
9534                    fis.close();
9535                } catch (IOException e) {
9536                }
9537            }
9538        }
9539        return lastDoneReceivers;
9540    }
9541
9542    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9543        File file = getCalledPreBootReceiversFile();
9544        FileOutputStream fos = null;
9545        DataOutputStream dos = null;
9546        try {
9547            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9548            fos = new FileOutputStream(file);
9549            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9550            dos.writeInt(LAST_DONE_VERSION);
9551            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9552            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9553            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9554            dos.writeInt(list.size());
9555            for (int i=0; i<list.size(); i++) {
9556                dos.writeUTF(list.get(i).getPackageName());
9557                dos.writeUTF(list.get(i).getClassName());
9558            }
9559        } catch (IOException e) {
9560            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9561            file.delete();
9562        } finally {
9563            FileUtils.sync(fos);
9564            if (dos != null) {
9565                try {
9566                    dos.close();
9567                } catch (IOException e) {
9568                    // TODO Auto-generated catch block
9569                    e.printStackTrace();
9570                }
9571            }
9572        }
9573    }
9574
9575    public void systemReady(final Runnable goingCallback) {
9576        synchronized(this) {
9577            if (mSystemReady) {
9578                if (goingCallback != null) goingCallback.run();
9579                return;
9580            }
9581
9582            // Check to see if there are any update receivers to run.
9583            if (!mDidUpdate) {
9584                if (mWaitingUpdate) {
9585                    return;
9586                }
9587                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9588                List<ResolveInfo> ris = null;
9589                try {
9590                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9591                            intent, null, 0, 0);
9592                } catch (RemoteException e) {
9593                }
9594                if (ris != null) {
9595                    for (int i=ris.size()-1; i>=0; i--) {
9596                        if ((ris.get(i).activityInfo.applicationInfo.flags
9597                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9598                            ris.remove(i);
9599                        }
9600                    }
9601                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9602
9603                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9604
9605                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9606                    for (int i=0; i<ris.size(); i++) {
9607                        ActivityInfo ai = ris.get(i).activityInfo;
9608                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9609                        if (lastDoneReceivers.contains(comp)) {
9610                            // We already did the pre boot receiver for this app with the current
9611                            // platform version, so don't do it again...
9612                            ris.remove(i);
9613                            i--;
9614                            // ...however, do keep it as one that has been done, so we don't
9615                            // forget about it when rewriting the file of last done receivers.
9616                            doneReceivers.add(comp);
9617                        }
9618                    }
9619
9620                    final int[] users = getUsersLocked();
9621                    for (int i=0; i<ris.size(); i++) {
9622                        ActivityInfo ai = ris.get(i).activityInfo;
9623                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9624                        doneReceivers.add(comp);
9625                        intent.setComponent(comp);
9626                        for (int j=0; j<users.length; j++) {
9627                            IIntentReceiver finisher = null;
9628                            if (i == ris.size()-1 && j == users.length-1) {
9629                                finisher = new IIntentReceiver.Stub() {
9630                                    public void performReceive(Intent intent, int resultCode,
9631                                            String data, Bundle extras, boolean ordered,
9632                                            boolean sticky, int sendingUser) {
9633                                        // The raw IIntentReceiver interface is called
9634                                        // with the AM lock held, so redispatch to
9635                                        // execute our code without the lock.
9636                                        mHandler.post(new Runnable() {
9637                                            public void run() {
9638                                                synchronized (ActivityManagerService.this) {
9639                                                    mDidUpdate = true;
9640                                                }
9641                                                writeLastDonePreBootReceivers(doneReceivers);
9642                                                showBootMessage(mContext.getText(
9643                                                        R.string.android_upgrading_complete),
9644                                                        false);
9645                                                systemReady(goingCallback);
9646                                            }
9647                                        });
9648                                    }
9649                                };
9650                            }
9651                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9652                                    + " for user " + users[j]);
9653                            broadcastIntentLocked(null, null, intent, null, finisher,
9654                                    0, null, null, null, AppOpsManager.OP_NONE,
9655                                    true, false, MY_PID, Process.SYSTEM_UID,
9656                                    users[j]);
9657                            if (finisher != null) {
9658                                mWaitingUpdate = true;
9659                            }
9660                        }
9661                    }
9662                }
9663                if (mWaitingUpdate) {
9664                    return;
9665                }
9666                mDidUpdate = true;
9667            }
9668
9669            mAppOpsService.systemReady();
9670            mSystemReady = true;
9671        }
9672
9673        ArrayList<ProcessRecord> procsToKill = null;
9674        synchronized(mPidsSelfLocked) {
9675            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9676                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9677                if (!isAllowedWhileBooting(proc.info)){
9678                    if (procsToKill == null) {
9679                        procsToKill = new ArrayList<ProcessRecord>();
9680                    }
9681                    procsToKill.add(proc);
9682                }
9683            }
9684        }
9685
9686        synchronized(this) {
9687            if (procsToKill != null) {
9688                for (int i=procsToKill.size()-1; i>=0; i--) {
9689                    ProcessRecord proc = procsToKill.get(i);
9690                    Slog.i(TAG, "Removing system update proc: " + proc);
9691                    removeProcessLocked(proc, true, false, "system update done");
9692                }
9693            }
9694
9695            // Now that we have cleaned up any update processes, we
9696            // are ready to start launching real processes and know that
9697            // we won't trample on them any more.
9698            mProcessesReady = true;
9699        }
9700
9701        Slog.i(TAG, "System now ready");
9702        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9703            SystemClock.uptimeMillis());
9704
9705        synchronized(this) {
9706            // Make sure we have no pre-ready processes sitting around.
9707
9708            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9709                ResolveInfo ri = mContext.getPackageManager()
9710                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9711                                STOCK_PM_FLAGS);
9712                CharSequence errorMsg = null;
9713                if (ri != null) {
9714                    ActivityInfo ai = ri.activityInfo;
9715                    ApplicationInfo app = ai.applicationInfo;
9716                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9717                        mTopAction = Intent.ACTION_FACTORY_TEST;
9718                        mTopData = null;
9719                        mTopComponent = new ComponentName(app.packageName,
9720                                ai.name);
9721                    } else {
9722                        errorMsg = mContext.getResources().getText(
9723                                com.android.internal.R.string.factorytest_not_system);
9724                    }
9725                } else {
9726                    errorMsg = mContext.getResources().getText(
9727                            com.android.internal.R.string.factorytest_no_action);
9728                }
9729                if (errorMsg != null) {
9730                    mTopAction = null;
9731                    mTopData = null;
9732                    mTopComponent = null;
9733                    Message msg = Message.obtain();
9734                    msg.what = SHOW_FACTORY_ERROR_MSG;
9735                    msg.getData().putCharSequence("msg", errorMsg);
9736                    mHandler.sendMessage(msg);
9737                }
9738            }
9739        }
9740
9741        retrieveSettings();
9742
9743        synchronized (this) {
9744            readGrantedUriPermissionsLocked();
9745        }
9746
9747        if (goingCallback != null) goingCallback.run();
9748
9749        mSystemServiceManager.startUser(mCurrentUserId);
9750
9751        synchronized (this) {
9752            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9753                try {
9754                    List apps = AppGlobals.getPackageManager().
9755                        getPersistentApplications(STOCK_PM_FLAGS);
9756                    if (apps != null) {
9757                        int N = apps.size();
9758                        int i;
9759                        for (i=0; i<N; i++) {
9760                            ApplicationInfo info
9761                                = (ApplicationInfo)apps.get(i);
9762                            if (info != null &&
9763                                    !info.packageName.equals("android")) {
9764                                addAppLocked(info, false);
9765                            }
9766                        }
9767                    }
9768                } catch (RemoteException ex) {
9769                    // pm is in same process, this will never happen.
9770                }
9771            }
9772
9773            // Start up initial activity.
9774            mBooting = true;
9775
9776            try {
9777                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9778                    Message msg = Message.obtain();
9779                    msg.what = SHOW_UID_ERROR_MSG;
9780                    mHandler.sendMessage(msg);
9781                }
9782            } catch (RemoteException e) {
9783            }
9784
9785            long ident = Binder.clearCallingIdentity();
9786            try {
9787                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9788                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9789                        | Intent.FLAG_RECEIVER_FOREGROUND);
9790                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9791                broadcastIntentLocked(null, null, intent,
9792                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9793                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9794                intent = new Intent(Intent.ACTION_USER_STARTING);
9795                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9796                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9797                broadcastIntentLocked(null, null, intent,
9798                        null, new IIntentReceiver.Stub() {
9799                            @Override
9800                            public void performReceive(Intent intent, int resultCode, String data,
9801                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9802                                    throws RemoteException {
9803                            }
9804                        }, 0, null, null,
9805                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9806                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9807            } catch (Throwable t) {
9808                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9809            } finally {
9810                Binder.restoreCallingIdentity(ident);
9811            }
9812            mStackSupervisor.resumeTopActivitiesLocked();
9813            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9814        }
9815    }
9816
9817    private boolean makeAppCrashingLocked(ProcessRecord app,
9818            String shortMsg, String longMsg, String stackTrace) {
9819        app.crashing = true;
9820        app.crashingReport = generateProcessError(app,
9821                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9822        startAppProblemLocked(app);
9823        app.stopFreezingAllLocked();
9824        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9825    }
9826
9827    private void makeAppNotRespondingLocked(ProcessRecord app,
9828            String activity, String shortMsg, String longMsg) {
9829        app.notResponding = true;
9830        app.notRespondingReport = generateProcessError(app,
9831                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9832                activity, shortMsg, longMsg, null);
9833        startAppProblemLocked(app);
9834        app.stopFreezingAllLocked();
9835    }
9836
9837    /**
9838     * Generate a process error record, suitable for attachment to a ProcessRecord.
9839     *
9840     * @param app The ProcessRecord in which the error occurred.
9841     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9842     *                      ActivityManager.AppErrorStateInfo
9843     * @param activity The activity associated with the crash, if known.
9844     * @param shortMsg Short message describing the crash.
9845     * @param longMsg Long message describing the crash.
9846     * @param stackTrace Full crash stack trace, may be null.
9847     *
9848     * @return Returns a fully-formed AppErrorStateInfo record.
9849     */
9850    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9851            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9852        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9853
9854        report.condition = condition;
9855        report.processName = app.processName;
9856        report.pid = app.pid;
9857        report.uid = app.info.uid;
9858        report.tag = activity;
9859        report.shortMsg = shortMsg;
9860        report.longMsg = longMsg;
9861        report.stackTrace = stackTrace;
9862
9863        return report;
9864    }
9865
9866    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9867        synchronized (this) {
9868            app.crashing = false;
9869            app.crashingReport = null;
9870            app.notResponding = false;
9871            app.notRespondingReport = null;
9872            if (app.anrDialog == fromDialog) {
9873                app.anrDialog = null;
9874            }
9875            if (app.waitDialog == fromDialog) {
9876                app.waitDialog = null;
9877            }
9878            if (app.pid > 0 && app.pid != MY_PID) {
9879                handleAppCrashLocked(app, null, null, null);
9880                killUnneededProcessLocked(app, "user request after error");
9881            }
9882        }
9883    }
9884
9885    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9886            String stackTrace) {
9887        long now = SystemClock.uptimeMillis();
9888
9889        Long crashTime;
9890        if (!app.isolated) {
9891            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9892        } else {
9893            crashTime = null;
9894        }
9895        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9896            // This process loses!
9897            Slog.w(TAG, "Process " + app.info.processName
9898                    + " has crashed too many times: killing!");
9899            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9900                    app.userId, app.info.processName, app.uid);
9901            mStackSupervisor.handleAppCrashLocked(app);
9902            if (!app.persistent) {
9903                // We don't want to start this process again until the user
9904                // explicitly does so...  but for persistent process, we really
9905                // need to keep it running.  If a persistent process is actually
9906                // repeatedly crashing, then badness for everyone.
9907                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9908                        app.info.processName);
9909                if (!app.isolated) {
9910                    // XXX We don't have a way to mark isolated processes
9911                    // as bad, since they don't have a peristent identity.
9912                    mBadProcesses.put(app.info.processName, app.uid,
9913                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9914                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9915                }
9916                app.bad = true;
9917                app.removed = true;
9918                // Don't let services in this process be restarted and potentially
9919                // annoy the user repeatedly.  Unless it is persistent, since those
9920                // processes run critical code.
9921                removeProcessLocked(app, false, false, "crash");
9922                mStackSupervisor.resumeTopActivitiesLocked();
9923                return false;
9924            }
9925            mStackSupervisor.resumeTopActivitiesLocked();
9926        } else {
9927            mStackSupervisor.finishTopRunningActivityLocked(app);
9928        }
9929
9930        // Bump up the crash count of any services currently running in the proc.
9931        for (int i=app.services.size()-1; i>=0; i--) {
9932            // Any services running in the application need to be placed
9933            // back in the pending list.
9934            ServiceRecord sr = app.services.valueAt(i);
9935            sr.crashCount++;
9936        }
9937
9938        // If the crashing process is what we consider to be the "home process" and it has been
9939        // replaced by a third-party app, clear the package preferred activities from packages
9940        // with a home activity running in the process to prevent a repeatedly crashing app
9941        // from blocking the user to manually clear the list.
9942        final ArrayList<ActivityRecord> activities = app.activities;
9943        if (app == mHomeProcess && activities.size() > 0
9944                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9945            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9946                final ActivityRecord r = activities.get(activityNdx);
9947                if (r.isHomeActivity()) {
9948                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9949                    try {
9950                        ActivityThread.getPackageManager()
9951                                .clearPackagePreferredActivities(r.packageName);
9952                    } catch (RemoteException c) {
9953                        // pm is in same process, this will never happen.
9954                    }
9955                }
9956            }
9957        }
9958
9959        if (!app.isolated) {
9960            // XXX Can't keep track of crash times for isolated processes,
9961            // because they don't have a perisistent identity.
9962            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9963        }
9964
9965        return true;
9966    }
9967
9968    void startAppProblemLocked(ProcessRecord app) {
9969        if (app.userId == mCurrentUserId) {
9970            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9971                    mContext, app.info.packageName, app.info.flags);
9972        } else {
9973            // If this app is not running under the current user, then we
9974            // can't give it a report button because that would require
9975            // launching the report UI under a different user.
9976            app.errorReportReceiver = null;
9977        }
9978        skipCurrentReceiverLocked(app);
9979    }
9980
9981    void skipCurrentReceiverLocked(ProcessRecord app) {
9982        for (BroadcastQueue queue : mBroadcastQueues) {
9983            queue.skipCurrentReceiverLocked(app);
9984        }
9985    }
9986
9987    /**
9988     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9989     * The application process will exit immediately after this call returns.
9990     * @param app object of the crashing app, null for the system server
9991     * @param crashInfo describing the exception
9992     */
9993    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9994        ProcessRecord r = findAppProcess(app, "Crash");
9995        final String processName = app == null ? "system_server"
9996                : (r == null ? "unknown" : r.processName);
9997
9998        handleApplicationCrashInner("crash", r, processName, crashInfo);
9999    }
10000
10001    /* Native crash reporting uses this inner version because it needs to be somewhat
10002     * decoupled from the AM-managed cleanup lifecycle
10003     */
10004    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10005            ApplicationErrorReport.CrashInfo crashInfo) {
10006        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10007                UserHandle.getUserId(Binder.getCallingUid()), processName,
10008                r == null ? -1 : r.info.flags,
10009                crashInfo.exceptionClassName,
10010                crashInfo.exceptionMessage,
10011                crashInfo.throwFileName,
10012                crashInfo.throwLineNumber);
10013
10014        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10015
10016        crashApplication(r, crashInfo);
10017    }
10018
10019    public void handleApplicationStrictModeViolation(
10020            IBinder app,
10021            int violationMask,
10022            StrictMode.ViolationInfo info) {
10023        ProcessRecord r = findAppProcess(app, "StrictMode");
10024        if (r == null) {
10025            return;
10026        }
10027
10028        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10029            Integer stackFingerprint = info.hashCode();
10030            boolean logIt = true;
10031            synchronized (mAlreadyLoggedViolatedStacks) {
10032                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10033                    logIt = false;
10034                    // TODO: sub-sample into EventLog for these, with
10035                    // the info.durationMillis?  Then we'd get
10036                    // the relative pain numbers, without logging all
10037                    // the stack traces repeatedly.  We'd want to do
10038                    // likewise in the client code, which also does
10039                    // dup suppression, before the Binder call.
10040                } else {
10041                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10042                        mAlreadyLoggedViolatedStacks.clear();
10043                    }
10044                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10045                }
10046            }
10047            if (logIt) {
10048                logStrictModeViolationToDropBox(r, info);
10049            }
10050        }
10051
10052        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10053            AppErrorResult result = new AppErrorResult();
10054            synchronized (this) {
10055                final long origId = Binder.clearCallingIdentity();
10056
10057                Message msg = Message.obtain();
10058                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10059                HashMap<String, Object> data = new HashMap<String, Object>();
10060                data.put("result", result);
10061                data.put("app", r);
10062                data.put("violationMask", violationMask);
10063                data.put("info", info);
10064                msg.obj = data;
10065                mHandler.sendMessage(msg);
10066
10067                Binder.restoreCallingIdentity(origId);
10068            }
10069            int res = result.get();
10070            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10071        }
10072    }
10073
10074    // Depending on the policy in effect, there could be a bunch of
10075    // these in quick succession so we try to batch these together to
10076    // minimize disk writes, number of dropbox entries, and maximize
10077    // compression, by having more fewer, larger records.
10078    private void logStrictModeViolationToDropBox(
10079            ProcessRecord process,
10080            StrictMode.ViolationInfo info) {
10081        if (info == null) {
10082            return;
10083        }
10084        final boolean isSystemApp = process == null ||
10085                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10086                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10087        final String processName = process == null ? "unknown" : process.processName;
10088        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10089        final DropBoxManager dbox = (DropBoxManager)
10090                mContext.getSystemService(Context.DROPBOX_SERVICE);
10091
10092        // Exit early if the dropbox isn't configured to accept this report type.
10093        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10094
10095        boolean bufferWasEmpty;
10096        boolean needsFlush;
10097        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10098        synchronized (sb) {
10099            bufferWasEmpty = sb.length() == 0;
10100            appendDropBoxProcessHeaders(process, processName, sb);
10101            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10102            sb.append("System-App: ").append(isSystemApp).append("\n");
10103            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10104            if (info.violationNumThisLoop != 0) {
10105                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10106            }
10107            if (info.numAnimationsRunning != 0) {
10108                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10109            }
10110            if (info.broadcastIntentAction != null) {
10111                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10112            }
10113            if (info.durationMillis != -1) {
10114                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10115            }
10116            if (info.numInstances != -1) {
10117                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10118            }
10119            if (info.tags != null) {
10120                for (String tag : info.tags) {
10121                    sb.append("Span-Tag: ").append(tag).append("\n");
10122                }
10123            }
10124            sb.append("\n");
10125            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10126                sb.append(info.crashInfo.stackTrace);
10127            }
10128            sb.append("\n");
10129
10130            // Only buffer up to ~64k.  Various logging bits truncate
10131            // things at 128k.
10132            needsFlush = (sb.length() > 64 * 1024);
10133        }
10134
10135        // Flush immediately if the buffer's grown too large, or this
10136        // is a non-system app.  Non-system apps are isolated with a
10137        // different tag & policy and not batched.
10138        //
10139        // Batching is useful during internal testing with
10140        // StrictMode settings turned up high.  Without batching,
10141        // thousands of separate files could be created on boot.
10142        if (!isSystemApp || needsFlush) {
10143            new Thread("Error dump: " + dropboxTag) {
10144                @Override
10145                public void run() {
10146                    String report;
10147                    synchronized (sb) {
10148                        report = sb.toString();
10149                        sb.delete(0, sb.length());
10150                        sb.trimToSize();
10151                    }
10152                    if (report.length() != 0) {
10153                        dbox.addText(dropboxTag, report);
10154                    }
10155                }
10156            }.start();
10157            return;
10158        }
10159
10160        // System app batching:
10161        if (!bufferWasEmpty) {
10162            // An existing dropbox-writing thread is outstanding, so
10163            // we don't need to start it up.  The existing thread will
10164            // catch the buffer appends we just did.
10165            return;
10166        }
10167
10168        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10169        // (After this point, we shouldn't access AMS internal data structures.)
10170        new Thread("Error dump: " + dropboxTag) {
10171            @Override
10172            public void run() {
10173                // 5 second sleep to let stacks arrive and be batched together
10174                try {
10175                    Thread.sleep(5000);  // 5 seconds
10176                } catch (InterruptedException e) {}
10177
10178                String errorReport;
10179                synchronized (mStrictModeBuffer) {
10180                    errorReport = mStrictModeBuffer.toString();
10181                    if (errorReport.length() == 0) {
10182                        return;
10183                    }
10184                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10185                    mStrictModeBuffer.trimToSize();
10186                }
10187                dbox.addText(dropboxTag, errorReport);
10188            }
10189        }.start();
10190    }
10191
10192    /**
10193     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10194     * @param app object of the crashing app, null for the system server
10195     * @param tag reported by the caller
10196     * @param crashInfo describing the context of the error
10197     * @return true if the process should exit immediately (WTF is fatal)
10198     */
10199    public boolean handleApplicationWtf(IBinder app, String tag,
10200            ApplicationErrorReport.CrashInfo crashInfo) {
10201        ProcessRecord r = findAppProcess(app, "WTF");
10202        final String processName = app == null ? "system_server"
10203                : (r == null ? "unknown" : r.processName);
10204
10205        EventLog.writeEvent(EventLogTags.AM_WTF,
10206                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10207                processName,
10208                r == null ? -1 : r.info.flags,
10209                tag, crashInfo.exceptionMessage);
10210
10211        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10212
10213        if (r != null && r.pid != Process.myPid() &&
10214                Settings.Global.getInt(mContext.getContentResolver(),
10215                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10216            crashApplication(r, crashInfo);
10217            return true;
10218        } else {
10219            return false;
10220        }
10221    }
10222
10223    /**
10224     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10225     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10226     */
10227    private ProcessRecord findAppProcess(IBinder app, String reason) {
10228        if (app == null) {
10229            return null;
10230        }
10231
10232        synchronized (this) {
10233            final int NP = mProcessNames.getMap().size();
10234            for (int ip=0; ip<NP; ip++) {
10235                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10236                final int NA = apps.size();
10237                for (int ia=0; ia<NA; ia++) {
10238                    ProcessRecord p = apps.valueAt(ia);
10239                    if (p.thread != null && p.thread.asBinder() == app) {
10240                        return p;
10241                    }
10242                }
10243            }
10244
10245            Slog.w(TAG, "Can't find mystery application for " + reason
10246                    + " from pid=" + Binder.getCallingPid()
10247                    + " uid=" + Binder.getCallingUid() + ": " + app);
10248            return null;
10249        }
10250    }
10251
10252    /**
10253     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10254     * to append various headers to the dropbox log text.
10255     */
10256    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10257            StringBuilder sb) {
10258        // Watchdog thread ends up invoking this function (with
10259        // a null ProcessRecord) to add the stack file to dropbox.
10260        // Do not acquire a lock on this (am) in such cases, as it
10261        // could cause a potential deadlock, if and when watchdog
10262        // is invoked due to unavailability of lock on am and it
10263        // would prevent watchdog from killing system_server.
10264        if (process == null) {
10265            sb.append("Process: ").append(processName).append("\n");
10266            return;
10267        }
10268        // Note: ProcessRecord 'process' is guarded by the service
10269        // instance.  (notably process.pkgList, which could otherwise change
10270        // concurrently during execution of this method)
10271        synchronized (this) {
10272            sb.append("Process: ").append(processName).append("\n");
10273            int flags = process.info.flags;
10274            IPackageManager pm = AppGlobals.getPackageManager();
10275            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10276            for (int ip=0; ip<process.pkgList.size(); ip++) {
10277                String pkg = process.pkgList.keyAt(ip);
10278                sb.append("Package: ").append(pkg);
10279                try {
10280                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10281                    if (pi != null) {
10282                        sb.append(" v").append(pi.versionCode);
10283                        if (pi.versionName != null) {
10284                            sb.append(" (").append(pi.versionName).append(")");
10285                        }
10286                    }
10287                } catch (RemoteException e) {
10288                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10289                }
10290                sb.append("\n");
10291            }
10292        }
10293    }
10294
10295    private static String processClass(ProcessRecord process) {
10296        if (process == null || process.pid == MY_PID) {
10297            return "system_server";
10298        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10299            return "system_app";
10300        } else {
10301            return "data_app";
10302        }
10303    }
10304
10305    /**
10306     * Write a description of an error (crash, WTF, ANR) to the drop box.
10307     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10308     * @param process which caused the error, null means the system server
10309     * @param activity which triggered the error, null if unknown
10310     * @param parent activity related to the error, null if unknown
10311     * @param subject line related to the error, null if absent
10312     * @param report in long form describing the error, null if absent
10313     * @param logFile to include in the report, null if none
10314     * @param crashInfo giving an application stack trace, null if absent
10315     */
10316    public void addErrorToDropBox(String eventType,
10317            ProcessRecord process, String processName, ActivityRecord activity,
10318            ActivityRecord parent, String subject,
10319            final String report, final File logFile,
10320            final ApplicationErrorReport.CrashInfo crashInfo) {
10321        // NOTE -- this must never acquire the ActivityManagerService lock,
10322        // otherwise the watchdog may be prevented from resetting the system.
10323
10324        final String dropboxTag = processClass(process) + "_" + eventType;
10325        final DropBoxManager dbox = (DropBoxManager)
10326                mContext.getSystemService(Context.DROPBOX_SERVICE);
10327
10328        // Exit early if the dropbox isn't configured to accept this report type.
10329        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10330
10331        final StringBuilder sb = new StringBuilder(1024);
10332        appendDropBoxProcessHeaders(process, processName, sb);
10333        if (activity != null) {
10334            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10335        }
10336        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10337            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10338        }
10339        if (parent != null && parent != activity) {
10340            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10341        }
10342        if (subject != null) {
10343            sb.append("Subject: ").append(subject).append("\n");
10344        }
10345        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10346        if (Debug.isDebuggerConnected()) {
10347            sb.append("Debugger: Connected\n");
10348        }
10349        sb.append("\n");
10350
10351        // Do the rest in a worker thread to avoid blocking the caller on I/O
10352        // (After this point, we shouldn't access AMS internal data structures.)
10353        Thread worker = new Thread("Error dump: " + dropboxTag) {
10354            @Override
10355            public void run() {
10356                if (report != null) {
10357                    sb.append(report);
10358                }
10359                if (logFile != null) {
10360                    try {
10361                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10362                                    "\n\n[[TRUNCATED]]"));
10363                    } catch (IOException e) {
10364                        Slog.e(TAG, "Error reading " + logFile, e);
10365                    }
10366                }
10367                if (crashInfo != null && crashInfo.stackTrace != null) {
10368                    sb.append(crashInfo.stackTrace);
10369                }
10370
10371                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10372                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10373                if (lines > 0) {
10374                    sb.append("\n");
10375
10376                    // Merge several logcat streams, and take the last N lines
10377                    InputStreamReader input = null;
10378                    try {
10379                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10380                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10381                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10382
10383                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10384                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10385                        input = new InputStreamReader(logcat.getInputStream());
10386
10387                        int num;
10388                        char[] buf = new char[8192];
10389                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10390                    } catch (IOException e) {
10391                        Slog.e(TAG, "Error running logcat", e);
10392                    } finally {
10393                        if (input != null) try { input.close(); } catch (IOException e) {}
10394                    }
10395                }
10396
10397                dbox.addText(dropboxTag, sb.toString());
10398            }
10399        };
10400
10401        if (process == null) {
10402            // If process is null, we are being called from some internal code
10403            // and may be about to die -- run this synchronously.
10404            worker.run();
10405        } else {
10406            worker.start();
10407        }
10408    }
10409
10410    /**
10411     * Bring up the "unexpected error" dialog box for a crashing app.
10412     * Deal with edge cases (intercepts from instrumented applications,
10413     * ActivityController, error intent receivers, that sort of thing).
10414     * @param r the application crashing
10415     * @param crashInfo describing the failure
10416     */
10417    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10418        long timeMillis = System.currentTimeMillis();
10419        String shortMsg = crashInfo.exceptionClassName;
10420        String longMsg = crashInfo.exceptionMessage;
10421        String stackTrace = crashInfo.stackTrace;
10422        if (shortMsg != null && longMsg != null) {
10423            longMsg = shortMsg + ": " + longMsg;
10424        } else if (shortMsg != null) {
10425            longMsg = shortMsg;
10426        }
10427
10428        AppErrorResult result = new AppErrorResult();
10429        synchronized (this) {
10430            if (mController != null) {
10431                try {
10432                    String name = r != null ? r.processName : null;
10433                    int pid = r != null ? r.pid : Binder.getCallingPid();
10434                    if (!mController.appCrashed(name, pid,
10435                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10436                        Slog.w(TAG, "Force-killing crashed app " + name
10437                                + " at watcher's request");
10438                        Process.killProcess(pid);
10439                        return;
10440                    }
10441                } catch (RemoteException e) {
10442                    mController = null;
10443                    Watchdog.getInstance().setActivityController(null);
10444                }
10445            }
10446
10447            final long origId = Binder.clearCallingIdentity();
10448
10449            // If this process is running instrumentation, finish it.
10450            if (r != null && r.instrumentationClass != null) {
10451                Slog.w(TAG, "Error in app " + r.processName
10452                      + " running instrumentation " + r.instrumentationClass + ":");
10453                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10454                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10455                Bundle info = new Bundle();
10456                info.putString("shortMsg", shortMsg);
10457                info.putString("longMsg", longMsg);
10458                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10459                Binder.restoreCallingIdentity(origId);
10460                return;
10461            }
10462
10463            // If we can't identify the process or it's already exceeded its crash quota,
10464            // quit right away without showing a crash dialog.
10465            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10466                Binder.restoreCallingIdentity(origId);
10467                return;
10468            }
10469
10470            Message msg = Message.obtain();
10471            msg.what = SHOW_ERROR_MSG;
10472            HashMap data = new HashMap();
10473            data.put("result", result);
10474            data.put("app", r);
10475            msg.obj = data;
10476            mHandler.sendMessage(msg);
10477
10478            Binder.restoreCallingIdentity(origId);
10479        }
10480
10481        int res = result.get();
10482
10483        Intent appErrorIntent = null;
10484        synchronized (this) {
10485            if (r != null && !r.isolated) {
10486                // XXX Can't keep track of crash time for isolated processes,
10487                // since they don't have a persistent identity.
10488                mProcessCrashTimes.put(r.info.processName, r.uid,
10489                        SystemClock.uptimeMillis());
10490            }
10491            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10492                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10493            }
10494        }
10495
10496        if (appErrorIntent != null) {
10497            try {
10498                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10499            } catch (ActivityNotFoundException e) {
10500                Slog.w(TAG, "bug report receiver dissappeared", e);
10501            }
10502        }
10503    }
10504
10505    Intent createAppErrorIntentLocked(ProcessRecord r,
10506            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10507        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10508        if (report == null) {
10509            return null;
10510        }
10511        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10512        result.setComponent(r.errorReportReceiver);
10513        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10514        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10515        return result;
10516    }
10517
10518    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10519            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10520        if (r.errorReportReceiver == null) {
10521            return null;
10522        }
10523
10524        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10525            return null;
10526        }
10527
10528        ApplicationErrorReport report = new ApplicationErrorReport();
10529        report.packageName = r.info.packageName;
10530        report.installerPackageName = r.errorReportReceiver.getPackageName();
10531        report.processName = r.processName;
10532        report.time = timeMillis;
10533        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10534
10535        if (r.crashing || r.forceCrashReport) {
10536            report.type = ApplicationErrorReport.TYPE_CRASH;
10537            report.crashInfo = crashInfo;
10538        } else if (r.notResponding) {
10539            report.type = ApplicationErrorReport.TYPE_ANR;
10540            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10541
10542            report.anrInfo.activity = r.notRespondingReport.tag;
10543            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10544            report.anrInfo.info = r.notRespondingReport.longMsg;
10545        }
10546
10547        return report;
10548    }
10549
10550    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10551        enforceNotIsolatedCaller("getProcessesInErrorState");
10552        // assume our apps are happy - lazy create the list
10553        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10554
10555        final boolean allUsers = ActivityManager.checkUidPermission(
10556                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10557                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10558        int userId = UserHandle.getUserId(Binder.getCallingUid());
10559
10560        synchronized (this) {
10561
10562            // iterate across all processes
10563            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10564                ProcessRecord app = mLruProcesses.get(i);
10565                if (!allUsers && app.userId != userId) {
10566                    continue;
10567                }
10568                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10569                    // This one's in trouble, so we'll generate a report for it
10570                    // crashes are higher priority (in case there's a crash *and* an anr)
10571                    ActivityManager.ProcessErrorStateInfo report = null;
10572                    if (app.crashing) {
10573                        report = app.crashingReport;
10574                    } else if (app.notResponding) {
10575                        report = app.notRespondingReport;
10576                    }
10577
10578                    if (report != null) {
10579                        if (errList == null) {
10580                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10581                        }
10582                        errList.add(report);
10583                    } else {
10584                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10585                                " crashing = " + app.crashing +
10586                                " notResponding = " + app.notResponding);
10587                    }
10588                }
10589            }
10590        }
10591
10592        return errList;
10593    }
10594
10595    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10596        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10597            if (currApp != null) {
10598                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10599            }
10600            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10601        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10602            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10603        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10604            if (currApp != null) {
10605                currApp.lru = 0;
10606            }
10607            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10608        } else if (adj >= ProcessList.SERVICE_ADJ) {
10609            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10610        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10611            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10612        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10613            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10614        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10615            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10616        } else {
10617            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10618        }
10619    }
10620
10621    private void fillInProcMemInfo(ProcessRecord app,
10622            ActivityManager.RunningAppProcessInfo outInfo) {
10623        outInfo.pid = app.pid;
10624        outInfo.uid = app.info.uid;
10625        if (mHeavyWeightProcess == app) {
10626            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10627        }
10628        if (app.persistent) {
10629            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10630        }
10631        if (app.activities.size() > 0) {
10632            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10633        }
10634        outInfo.lastTrimLevel = app.trimMemoryLevel;
10635        int adj = app.curAdj;
10636        outInfo.importance = oomAdjToImportance(adj, outInfo);
10637        outInfo.importanceReasonCode = app.adjTypeCode;
10638    }
10639
10640    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10641        enforceNotIsolatedCaller("getRunningAppProcesses");
10642        // Lazy instantiation of list
10643        List<ActivityManager.RunningAppProcessInfo> runList = null;
10644        final boolean allUsers = ActivityManager.checkUidPermission(
10645                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10646                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10647        int userId = UserHandle.getUserId(Binder.getCallingUid());
10648        synchronized (this) {
10649            // Iterate across all processes
10650            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10651                ProcessRecord app = mLruProcesses.get(i);
10652                if (!allUsers && app.userId != userId) {
10653                    continue;
10654                }
10655                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10656                    // Generate process state info for running application
10657                    ActivityManager.RunningAppProcessInfo currApp =
10658                        new ActivityManager.RunningAppProcessInfo(app.processName,
10659                                app.pid, app.getPackageList());
10660                    fillInProcMemInfo(app, currApp);
10661                    if (app.adjSource instanceof ProcessRecord) {
10662                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10663                        currApp.importanceReasonImportance = oomAdjToImportance(
10664                                app.adjSourceOom, null);
10665                    } else if (app.adjSource instanceof ActivityRecord) {
10666                        ActivityRecord r = (ActivityRecord)app.adjSource;
10667                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10668                    }
10669                    if (app.adjTarget instanceof ComponentName) {
10670                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10671                    }
10672                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10673                    //        + " lru=" + currApp.lru);
10674                    if (runList == null) {
10675                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10676                    }
10677                    runList.add(currApp);
10678                }
10679            }
10680        }
10681        return runList;
10682    }
10683
10684    public List<ApplicationInfo> getRunningExternalApplications() {
10685        enforceNotIsolatedCaller("getRunningExternalApplications");
10686        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10687        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10688        if (runningApps != null && runningApps.size() > 0) {
10689            Set<String> extList = new HashSet<String>();
10690            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10691                if (app.pkgList != null) {
10692                    for (String pkg : app.pkgList) {
10693                        extList.add(pkg);
10694                    }
10695                }
10696            }
10697            IPackageManager pm = AppGlobals.getPackageManager();
10698            for (String pkg : extList) {
10699                try {
10700                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10701                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10702                        retList.add(info);
10703                    }
10704                } catch (RemoteException e) {
10705                }
10706            }
10707        }
10708        return retList;
10709    }
10710
10711    @Override
10712    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10713        enforceNotIsolatedCaller("getMyMemoryState");
10714        synchronized (this) {
10715            ProcessRecord proc;
10716            synchronized (mPidsSelfLocked) {
10717                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10718            }
10719            fillInProcMemInfo(proc, outInfo);
10720        }
10721    }
10722
10723    @Override
10724    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10725        if (checkCallingPermission(android.Manifest.permission.DUMP)
10726                != PackageManager.PERMISSION_GRANTED) {
10727            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10728                    + Binder.getCallingPid()
10729                    + ", uid=" + Binder.getCallingUid()
10730                    + " without permission "
10731                    + android.Manifest.permission.DUMP);
10732            return;
10733        }
10734
10735        boolean dumpAll = false;
10736        boolean dumpClient = false;
10737        String dumpPackage = null;
10738
10739        int opti = 0;
10740        while (opti < args.length) {
10741            String opt = args[opti];
10742            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10743                break;
10744            }
10745            opti++;
10746            if ("-a".equals(opt)) {
10747                dumpAll = true;
10748            } else if ("-c".equals(opt)) {
10749                dumpClient = true;
10750            } else if ("-h".equals(opt)) {
10751                pw.println("Activity manager dump options:");
10752                pw.println("  [-a] [-c] [-h] [cmd] ...");
10753                pw.println("  cmd may be one of:");
10754                pw.println("    a[ctivities]: activity stack state");
10755                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10756                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10757                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10758                pw.println("    o[om]: out of memory management");
10759                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10760                pw.println("    provider [COMP_SPEC]: provider client-side state");
10761                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10762                pw.println("    service [COMP_SPEC]: service client-side state");
10763                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10764                pw.println("    all: dump all activities");
10765                pw.println("    top: dump the top activity");
10766                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10767                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10768                pw.println("    a partial substring in a component name, a");
10769                pw.println("    hex object identifier.");
10770                pw.println("  -a: include all available server state.");
10771                pw.println("  -c: include client state.");
10772                return;
10773            } else {
10774                pw.println("Unknown argument: " + opt + "; use -h for help");
10775            }
10776        }
10777
10778        long origId = Binder.clearCallingIdentity();
10779        boolean more = false;
10780        // Is the caller requesting to dump a particular piece of data?
10781        if (opti < args.length) {
10782            String cmd = args[opti];
10783            opti++;
10784            if ("activities".equals(cmd) || "a".equals(cmd)) {
10785                synchronized (this) {
10786                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10787                }
10788            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10789                String[] newArgs;
10790                String name;
10791                if (opti >= args.length) {
10792                    name = null;
10793                    newArgs = EMPTY_STRING_ARRAY;
10794                } else {
10795                    name = args[opti];
10796                    opti++;
10797                    newArgs = new String[args.length - opti];
10798                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10799                            args.length - opti);
10800                }
10801                synchronized (this) {
10802                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10803                }
10804            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10805                String[] newArgs;
10806                String name;
10807                if (opti >= args.length) {
10808                    name = null;
10809                    newArgs = EMPTY_STRING_ARRAY;
10810                } else {
10811                    name = args[opti];
10812                    opti++;
10813                    newArgs = new String[args.length - opti];
10814                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10815                            args.length - opti);
10816                }
10817                synchronized (this) {
10818                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10819                }
10820            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10821                String[] newArgs;
10822                String name;
10823                if (opti >= args.length) {
10824                    name = null;
10825                    newArgs = EMPTY_STRING_ARRAY;
10826                } else {
10827                    name = args[opti];
10828                    opti++;
10829                    newArgs = new String[args.length - opti];
10830                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10831                            args.length - opti);
10832                }
10833                synchronized (this) {
10834                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10835                }
10836            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10837                synchronized (this) {
10838                    dumpOomLocked(fd, pw, args, opti, true);
10839                }
10840            } else if ("provider".equals(cmd)) {
10841                String[] newArgs;
10842                String name;
10843                if (opti >= args.length) {
10844                    name = null;
10845                    newArgs = EMPTY_STRING_ARRAY;
10846                } else {
10847                    name = args[opti];
10848                    opti++;
10849                    newArgs = new String[args.length - opti];
10850                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10851                }
10852                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10853                    pw.println("No providers match: " + name);
10854                    pw.println("Use -h for help.");
10855                }
10856            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10857                synchronized (this) {
10858                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10859                }
10860            } else if ("service".equals(cmd)) {
10861                String[] newArgs;
10862                String name;
10863                if (opti >= args.length) {
10864                    name = null;
10865                    newArgs = EMPTY_STRING_ARRAY;
10866                } else {
10867                    name = args[opti];
10868                    opti++;
10869                    newArgs = new String[args.length - opti];
10870                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10871                            args.length - opti);
10872                }
10873                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10874                    pw.println("No services match: " + name);
10875                    pw.println("Use -h for help.");
10876                }
10877            } else if ("package".equals(cmd)) {
10878                String[] newArgs;
10879                if (opti >= args.length) {
10880                    pw.println("package: no package name specified");
10881                    pw.println("Use -h for help.");
10882                } else {
10883                    dumpPackage = args[opti];
10884                    opti++;
10885                    newArgs = new String[args.length - opti];
10886                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10887                            args.length - opti);
10888                    args = newArgs;
10889                    opti = 0;
10890                    more = true;
10891                }
10892            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10893                synchronized (this) {
10894                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10895                }
10896            } else {
10897                // Dumping a single activity?
10898                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10899                    pw.println("Bad activity command, or no activities match: " + cmd);
10900                    pw.println("Use -h for help.");
10901                }
10902            }
10903            if (!more) {
10904                Binder.restoreCallingIdentity(origId);
10905                return;
10906            }
10907        }
10908
10909        // No piece of data specified, dump everything.
10910        synchronized (this) {
10911            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10912            pw.println();
10913            if (dumpAll) {
10914                pw.println("-------------------------------------------------------------------------------");
10915            }
10916            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10917            pw.println();
10918            if (dumpAll) {
10919                pw.println("-------------------------------------------------------------------------------");
10920            }
10921            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10922            pw.println();
10923            if (dumpAll) {
10924                pw.println("-------------------------------------------------------------------------------");
10925            }
10926            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10927            pw.println();
10928            if (dumpAll) {
10929                pw.println("-------------------------------------------------------------------------------");
10930            }
10931            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10932            pw.println();
10933            if (dumpAll) {
10934                pw.println("-------------------------------------------------------------------------------");
10935            }
10936            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10937        }
10938        Binder.restoreCallingIdentity(origId);
10939    }
10940
10941    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10942            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10943        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10944
10945        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10946                dumpPackage);
10947        boolean needSep = printedAnything;
10948
10949        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10950                dumpPackage, needSep, "  mFocusedActivity: ");
10951        if (printed) {
10952            printedAnything = true;
10953            needSep = false;
10954        }
10955
10956        if (dumpPackage == null) {
10957            if (needSep) {
10958                pw.println();
10959            }
10960            needSep = true;
10961            printedAnything = true;
10962            mStackSupervisor.dump(pw, "  ");
10963        }
10964
10965        if (mRecentTasks.size() > 0) {
10966            boolean printedHeader = false;
10967
10968            final int N = mRecentTasks.size();
10969            for (int i=0; i<N; i++) {
10970                TaskRecord tr = mRecentTasks.get(i);
10971                if (dumpPackage != null) {
10972                    if (tr.realActivity == null ||
10973                            !dumpPackage.equals(tr.realActivity)) {
10974                        continue;
10975                    }
10976                }
10977                if (!printedHeader) {
10978                    if (needSep) {
10979                        pw.println();
10980                    }
10981                    pw.println("  Recent tasks:");
10982                    printedHeader = true;
10983                    printedAnything = true;
10984                }
10985                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10986                        pw.println(tr);
10987                if (dumpAll) {
10988                    mRecentTasks.get(i).dump(pw, "    ");
10989                }
10990            }
10991        }
10992
10993        if (!printedAnything) {
10994            pw.println("  (nothing)");
10995        }
10996    }
10997
10998    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10999            int opti, boolean dumpAll, String dumpPackage) {
11000        boolean needSep = false;
11001        boolean printedAnything = false;
11002        int numPers = 0;
11003
11004        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11005
11006        if (dumpAll) {
11007            final int NP = mProcessNames.getMap().size();
11008            for (int ip=0; ip<NP; ip++) {
11009                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11010                final int NA = procs.size();
11011                for (int ia=0; ia<NA; ia++) {
11012                    ProcessRecord r = procs.valueAt(ia);
11013                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11014                        continue;
11015                    }
11016                    if (!needSep) {
11017                        pw.println("  All known processes:");
11018                        needSep = true;
11019                        printedAnything = true;
11020                    }
11021                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11022                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11023                        pw.print(" "); pw.println(r);
11024                    r.dump(pw, "    ");
11025                    if (r.persistent) {
11026                        numPers++;
11027                    }
11028                }
11029            }
11030        }
11031
11032        if (mIsolatedProcesses.size() > 0) {
11033            boolean printed = false;
11034            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11035                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11036                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11037                    continue;
11038                }
11039                if (!printed) {
11040                    if (needSep) {
11041                        pw.println();
11042                    }
11043                    pw.println("  Isolated process list (sorted by uid):");
11044                    printedAnything = true;
11045                    printed = true;
11046                    needSep = true;
11047                }
11048                pw.println(String.format("%sIsolated #%2d: %s",
11049                        "    ", i, r.toString()));
11050            }
11051        }
11052
11053        if (mLruProcesses.size() > 0) {
11054            if (needSep) {
11055                pw.println();
11056            }
11057            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11058                    pw.print(" total, non-act at ");
11059                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11060                    pw.print(", non-svc at ");
11061                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11062                    pw.println("):");
11063            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11064            needSep = true;
11065            printedAnything = true;
11066        }
11067
11068        if (dumpAll || dumpPackage != null) {
11069            synchronized (mPidsSelfLocked) {
11070                boolean printed = false;
11071                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11072                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11073                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11074                        continue;
11075                    }
11076                    if (!printed) {
11077                        if (needSep) pw.println();
11078                        needSep = true;
11079                        pw.println("  PID mappings:");
11080                        printed = true;
11081                        printedAnything = true;
11082                    }
11083                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11084                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11085                }
11086            }
11087        }
11088
11089        if (mForegroundProcesses.size() > 0) {
11090            synchronized (mPidsSelfLocked) {
11091                boolean printed = false;
11092                for (int i=0; i<mForegroundProcesses.size(); i++) {
11093                    ProcessRecord r = mPidsSelfLocked.get(
11094                            mForegroundProcesses.valueAt(i).pid);
11095                    if (dumpPackage != null && (r == null
11096                            || !r.pkgList.containsKey(dumpPackage))) {
11097                        continue;
11098                    }
11099                    if (!printed) {
11100                        if (needSep) pw.println();
11101                        needSep = true;
11102                        pw.println("  Foreground Processes:");
11103                        printed = true;
11104                        printedAnything = true;
11105                    }
11106                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11107                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11108                }
11109            }
11110        }
11111
11112        if (mPersistentStartingProcesses.size() > 0) {
11113            if (needSep) pw.println();
11114            needSep = true;
11115            printedAnything = true;
11116            pw.println("  Persisent processes that are starting:");
11117            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11118                    "Starting Norm", "Restarting PERS", dumpPackage);
11119        }
11120
11121        if (mRemovedProcesses.size() > 0) {
11122            if (needSep) pw.println();
11123            needSep = true;
11124            printedAnything = true;
11125            pw.println("  Processes that are being removed:");
11126            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11127                    "Removed Norm", "Removed PERS", dumpPackage);
11128        }
11129
11130        if (mProcessesOnHold.size() > 0) {
11131            if (needSep) pw.println();
11132            needSep = true;
11133            printedAnything = true;
11134            pw.println("  Processes that are on old until the system is ready:");
11135            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11136                    "OnHold Norm", "OnHold PERS", dumpPackage);
11137        }
11138
11139        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11140
11141        if (mProcessCrashTimes.getMap().size() > 0) {
11142            boolean printed = false;
11143            long now = SystemClock.uptimeMillis();
11144            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11145            final int NP = pmap.size();
11146            for (int ip=0; ip<NP; ip++) {
11147                String pname = pmap.keyAt(ip);
11148                SparseArray<Long> uids = pmap.valueAt(ip);
11149                final int N = uids.size();
11150                for (int i=0; i<N; i++) {
11151                    int puid = uids.keyAt(i);
11152                    ProcessRecord r = mProcessNames.get(pname, puid);
11153                    if (dumpPackage != null && (r == null
11154                            || !r.pkgList.containsKey(dumpPackage))) {
11155                        continue;
11156                    }
11157                    if (!printed) {
11158                        if (needSep) pw.println();
11159                        needSep = true;
11160                        pw.println("  Time since processes crashed:");
11161                        printed = true;
11162                        printedAnything = true;
11163                    }
11164                    pw.print("    Process "); pw.print(pname);
11165                            pw.print(" uid "); pw.print(puid);
11166                            pw.print(": last crashed ");
11167                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11168                            pw.println(" ago");
11169                }
11170            }
11171        }
11172
11173        if (mBadProcesses.getMap().size() > 0) {
11174            boolean printed = false;
11175            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11176            final int NP = pmap.size();
11177            for (int ip=0; ip<NP; ip++) {
11178                String pname = pmap.keyAt(ip);
11179                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11180                final int N = uids.size();
11181                for (int i=0; i<N; i++) {
11182                    int puid = uids.keyAt(i);
11183                    ProcessRecord r = mProcessNames.get(pname, puid);
11184                    if (dumpPackage != null && (r == null
11185                            || !r.pkgList.containsKey(dumpPackage))) {
11186                        continue;
11187                    }
11188                    if (!printed) {
11189                        if (needSep) pw.println();
11190                        needSep = true;
11191                        pw.println("  Bad processes:");
11192                        printedAnything = true;
11193                    }
11194                    BadProcessInfo info = uids.valueAt(i);
11195                    pw.print("    Bad process "); pw.print(pname);
11196                            pw.print(" uid "); pw.print(puid);
11197                            pw.print(": crashed at time "); pw.println(info.time);
11198                    if (info.shortMsg != null) {
11199                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11200                    }
11201                    if (info.longMsg != null) {
11202                        pw.print("      Long msg: "); pw.println(info.longMsg);
11203                    }
11204                    if (info.stack != null) {
11205                        pw.println("      Stack:");
11206                        int lastPos = 0;
11207                        for (int pos=0; pos<info.stack.length(); pos++) {
11208                            if (info.stack.charAt(pos) == '\n') {
11209                                pw.print("        ");
11210                                pw.write(info.stack, lastPos, pos-lastPos);
11211                                pw.println();
11212                                lastPos = pos+1;
11213                            }
11214                        }
11215                        if (lastPos < info.stack.length()) {
11216                            pw.print("        ");
11217                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11218                            pw.println();
11219                        }
11220                    }
11221                }
11222            }
11223        }
11224
11225        if (dumpPackage == null) {
11226            pw.println();
11227            needSep = false;
11228            pw.println("  mStartedUsers:");
11229            for (int i=0; i<mStartedUsers.size(); i++) {
11230                UserStartedState uss = mStartedUsers.valueAt(i);
11231                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11232                        pw.print(": "); uss.dump("", pw);
11233            }
11234            pw.print("  mStartedUserArray: [");
11235            for (int i=0; i<mStartedUserArray.length; i++) {
11236                if (i > 0) pw.print(", ");
11237                pw.print(mStartedUserArray[i]);
11238            }
11239            pw.println("]");
11240            pw.print("  mUserLru: [");
11241            for (int i=0; i<mUserLru.size(); i++) {
11242                if (i > 0) pw.print(", ");
11243                pw.print(mUserLru.get(i));
11244            }
11245            pw.println("]");
11246            if (dumpAll) {
11247                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11248            }
11249        }
11250        if (mHomeProcess != null && (dumpPackage == null
11251                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11252            if (needSep) {
11253                pw.println();
11254                needSep = false;
11255            }
11256            pw.println("  mHomeProcess: " + mHomeProcess);
11257        }
11258        if (mPreviousProcess != null && (dumpPackage == null
11259                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11260            if (needSep) {
11261                pw.println();
11262                needSep = false;
11263            }
11264            pw.println("  mPreviousProcess: " + mPreviousProcess);
11265        }
11266        if (dumpAll) {
11267            StringBuilder sb = new StringBuilder(128);
11268            sb.append("  mPreviousProcessVisibleTime: ");
11269            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11270            pw.println(sb);
11271        }
11272        if (mHeavyWeightProcess != null && (dumpPackage == null
11273                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11274            if (needSep) {
11275                pw.println();
11276                needSep = false;
11277            }
11278            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11279        }
11280        if (dumpPackage == null) {
11281            pw.println("  mConfiguration: " + mConfiguration);
11282        }
11283        if (dumpAll) {
11284            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11285            if (mCompatModePackages.getPackages().size() > 0) {
11286                boolean printed = false;
11287                for (Map.Entry<String, Integer> entry
11288                        : mCompatModePackages.getPackages().entrySet()) {
11289                    String pkg = entry.getKey();
11290                    int mode = entry.getValue();
11291                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11292                        continue;
11293                    }
11294                    if (!printed) {
11295                        pw.println("  mScreenCompatPackages:");
11296                        printed = true;
11297                    }
11298                    pw.print("    "); pw.print(pkg); pw.print(": ");
11299                            pw.print(mode); pw.println();
11300                }
11301            }
11302        }
11303        if (dumpPackage == null) {
11304            if (mSleeping || mWentToSleep || mLockScreenShown) {
11305                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11306                        + " mLockScreenShown " + mLockScreenShown);
11307            }
11308            if (mShuttingDown || mRunningVoice) {
11309                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11310            }
11311        }
11312        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11313                || mOrigWaitForDebugger) {
11314            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11315                    || dumpPackage.equals(mOrigDebugApp)) {
11316                if (needSep) {
11317                    pw.println();
11318                    needSep = false;
11319                }
11320                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11321                        + " mDebugTransient=" + mDebugTransient
11322                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11323            }
11324        }
11325        if (mOpenGlTraceApp != null) {
11326            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11327                if (needSep) {
11328                    pw.println();
11329                    needSep = false;
11330                }
11331                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11332            }
11333        }
11334        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11335                || mProfileFd != null) {
11336            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11337                if (needSep) {
11338                    pw.println();
11339                    needSep = false;
11340                }
11341                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11342                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11343                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11344                        + mAutoStopProfiler);
11345            }
11346        }
11347        if (dumpPackage == null) {
11348            if (mAlwaysFinishActivities || mController != null) {
11349                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11350                        + " mController=" + mController);
11351            }
11352            if (dumpAll) {
11353                pw.println("  Total persistent processes: " + numPers);
11354                pw.println("  mProcessesReady=" + mProcessesReady
11355                        + " mSystemReady=" + mSystemReady);
11356                pw.println("  mBooting=" + mBooting
11357                        + " mBooted=" + mBooted
11358                        + " mFactoryTest=" + mFactoryTest);
11359                pw.print("  mLastPowerCheckRealtime=");
11360                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11361                        pw.println("");
11362                pw.print("  mLastPowerCheckUptime=");
11363                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11364                        pw.println("");
11365                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11366                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11367                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11368                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11369                        + " (" + mLruProcesses.size() + " total)"
11370                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11371                        + " mNumServiceProcs=" + mNumServiceProcs
11372                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11373                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11374                        + " mLastMemoryLevel" + mLastMemoryLevel
11375                        + " mLastNumProcesses" + mLastNumProcesses);
11376                long now = SystemClock.uptimeMillis();
11377                pw.print("  mLastIdleTime=");
11378                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11379                        pw.print(" mLowRamSinceLastIdle=");
11380                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11381                        pw.println();
11382            }
11383        }
11384
11385        if (!printedAnything) {
11386            pw.println("  (nothing)");
11387        }
11388    }
11389
11390    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11391            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11392        if (mProcessesToGc.size() > 0) {
11393            boolean printed = false;
11394            long now = SystemClock.uptimeMillis();
11395            for (int i=0; i<mProcessesToGc.size(); i++) {
11396                ProcessRecord proc = mProcessesToGc.get(i);
11397                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11398                    continue;
11399                }
11400                if (!printed) {
11401                    if (needSep) pw.println();
11402                    needSep = true;
11403                    pw.println("  Processes that are waiting to GC:");
11404                    printed = true;
11405                }
11406                pw.print("    Process "); pw.println(proc);
11407                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11408                        pw.print(", last gced=");
11409                        pw.print(now-proc.lastRequestedGc);
11410                        pw.print(" ms ago, last lowMem=");
11411                        pw.print(now-proc.lastLowMemory);
11412                        pw.println(" ms ago");
11413
11414            }
11415        }
11416        return needSep;
11417    }
11418
11419    void printOomLevel(PrintWriter pw, String name, int adj) {
11420        pw.print("    ");
11421        if (adj >= 0) {
11422            pw.print(' ');
11423            if (adj < 10) pw.print(' ');
11424        } else {
11425            if (adj > -10) pw.print(' ');
11426        }
11427        pw.print(adj);
11428        pw.print(": ");
11429        pw.print(name);
11430        pw.print(" (");
11431        pw.print(mProcessList.getMemLevel(adj)/1024);
11432        pw.println(" kB)");
11433    }
11434
11435    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11436            int opti, boolean dumpAll) {
11437        boolean needSep = false;
11438
11439        if (mLruProcesses.size() > 0) {
11440            if (needSep) pw.println();
11441            needSep = true;
11442            pw.println("  OOM levels:");
11443            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11444            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11445            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11446            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11447            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11448            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11449            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11450            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11451            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11452            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11453            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11454            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11455            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11456
11457            if (needSep) pw.println();
11458            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11459                    pw.print(" total, non-act at ");
11460                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11461                    pw.print(", non-svc at ");
11462                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11463                    pw.println("):");
11464            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11465            needSep = true;
11466        }
11467
11468        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11469
11470        pw.println();
11471        pw.println("  mHomeProcess: " + mHomeProcess);
11472        pw.println("  mPreviousProcess: " + mPreviousProcess);
11473        if (mHeavyWeightProcess != null) {
11474            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11475        }
11476
11477        return true;
11478    }
11479
11480    /**
11481     * There are three ways to call this:
11482     *  - no provider specified: dump all the providers
11483     *  - a flattened component name that matched an existing provider was specified as the
11484     *    first arg: dump that one provider
11485     *  - the first arg isn't the flattened component name of an existing provider:
11486     *    dump all providers whose component contains the first arg as a substring
11487     */
11488    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11489            int opti, boolean dumpAll) {
11490        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11491    }
11492
11493    static class ItemMatcher {
11494        ArrayList<ComponentName> components;
11495        ArrayList<String> strings;
11496        ArrayList<Integer> objects;
11497        boolean all;
11498
11499        ItemMatcher() {
11500            all = true;
11501        }
11502
11503        void build(String name) {
11504            ComponentName componentName = ComponentName.unflattenFromString(name);
11505            if (componentName != null) {
11506                if (components == null) {
11507                    components = new ArrayList<ComponentName>();
11508                }
11509                components.add(componentName);
11510                all = false;
11511            } else {
11512                int objectId = 0;
11513                // Not a '/' separated full component name; maybe an object ID?
11514                try {
11515                    objectId = Integer.parseInt(name, 16);
11516                    if (objects == null) {
11517                        objects = new ArrayList<Integer>();
11518                    }
11519                    objects.add(objectId);
11520                    all = false;
11521                } catch (RuntimeException e) {
11522                    // Not an integer; just do string match.
11523                    if (strings == null) {
11524                        strings = new ArrayList<String>();
11525                    }
11526                    strings.add(name);
11527                    all = false;
11528                }
11529            }
11530        }
11531
11532        int build(String[] args, int opti) {
11533            for (; opti<args.length; opti++) {
11534                String name = args[opti];
11535                if ("--".equals(name)) {
11536                    return opti+1;
11537                }
11538                build(name);
11539            }
11540            return opti;
11541        }
11542
11543        boolean match(Object object, ComponentName comp) {
11544            if (all) {
11545                return true;
11546            }
11547            if (components != null) {
11548                for (int i=0; i<components.size(); i++) {
11549                    if (components.get(i).equals(comp)) {
11550                        return true;
11551                    }
11552                }
11553            }
11554            if (objects != null) {
11555                for (int i=0; i<objects.size(); i++) {
11556                    if (System.identityHashCode(object) == objects.get(i)) {
11557                        return true;
11558                    }
11559                }
11560            }
11561            if (strings != null) {
11562                String flat = comp.flattenToString();
11563                for (int i=0; i<strings.size(); i++) {
11564                    if (flat.contains(strings.get(i))) {
11565                        return true;
11566                    }
11567                }
11568            }
11569            return false;
11570        }
11571    }
11572
11573    /**
11574     * There are three things that cmd can be:
11575     *  - a flattened component name that matches an existing activity
11576     *  - the cmd arg isn't the flattened component name of an existing activity:
11577     *    dump all activity whose component contains the cmd as a substring
11578     *  - A hex number of the ActivityRecord object instance.
11579     */
11580    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11581            int opti, boolean dumpAll) {
11582        ArrayList<ActivityRecord> activities;
11583
11584        synchronized (this) {
11585            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11586        }
11587
11588        if (activities.size() <= 0) {
11589            return false;
11590        }
11591
11592        String[] newArgs = new String[args.length - opti];
11593        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11594
11595        TaskRecord lastTask = null;
11596        boolean needSep = false;
11597        for (int i=activities.size()-1; i>=0; i--) {
11598            ActivityRecord r = activities.get(i);
11599            if (needSep) {
11600                pw.println();
11601            }
11602            needSep = true;
11603            synchronized (this) {
11604                if (lastTask != r.task) {
11605                    lastTask = r.task;
11606                    pw.print("TASK "); pw.print(lastTask.affinity);
11607                            pw.print(" id="); pw.println(lastTask.taskId);
11608                    if (dumpAll) {
11609                        lastTask.dump(pw, "  ");
11610                    }
11611                }
11612            }
11613            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11614        }
11615        return true;
11616    }
11617
11618    /**
11619     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11620     * there is a thread associated with the activity.
11621     */
11622    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11623            final ActivityRecord r, String[] args, boolean dumpAll) {
11624        String innerPrefix = prefix + "  ";
11625        synchronized (this) {
11626            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11627                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11628                    pw.print(" pid=");
11629                    if (r.app != null) pw.println(r.app.pid);
11630                    else pw.println("(not running)");
11631            if (dumpAll) {
11632                r.dump(pw, innerPrefix);
11633            }
11634        }
11635        if (r.app != null && r.app.thread != null) {
11636            // flush anything that is already in the PrintWriter since the thread is going
11637            // to write to the file descriptor directly
11638            pw.flush();
11639            try {
11640                TransferPipe tp = new TransferPipe();
11641                try {
11642                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11643                            r.appToken, innerPrefix, args);
11644                    tp.go(fd);
11645                } finally {
11646                    tp.kill();
11647                }
11648            } catch (IOException e) {
11649                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11650            } catch (RemoteException e) {
11651                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11652            }
11653        }
11654    }
11655
11656    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11657            int opti, boolean dumpAll, String dumpPackage) {
11658        boolean needSep = false;
11659        boolean onlyHistory = false;
11660        boolean printedAnything = false;
11661
11662        if ("history".equals(dumpPackage)) {
11663            if (opti < args.length && "-s".equals(args[opti])) {
11664                dumpAll = false;
11665            }
11666            onlyHistory = true;
11667            dumpPackage = null;
11668        }
11669
11670        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11671        if (!onlyHistory && dumpAll) {
11672            if (mRegisteredReceivers.size() > 0) {
11673                boolean printed = false;
11674                Iterator it = mRegisteredReceivers.values().iterator();
11675                while (it.hasNext()) {
11676                    ReceiverList r = (ReceiverList)it.next();
11677                    if (dumpPackage != null && (r.app == null ||
11678                            !dumpPackage.equals(r.app.info.packageName))) {
11679                        continue;
11680                    }
11681                    if (!printed) {
11682                        pw.println("  Registered Receivers:");
11683                        needSep = true;
11684                        printed = true;
11685                        printedAnything = true;
11686                    }
11687                    pw.print("  * "); pw.println(r);
11688                    r.dump(pw, "    ");
11689                }
11690            }
11691
11692            if (mReceiverResolver.dump(pw, needSep ?
11693                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11694                    "    ", dumpPackage, false)) {
11695                needSep = true;
11696                printedAnything = true;
11697            }
11698        }
11699
11700        for (BroadcastQueue q : mBroadcastQueues) {
11701            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11702            printedAnything |= needSep;
11703        }
11704
11705        needSep = true;
11706
11707        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11708            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11709                if (needSep) {
11710                    pw.println();
11711                }
11712                needSep = true;
11713                printedAnything = true;
11714                pw.print("  Sticky broadcasts for user ");
11715                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11716                StringBuilder sb = new StringBuilder(128);
11717                for (Map.Entry<String, ArrayList<Intent>> ent
11718                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11719                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11720                    if (dumpAll) {
11721                        pw.println(":");
11722                        ArrayList<Intent> intents = ent.getValue();
11723                        final int N = intents.size();
11724                        for (int i=0; i<N; i++) {
11725                            sb.setLength(0);
11726                            sb.append("    Intent: ");
11727                            intents.get(i).toShortString(sb, false, true, false, false);
11728                            pw.println(sb.toString());
11729                            Bundle bundle = intents.get(i).getExtras();
11730                            if (bundle != null) {
11731                                pw.print("      ");
11732                                pw.println(bundle.toString());
11733                            }
11734                        }
11735                    } else {
11736                        pw.println("");
11737                    }
11738                }
11739            }
11740        }
11741
11742        if (!onlyHistory && dumpAll) {
11743            pw.println();
11744            for (BroadcastQueue queue : mBroadcastQueues) {
11745                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11746                        + queue.mBroadcastsScheduled);
11747            }
11748            pw.println("  mHandler:");
11749            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11750            needSep = true;
11751            printedAnything = true;
11752        }
11753
11754        if (!printedAnything) {
11755            pw.println("  (nothing)");
11756        }
11757    }
11758
11759    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11760            int opti, boolean dumpAll, String dumpPackage) {
11761        boolean needSep;
11762        boolean printedAnything = false;
11763
11764        ItemMatcher matcher = new ItemMatcher();
11765        matcher.build(args, opti);
11766
11767        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11768
11769        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11770        printedAnything |= needSep;
11771
11772        if (mLaunchingProviders.size() > 0) {
11773            boolean printed = false;
11774            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11775                ContentProviderRecord r = mLaunchingProviders.get(i);
11776                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11777                    continue;
11778                }
11779                if (!printed) {
11780                    if (needSep) pw.println();
11781                    needSep = true;
11782                    pw.println("  Launching content providers:");
11783                    printed = true;
11784                    printedAnything = true;
11785                }
11786                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11787                        pw.println(r);
11788            }
11789        }
11790
11791        if (mGrantedUriPermissions.size() > 0) {
11792            boolean printed = false;
11793            int dumpUid = -2;
11794            if (dumpPackage != null) {
11795                try {
11796                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11797                } catch (NameNotFoundException e) {
11798                    dumpUid = -1;
11799                }
11800            }
11801            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11802                int uid = mGrantedUriPermissions.keyAt(i);
11803                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11804                    continue;
11805                }
11806                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11807                if (!printed) {
11808                    if (needSep) pw.println();
11809                    needSep = true;
11810                    pw.println("  Granted Uri Permissions:");
11811                    printed = true;
11812                    printedAnything = true;
11813                }
11814                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11815                for (UriPermission perm : perms.values()) {
11816                    pw.print("    "); pw.println(perm);
11817                    if (dumpAll) {
11818                        perm.dump(pw, "      ");
11819                    }
11820                }
11821            }
11822        }
11823
11824        if (!printedAnything) {
11825            pw.println("  (nothing)");
11826        }
11827    }
11828
11829    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11830            int opti, boolean dumpAll, String dumpPackage) {
11831        boolean printed = false;
11832
11833        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11834
11835        if (mIntentSenderRecords.size() > 0) {
11836            Iterator<WeakReference<PendingIntentRecord>> it
11837                    = mIntentSenderRecords.values().iterator();
11838            while (it.hasNext()) {
11839                WeakReference<PendingIntentRecord> ref = it.next();
11840                PendingIntentRecord rec = ref != null ? ref.get(): null;
11841                if (dumpPackage != null && (rec == null
11842                        || !dumpPackage.equals(rec.key.packageName))) {
11843                    continue;
11844                }
11845                printed = true;
11846                if (rec != null) {
11847                    pw.print("  * "); pw.println(rec);
11848                    if (dumpAll) {
11849                        rec.dump(pw, "    ");
11850                    }
11851                } else {
11852                    pw.print("  * "); pw.println(ref);
11853                }
11854            }
11855        }
11856
11857        if (!printed) {
11858            pw.println("  (nothing)");
11859        }
11860    }
11861
11862    private static final int dumpProcessList(PrintWriter pw,
11863            ActivityManagerService service, List list,
11864            String prefix, String normalLabel, String persistentLabel,
11865            String dumpPackage) {
11866        int numPers = 0;
11867        final int N = list.size()-1;
11868        for (int i=N; i>=0; i--) {
11869            ProcessRecord r = (ProcessRecord)list.get(i);
11870            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11871                continue;
11872            }
11873            pw.println(String.format("%s%s #%2d: %s",
11874                    prefix, (r.persistent ? persistentLabel : normalLabel),
11875                    i, r.toString()));
11876            if (r.persistent) {
11877                numPers++;
11878            }
11879        }
11880        return numPers;
11881    }
11882
11883    private static final boolean dumpProcessOomList(PrintWriter pw,
11884            ActivityManagerService service, List<ProcessRecord> origList,
11885            String prefix, String normalLabel, String persistentLabel,
11886            boolean inclDetails, String dumpPackage) {
11887
11888        ArrayList<Pair<ProcessRecord, Integer>> list
11889                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11890        for (int i=0; i<origList.size(); i++) {
11891            ProcessRecord r = origList.get(i);
11892            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11893                continue;
11894            }
11895            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11896        }
11897
11898        if (list.size() <= 0) {
11899            return false;
11900        }
11901
11902        Comparator<Pair<ProcessRecord, Integer>> comparator
11903                = new Comparator<Pair<ProcessRecord, Integer>>() {
11904            @Override
11905            public int compare(Pair<ProcessRecord, Integer> object1,
11906                    Pair<ProcessRecord, Integer> object2) {
11907                if (object1.first.setAdj != object2.first.setAdj) {
11908                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11909                }
11910                if (object1.second.intValue() != object2.second.intValue()) {
11911                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11912                }
11913                return 0;
11914            }
11915        };
11916
11917        Collections.sort(list, comparator);
11918
11919        final long curRealtime = SystemClock.elapsedRealtime();
11920        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11921        final long curUptime = SystemClock.uptimeMillis();
11922        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11923
11924        for (int i=list.size()-1; i>=0; i--) {
11925            ProcessRecord r = list.get(i).first;
11926            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11927            char schedGroup;
11928            switch (r.setSchedGroup) {
11929                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11930                    schedGroup = 'B';
11931                    break;
11932                case Process.THREAD_GROUP_DEFAULT:
11933                    schedGroup = 'F';
11934                    break;
11935                default:
11936                    schedGroup = '?';
11937                    break;
11938            }
11939            char foreground;
11940            if (r.foregroundActivities) {
11941                foreground = 'A';
11942            } else if (r.foregroundServices) {
11943                foreground = 'S';
11944            } else {
11945                foreground = ' ';
11946            }
11947            String procState = ProcessList.makeProcStateString(r.curProcState);
11948            pw.print(prefix);
11949            pw.print(r.persistent ? persistentLabel : normalLabel);
11950            pw.print(" #");
11951            int num = (origList.size()-1)-list.get(i).second;
11952            if (num < 10) pw.print(' ');
11953            pw.print(num);
11954            pw.print(": ");
11955            pw.print(oomAdj);
11956            pw.print(' ');
11957            pw.print(schedGroup);
11958            pw.print('/');
11959            pw.print(foreground);
11960            pw.print('/');
11961            pw.print(procState);
11962            pw.print(" trm:");
11963            if (r.trimMemoryLevel < 10) pw.print(' ');
11964            pw.print(r.trimMemoryLevel);
11965            pw.print(' ');
11966            pw.print(r.toShortString());
11967            pw.print(" (");
11968            pw.print(r.adjType);
11969            pw.println(')');
11970            if (r.adjSource != null || r.adjTarget != null) {
11971                pw.print(prefix);
11972                pw.print("    ");
11973                if (r.adjTarget instanceof ComponentName) {
11974                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11975                } else if (r.adjTarget != null) {
11976                    pw.print(r.adjTarget.toString());
11977                } else {
11978                    pw.print("{null}");
11979                }
11980                pw.print("<=");
11981                if (r.adjSource instanceof ProcessRecord) {
11982                    pw.print("Proc{");
11983                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11984                    pw.println("}");
11985                } else if (r.adjSource != null) {
11986                    pw.println(r.adjSource.toString());
11987                } else {
11988                    pw.println("{null}");
11989                }
11990            }
11991            if (inclDetails) {
11992                pw.print(prefix);
11993                pw.print("    ");
11994                pw.print("oom: max="); pw.print(r.maxAdj);
11995                pw.print(" curRaw="); pw.print(r.curRawAdj);
11996                pw.print(" setRaw="); pw.print(r.setRawAdj);
11997                pw.print(" cur="); pw.print(r.curAdj);
11998                pw.print(" set="); pw.println(r.setAdj);
11999                pw.print(prefix);
12000                pw.print("    ");
12001                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12002                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12003                pw.print(" lastPss="); pw.print(r.lastPss);
12004                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12005                pw.print(prefix);
12006                pw.print("    ");
12007                pw.print("keeping="); pw.print(r.keeping);
12008                pw.print(" cached="); pw.print(r.cached);
12009                pw.print(" empty="); pw.print(r.empty);
12010                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12011
12012                if (!r.keeping) {
12013                    if (r.lastWakeTime != 0) {
12014                        long wtime;
12015                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12016                        synchronized (stats) {
12017                            wtime = stats.getProcessWakeTime(r.info.uid,
12018                                    r.pid, curRealtime);
12019                        }
12020                        long timeUsed = wtime - r.lastWakeTime;
12021                        pw.print(prefix);
12022                        pw.print("    ");
12023                        pw.print("keep awake over ");
12024                        TimeUtils.formatDuration(realtimeSince, pw);
12025                        pw.print(" used ");
12026                        TimeUtils.formatDuration(timeUsed, pw);
12027                        pw.print(" (");
12028                        pw.print((timeUsed*100)/realtimeSince);
12029                        pw.println("%)");
12030                    }
12031                    if (r.lastCpuTime != 0) {
12032                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12033                        pw.print(prefix);
12034                        pw.print("    ");
12035                        pw.print("run cpu over ");
12036                        TimeUtils.formatDuration(uptimeSince, pw);
12037                        pw.print(" used ");
12038                        TimeUtils.formatDuration(timeUsed, pw);
12039                        pw.print(" (");
12040                        pw.print((timeUsed*100)/uptimeSince);
12041                        pw.println("%)");
12042                    }
12043                }
12044            }
12045        }
12046        return true;
12047    }
12048
12049    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12050        ArrayList<ProcessRecord> procs;
12051        synchronized (this) {
12052            if (args != null && args.length > start
12053                    && args[start].charAt(0) != '-') {
12054                procs = new ArrayList<ProcessRecord>();
12055                int pid = -1;
12056                try {
12057                    pid = Integer.parseInt(args[start]);
12058                } catch (NumberFormatException e) {
12059                }
12060                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12061                    ProcessRecord proc = mLruProcesses.get(i);
12062                    if (proc.pid == pid) {
12063                        procs.add(proc);
12064                    } else if (proc.processName.equals(args[start])) {
12065                        procs.add(proc);
12066                    }
12067                }
12068                if (procs.size() <= 0) {
12069                    return null;
12070                }
12071            } else {
12072                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12073            }
12074        }
12075        return procs;
12076    }
12077
12078    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12079            PrintWriter pw, String[] args) {
12080        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12081        if (procs == null) {
12082            pw.println("No process found for: " + args[0]);
12083            return;
12084        }
12085
12086        long uptime = SystemClock.uptimeMillis();
12087        long realtime = SystemClock.elapsedRealtime();
12088        pw.println("Applications Graphics Acceleration Info:");
12089        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12090
12091        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12092            ProcessRecord r = procs.get(i);
12093            if (r.thread != null) {
12094                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12095                pw.flush();
12096                try {
12097                    TransferPipe tp = new TransferPipe();
12098                    try {
12099                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12100                        tp.go(fd);
12101                    } finally {
12102                        tp.kill();
12103                    }
12104                } catch (IOException e) {
12105                    pw.println("Failure while dumping the app: " + r);
12106                    pw.flush();
12107                } catch (RemoteException e) {
12108                    pw.println("Got a RemoteException while dumping the app " + r);
12109                    pw.flush();
12110                }
12111            }
12112        }
12113    }
12114
12115    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12116        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12117        if (procs == null) {
12118            pw.println("No process found for: " + args[0]);
12119            return;
12120        }
12121
12122        pw.println("Applications Database Info:");
12123
12124        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12125            ProcessRecord r = procs.get(i);
12126            if (r.thread != null) {
12127                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12128                pw.flush();
12129                try {
12130                    TransferPipe tp = new TransferPipe();
12131                    try {
12132                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12133                        tp.go(fd);
12134                    } finally {
12135                        tp.kill();
12136                    }
12137                } catch (IOException e) {
12138                    pw.println("Failure while dumping the app: " + r);
12139                    pw.flush();
12140                } catch (RemoteException e) {
12141                    pw.println("Got a RemoteException while dumping the app " + r);
12142                    pw.flush();
12143                }
12144            }
12145        }
12146    }
12147
12148    final static class MemItem {
12149        final boolean isProc;
12150        final String label;
12151        final String shortLabel;
12152        final long pss;
12153        final int id;
12154        final boolean hasActivities;
12155        ArrayList<MemItem> subitems;
12156
12157        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12158                boolean _hasActivities) {
12159            isProc = true;
12160            label = _label;
12161            shortLabel = _shortLabel;
12162            pss = _pss;
12163            id = _id;
12164            hasActivities = _hasActivities;
12165        }
12166
12167        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12168            isProc = false;
12169            label = _label;
12170            shortLabel = _shortLabel;
12171            pss = _pss;
12172            id = _id;
12173            hasActivities = false;
12174        }
12175    }
12176
12177    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12178            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12179        if (sort && !isCompact) {
12180            Collections.sort(items, new Comparator<MemItem>() {
12181                @Override
12182                public int compare(MemItem lhs, MemItem rhs) {
12183                    if (lhs.pss < rhs.pss) {
12184                        return 1;
12185                    } else if (lhs.pss > rhs.pss) {
12186                        return -1;
12187                    }
12188                    return 0;
12189                }
12190            });
12191        }
12192
12193        for (int i=0; i<items.size(); i++) {
12194            MemItem mi = items.get(i);
12195            if (!isCompact) {
12196                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12197            } else if (mi.isProc) {
12198                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12199                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12200                pw.println(mi.hasActivities ? ",a" : ",e");
12201            } else {
12202                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12203                pw.println(mi.pss);
12204            }
12205            if (mi.subitems != null) {
12206                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12207                        true, isCompact);
12208            }
12209        }
12210    }
12211
12212    // These are in KB.
12213    static final long[] DUMP_MEM_BUCKETS = new long[] {
12214        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12215        120*1024, 160*1024, 200*1024,
12216        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12217        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12218    };
12219
12220    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12221            boolean stackLike) {
12222        int start = label.lastIndexOf('.');
12223        if (start >= 0) start++;
12224        else start = 0;
12225        int end = label.length();
12226        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12227            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12228                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12229                out.append(bucket);
12230                out.append(stackLike ? "MB." : "MB ");
12231                out.append(label, start, end);
12232                return;
12233            }
12234        }
12235        out.append(memKB/1024);
12236        out.append(stackLike ? "MB." : "MB ");
12237        out.append(label, start, end);
12238    }
12239
12240    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12241            ProcessList.NATIVE_ADJ,
12242            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12243            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12244            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12245            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12246            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12247    };
12248    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12249            "Native",
12250            "System", "Persistent", "Foreground",
12251            "Visible", "Perceptible",
12252            "Heavy Weight", "Backup",
12253            "A Services", "Home",
12254            "Previous", "B Services", "Cached"
12255    };
12256    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12257            "native",
12258            "sys", "pers", "fore",
12259            "vis", "percept",
12260            "heavy", "backup",
12261            "servicea", "home",
12262            "prev", "serviceb", "cached"
12263    };
12264
12265    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12266            long realtime, boolean isCheckinRequest, boolean isCompact) {
12267        if (isCheckinRequest || isCompact) {
12268            // short checkin version
12269            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12270        } else {
12271            pw.println("Applications Memory Usage (kB):");
12272            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12273        }
12274    }
12275
12276    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12277            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12278        boolean dumpDetails = false;
12279        boolean dumpFullDetails = false;
12280        boolean dumpDalvik = false;
12281        boolean oomOnly = false;
12282        boolean isCompact = false;
12283        boolean localOnly = false;
12284
12285        int opti = 0;
12286        while (opti < args.length) {
12287            String opt = args[opti];
12288            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12289                break;
12290            }
12291            opti++;
12292            if ("-a".equals(opt)) {
12293                dumpDetails = true;
12294                dumpFullDetails = true;
12295                dumpDalvik = true;
12296            } else if ("-d".equals(opt)) {
12297                dumpDalvik = true;
12298            } else if ("-c".equals(opt)) {
12299                isCompact = true;
12300            } else if ("--oom".equals(opt)) {
12301                oomOnly = true;
12302            } else if ("--local".equals(opt)) {
12303                localOnly = true;
12304            } else if ("-h".equals(opt)) {
12305                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12306                pw.println("  -a: include all available information for each process.");
12307                pw.println("  -d: include dalvik details when dumping process details.");
12308                pw.println("  -c: dump in a compact machine-parseable representation.");
12309                pw.println("  --oom: only show processes organized by oom adj.");
12310                pw.println("  --local: only collect details locally, don't call process.");
12311                pw.println("If [process] is specified it can be the name or ");
12312                pw.println("pid of a specific process to dump.");
12313                return;
12314            } else {
12315                pw.println("Unknown argument: " + opt + "; use -h for help");
12316            }
12317        }
12318
12319        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12320        long uptime = SystemClock.uptimeMillis();
12321        long realtime = SystemClock.elapsedRealtime();
12322        final long[] tmpLong = new long[1];
12323
12324        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12325        if (procs == null) {
12326            // No Java processes.  Maybe they want to print a native process.
12327            if (args != null && args.length > opti
12328                    && args[opti].charAt(0) != '-') {
12329                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12330                        = new ArrayList<ProcessCpuTracker.Stats>();
12331                updateCpuStatsNow();
12332                int findPid = -1;
12333                try {
12334                    findPid = Integer.parseInt(args[opti]);
12335                } catch (NumberFormatException e) {
12336                }
12337                synchronized (mProcessCpuThread) {
12338                    final int N = mProcessCpuTracker.countStats();
12339                    for (int i=0; i<N; i++) {
12340                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12341                        if (st.pid == findPid || (st.baseName != null
12342                                && st.baseName.equals(args[opti]))) {
12343                            nativeProcs.add(st);
12344                        }
12345                    }
12346                }
12347                if (nativeProcs.size() > 0) {
12348                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12349                            isCompact);
12350                    Debug.MemoryInfo mi = null;
12351                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12352                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12353                        final int pid = r.pid;
12354                        if (!isCheckinRequest && dumpDetails) {
12355                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12356                        }
12357                        if (mi == null) {
12358                            mi = new Debug.MemoryInfo();
12359                        }
12360                        if (dumpDetails || (!brief && !oomOnly)) {
12361                            Debug.getMemoryInfo(pid, mi);
12362                        } else {
12363                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12364                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12365                        }
12366                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12367                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12368                        if (isCheckinRequest) {
12369                            pw.println();
12370                        }
12371                    }
12372                    return;
12373                }
12374            }
12375            pw.println("No process found for: " + args[opti]);
12376            return;
12377        }
12378
12379        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12380            dumpDetails = true;
12381        }
12382
12383        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12384
12385        String[] innerArgs = new String[args.length-opti];
12386        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12387
12388        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12389        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12390        long nativePss=0, dalvikPss=0, otherPss=0;
12391        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12392
12393        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12394        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12395                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12396
12397        long totalPss = 0;
12398        long cachedPss = 0;
12399
12400        Debug.MemoryInfo mi = null;
12401        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12402            final ProcessRecord r = procs.get(i);
12403            final IApplicationThread thread;
12404            final int pid;
12405            final int oomAdj;
12406            final boolean hasActivities;
12407            synchronized (this) {
12408                thread = r.thread;
12409                pid = r.pid;
12410                oomAdj = r.getSetAdjWithServices();
12411                hasActivities = r.activities.size() > 0;
12412            }
12413            if (thread != null) {
12414                if (!isCheckinRequest && dumpDetails) {
12415                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12416                }
12417                if (mi == null) {
12418                    mi = new Debug.MemoryInfo();
12419                }
12420                if (dumpDetails || (!brief && !oomOnly)) {
12421                    Debug.getMemoryInfo(pid, mi);
12422                } else {
12423                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12424                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12425                }
12426                if (dumpDetails) {
12427                    if (localOnly) {
12428                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12429                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12430                        if (isCheckinRequest) {
12431                            pw.println();
12432                        }
12433                    } else {
12434                        try {
12435                            pw.flush();
12436                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12437                                    dumpDalvik, innerArgs);
12438                        } catch (RemoteException e) {
12439                            if (!isCheckinRequest) {
12440                                pw.println("Got RemoteException!");
12441                                pw.flush();
12442                            }
12443                        }
12444                    }
12445                }
12446
12447                final long myTotalPss = mi.getTotalPss();
12448                final long myTotalUss = mi.getTotalUss();
12449
12450                synchronized (this) {
12451                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12452                        // Record this for posterity if the process has been stable.
12453                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12454                    }
12455                }
12456
12457                if (!isCheckinRequest && mi != null) {
12458                    totalPss += myTotalPss;
12459                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12460                            (hasActivities ? " / activities)" : ")"),
12461                            r.processName, myTotalPss, pid, hasActivities);
12462                    procMems.add(pssItem);
12463                    procMemsMap.put(pid, pssItem);
12464
12465                    nativePss += mi.nativePss;
12466                    dalvikPss += mi.dalvikPss;
12467                    otherPss += mi.otherPss;
12468                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12469                        long mem = mi.getOtherPss(j);
12470                        miscPss[j] += mem;
12471                        otherPss -= mem;
12472                    }
12473
12474                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12475                        cachedPss += myTotalPss;
12476                    }
12477
12478                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12479                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12480                                || oomIndex == (oomPss.length-1)) {
12481                            oomPss[oomIndex] += myTotalPss;
12482                            if (oomProcs[oomIndex] == null) {
12483                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12484                            }
12485                            oomProcs[oomIndex].add(pssItem);
12486                            break;
12487                        }
12488                    }
12489                }
12490            }
12491        }
12492
12493        if (!isCheckinRequest && procs.size() > 1) {
12494            // If we are showing aggregations, also look for native processes to
12495            // include so that our aggregations are more accurate.
12496            updateCpuStatsNow();
12497            synchronized (mProcessCpuThread) {
12498                final int N = mProcessCpuTracker.countStats();
12499                for (int i=0; i<N; i++) {
12500                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12501                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12502                        if (mi == null) {
12503                            mi = new Debug.MemoryInfo();
12504                        }
12505                        if (!brief && !oomOnly) {
12506                            Debug.getMemoryInfo(st.pid, mi);
12507                        } else {
12508                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12509                            mi.nativePrivateDirty = (int)tmpLong[0];
12510                        }
12511
12512                        final long myTotalPss = mi.getTotalPss();
12513                        totalPss += myTotalPss;
12514
12515                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12516                                st.name, myTotalPss, st.pid, false);
12517                        procMems.add(pssItem);
12518
12519                        nativePss += mi.nativePss;
12520                        dalvikPss += mi.dalvikPss;
12521                        otherPss += mi.otherPss;
12522                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12523                            long mem = mi.getOtherPss(j);
12524                            miscPss[j] += mem;
12525                            otherPss -= mem;
12526                        }
12527                        oomPss[0] += myTotalPss;
12528                        if (oomProcs[0] == null) {
12529                            oomProcs[0] = new ArrayList<MemItem>();
12530                        }
12531                        oomProcs[0].add(pssItem);
12532                    }
12533                }
12534            }
12535
12536            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12537
12538            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12539            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12540            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12541            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12542                String label = Debug.MemoryInfo.getOtherLabel(j);
12543                catMems.add(new MemItem(label, label, miscPss[j], j));
12544            }
12545
12546            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12547            for (int j=0; j<oomPss.length; j++) {
12548                if (oomPss[j] != 0) {
12549                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12550                            : DUMP_MEM_OOM_LABEL[j];
12551                    MemItem item = new MemItem(label, label, oomPss[j],
12552                            DUMP_MEM_OOM_ADJ[j]);
12553                    item.subitems = oomProcs[j];
12554                    oomMems.add(item);
12555                }
12556            }
12557
12558            if (!brief && !oomOnly && !isCompact) {
12559                pw.println();
12560                pw.println("Total PSS by process:");
12561                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12562                pw.println();
12563            }
12564            if (!isCompact) {
12565                pw.println("Total PSS by OOM adjustment:");
12566            }
12567            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12568            if (!brief && !oomOnly) {
12569                PrintWriter out = categoryPw != null ? categoryPw : pw;
12570                if (!isCompact) {
12571                    out.println();
12572                    out.println("Total PSS by category:");
12573                }
12574                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12575            }
12576            if (!isCompact) {
12577                pw.println();
12578            }
12579            MemInfoReader memInfo = new MemInfoReader();
12580            memInfo.readMemInfo();
12581            if (!brief) {
12582                if (!isCompact) {
12583                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12584                    pw.print(" kB (status ");
12585                    switch (mLastMemoryLevel) {
12586                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12587                            pw.println("normal)");
12588                            break;
12589                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12590                            pw.println("moderate)");
12591                            break;
12592                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12593                            pw.println("low)");
12594                            break;
12595                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12596                            pw.println("critical)");
12597                            break;
12598                        default:
12599                            pw.print(mLastMemoryLevel);
12600                            pw.println(")");
12601                            break;
12602                    }
12603                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12604                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12605                            pw.print(cachedPss); pw.print(" cached pss + ");
12606                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12607                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12608                } else {
12609                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12610                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12611                            + memInfo.getFreeSizeKb()); pw.print(",");
12612                    pw.println(totalPss - cachedPss);
12613                }
12614            }
12615            if (!isCompact) {
12616                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12617                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12618                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12619                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12620                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12621                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12622                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12623                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12624                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12625                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12626                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12627            }
12628            if (!brief) {
12629                if (memInfo.getZramTotalSizeKb() != 0) {
12630                    if (!isCompact) {
12631                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12632                                pw.print(" kB physical used for ");
12633                                pw.print(memInfo.getSwapTotalSizeKb()
12634                                        - memInfo.getSwapFreeSizeKb());
12635                                pw.print(" kB in swap (");
12636                                pw.print(memInfo.getSwapTotalSizeKb());
12637                                pw.println(" kB total swap)");
12638                    } else {
12639                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12640                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12641                                pw.println(memInfo.getSwapFreeSizeKb());
12642                    }
12643                }
12644                final int[] SINGLE_LONG_FORMAT = new int[] {
12645                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12646                };
12647                long[] longOut = new long[1];
12648                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12649                        SINGLE_LONG_FORMAT, null, longOut, null);
12650                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12651                longOut[0] = 0;
12652                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12653                        SINGLE_LONG_FORMAT, null, longOut, null);
12654                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12655                longOut[0] = 0;
12656                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12657                        SINGLE_LONG_FORMAT, null, longOut, null);
12658                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12659                longOut[0] = 0;
12660                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12661                        SINGLE_LONG_FORMAT, null, longOut, null);
12662                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12663                if (!isCompact) {
12664                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12665                        pw.print("      KSM: "); pw.print(sharing);
12666                                pw.print(" kB saved from shared ");
12667                                pw.print(shared); pw.println(" kB");
12668                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12669                                pw.print(voltile); pw.println(" kB volatile");
12670                    }
12671                    pw.print("   Tuning: ");
12672                    pw.print(ActivityManager.staticGetMemoryClass());
12673                    pw.print(" (large ");
12674                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12675                    pw.print("), oom ");
12676                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12677                    pw.print(" kB");
12678                    pw.print(", restore limit ");
12679                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12680                    pw.print(" kB");
12681                    if (ActivityManager.isLowRamDeviceStatic()) {
12682                        pw.print(" (low-ram)");
12683                    }
12684                    if (ActivityManager.isHighEndGfx()) {
12685                        pw.print(" (high-end-gfx)");
12686                    }
12687                    pw.println();
12688                } else {
12689                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12690                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12691                    pw.println(voltile);
12692                    pw.print("tuning,");
12693                    pw.print(ActivityManager.staticGetMemoryClass());
12694                    pw.print(',');
12695                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12696                    pw.print(',');
12697                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12698                    if (ActivityManager.isLowRamDeviceStatic()) {
12699                        pw.print(",low-ram");
12700                    }
12701                    if (ActivityManager.isHighEndGfx()) {
12702                        pw.print(",high-end-gfx");
12703                    }
12704                    pw.println();
12705                }
12706            }
12707        }
12708    }
12709
12710    /**
12711     * Searches array of arguments for the specified string
12712     * @param args array of argument strings
12713     * @param value value to search for
12714     * @return true if the value is contained in the array
12715     */
12716    private static boolean scanArgs(String[] args, String value) {
12717        if (args != null) {
12718            for (String arg : args) {
12719                if (value.equals(arg)) {
12720                    return true;
12721                }
12722            }
12723        }
12724        return false;
12725    }
12726
12727    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12728            ContentProviderRecord cpr, boolean always) {
12729        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12730
12731        if (!inLaunching || always) {
12732            synchronized (cpr) {
12733                cpr.launchingApp = null;
12734                cpr.notifyAll();
12735            }
12736            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12737            String names[] = cpr.info.authority.split(";");
12738            for (int j = 0; j < names.length; j++) {
12739                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12740            }
12741        }
12742
12743        for (int i=0; i<cpr.connections.size(); i++) {
12744            ContentProviderConnection conn = cpr.connections.get(i);
12745            if (conn.waiting) {
12746                // If this connection is waiting for the provider, then we don't
12747                // need to mess with its process unless we are always removing
12748                // or for some reason the provider is not currently launching.
12749                if (inLaunching && !always) {
12750                    continue;
12751                }
12752            }
12753            ProcessRecord capp = conn.client;
12754            conn.dead = true;
12755            if (conn.stableCount > 0) {
12756                if (!capp.persistent && capp.thread != null
12757                        && capp.pid != 0
12758                        && capp.pid != MY_PID) {
12759                    killUnneededProcessLocked(capp, "depends on provider "
12760                            + cpr.name.flattenToShortString()
12761                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12762                }
12763            } else if (capp.thread != null && conn.provider.provider != null) {
12764                try {
12765                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12766                } catch (RemoteException e) {
12767                }
12768                // In the protocol here, we don't expect the client to correctly
12769                // clean up this connection, we'll just remove it.
12770                cpr.connections.remove(i);
12771                conn.client.conProviders.remove(conn);
12772            }
12773        }
12774
12775        if (inLaunching && always) {
12776            mLaunchingProviders.remove(cpr);
12777        }
12778        return inLaunching;
12779    }
12780
12781    /**
12782     * Main code for cleaning up a process when it has gone away.  This is
12783     * called both as a result of the process dying, or directly when stopping
12784     * a process when running in single process mode.
12785     */
12786    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12787            boolean restarting, boolean allowRestart, int index) {
12788        if (index >= 0) {
12789            removeLruProcessLocked(app);
12790            ProcessList.remove(app.pid);
12791        }
12792
12793        mProcessesToGc.remove(app);
12794        mPendingPssProcesses.remove(app);
12795
12796        // Dismiss any open dialogs.
12797        if (app.crashDialog != null && !app.forceCrashReport) {
12798            app.crashDialog.dismiss();
12799            app.crashDialog = null;
12800        }
12801        if (app.anrDialog != null) {
12802            app.anrDialog.dismiss();
12803            app.anrDialog = null;
12804        }
12805        if (app.waitDialog != null) {
12806            app.waitDialog.dismiss();
12807            app.waitDialog = null;
12808        }
12809
12810        app.crashing = false;
12811        app.notResponding = false;
12812
12813        app.resetPackageList(mProcessStats);
12814        app.unlinkDeathRecipient();
12815        app.makeInactive(mProcessStats);
12816        app.forcingToForeground = null;
12817        updateProcessForegroundLocked(app, false, false);
12818        app.foregroundActivities = false;
12819        app.hasShownUi = false;
12820        app.treatLikeActivity = false;
12821        app.hasAboveClient = false;
12822        app.hasClientActivities = false;
12823
12824        mServices.killServicesLocked(app, allowRestart);
12825
12826        boolean restart = false;
12827
12828        // Remove published content providers.
12829        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12830            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12831            final boolean always = app.bad || !allowRestart;
12832            if (removeDyingProviderLocked(app, cpr, always) || always) {
12833                // We left the provider in the launching list, need to
12834                // restart it.
12835                restart = true;
12836            }
12837
12838            cpr.provider = null;
12839            cpr.proc = null;
12840        }
12841        app.pubProviders.clear();
12842
12843        // Take care of any launching providers waiting for this process.
12844        if (checkAppInLaunchingProvidersLocked(app, false)) {
12845            restart = true;
12846        }
12847
12848        // Unregister from connected content providers.
12849        if (!app.conProviders.isEmpty()) {
12850            for (int i=0; i<app.conProviders.size(); i++) {
12851                ContentProviderConnection conn = app.conProviders.get(i);
12852                conn.provider.connections.remove(conn);
12853            }
12854            app.conProviders.clear();
12855        }
12856
12857        // At this point there may be remaining entries in mLaunchingProviders
12858        // where we were the only one waiting, so they are no longer of use.
12859        // Look for these and clean up if found.
12860        // XXX Commented out for now.  Trying to figure out a way to reproduce
12861        // the actual situation to identify what is actually going on.
12862        if (false) {
12863            for (int i=0; i<mLaunchingProviders.size(); i++) {
12864                ContentProviderRecord cpr = (ContentProviderRecord)
12865                        mLaunchingProviders.get(i);
12866                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12867                    synchronized (cpr) {
12868                        cpr.launchingApp = null;
12869                        cpr.notifyAll();
12870                    }
12871                }
12872            }
12873        }
12874
12875        skipCurrentReceiverLocked(app);
12876
12877        // Unregister any receivers.
12878        for (int i=app.receivers.size()-1; i>=0; i--) {
12879            removeReceiverLocked(app.receivers.valueAt(i));
12880        }
12881        app.receivers.clear();
12882
12883        // If the app is undergoing backup, tell the backup manager about it
12884        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12885            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12886                    + mBackupTarget.appInfo + " died during backup");
12887            try {
12888                IBackupManager bm = IBackupManager.Stub.asInterface(
12889                        ServiceManager.getService(Context.BACKUP_SERVICE));
12890                bm.agentDisconnected(app.info.packageName);
12891            } catch (RemoteException e) {
12892                // can't happen; backup manager is local
12893            }
12894        }
12895
12896        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12897            ProcessChangeItem item = mPendingProcessChanges.get(i);
12898            if (item.pid == app.pid) {
12899                mPendingProcessChanges.remove(i);
12900                mAvailProcessChanges.add(item);
12901            }
12902        }
12903        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12904
12905        // If the caller is restarting this app, then leave it in its
12906        // current lists and let the caller take care of it.
12907        if (restarting) {
12908            return;
12909        }
12910
12911        if (!app.persistent || app.isolated) {
12912            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12913                    "Removing non-persistent process during cleanup: " + app);
12914            mProcessNames.remove(app.processName, app.uid);
12915            mIsolatedProcesses.remove(app.uid);
12916            if (mHeavyWeightProcess == app) {
12917                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12918                        mHeavyWeightProcess.userId, 0));
12919                mHeavyWeightProcess = null;
12920            }
12921        } else if (!app.removed) {
12922            // This app is persistent, so we need to keep its record around.
12923            // If it is not already on the pending app list, add it there
12924            // and start a new process for it.
12925            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12926                mPersistentStartingProcesses.add(app);
12927                restart = true;
12928            }
12929        }
12930        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12931                "Clean-up removing on hold: " + app);
12932        mProcessesOnHold.remove(app);
12933
12934        if (app == mHomeProcess) {
12935            mHomeProcess = null;
12936        }
12937        if (app == mPreviousProcess) {
12938            mPreviousProcess = null;
12939        }
12940
12941        if (restart && !app.isolated) {
12942            // We have components that still need to be running in the
12943            // process, so re-launch it.
12944            mProcessNames.put(app.processName, app.uid, app);
12945            startProcessLocked(app, "restart", app.processName);
12946        } else if (app.pid > 0 && app.pid != MY_PID) {
12947            // Goodbye!
12948            boolean removed;
12949            synchronized (mPidsSelfLocked) {
12950                mPidsSelfLocked.remove(app.pid);
12951                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12952            }
12953            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12954                    app.processName, app.info.uid);
12955            if (app.isolated) {
12956                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12957            }
12958            app.setPid(0);
12959        }
12960    }
12961
12962    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12963        // Look through the content providers we are waiting to have launched,
12964        // and if any run in this process then either schedule a restart of
12965        // the process or kill the client waiting for it if this process has
12966        // gone bad.
12967        int NL = mLaunchingProviders.size();
12968        boolean restart = false;
12969        for (int i=0; i<NL; i++) {
12970            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12971            if (cpr.launchingApp == app) {
12972                if (!alwaysBad && !app.bad) {
12973                    restart = true;
12974                } else {
12975                    removeDyingProviderLocked(app, cpr, true);
12976                    // cpr should have been removed from mLaunchingProviders
12977                    NL = mLaunchingProviders.size();
12978                    i--;
12979                }
12980            }
12981        }
12982        return restart;
12983    }
12984
12985    // =========================================================
12986    // SERVICES
12987    // =========================================================
12988
12989    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12990            int flags) {
12991        enforceNotIsolatedCaller("getServices");
12992        synchronized (this) {
12993            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12994        }
12995    }
12996
12997    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12998        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12999        synchronized (this) {
13000            return mServices.getRunningServiceControlPanelLocked(name);
13001        }
13002    }
13003
13004    public ComponentName startService(IApplicationThread caller, Intent service,
13005            String resolvedType, int userId) {
13006        enforceNotIsolatedCaller("startService");
13007        // Refuse possible leaked file descriptors
13008        if (service != null && service.hasFileDescriptors() == true) {
13009            throw new IllegalArgumentException("File descriptors passed in Intent");
13010        }
13011
13012        if (DEBUG_SERVICE)
13013            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13014        synchronized(this) {
13015            final int callingPid = Binder.getCallingPid();
13016            final int callingUid = Binder.getCallingUid();
13017            final long origId = Binder.clearCallingIdentity();
13018            ComponentName res = mServices.startServiceLocked(caller, service,
13019                    resolvedType, callingPid, callingUid, userId);
13020            Binder.restoreCallingIdentity(origId);
13021            return res;
13022        }
13023    }
13024
13025    ComponentName startServiceInPackage(int uid,
13026            Intent service, String resolvedType, int userId) {
13027        synchronized(this) {
13028            if (DEBUG_SERVICE)
13029                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13030            final long origId = Binder.clearCallingIdentity();
13031            ComponentName res = mServices.startServiceLocked(null, service,
13032                    resolvedType, -1, uid, userId);
13033            Binder.restoreCallingIdentity(origId);
13034            return res;
13035        }
13036    }
13037
13038    public int stopService(IApplicationThread caller, Intent service,
13039            String resolvedType, int userId) {
13040        enforceNotIsolatedCaller("stopService");
13041        // Refuse possible leaked file descriptors
13042        if (service != null && service.hasFileDescriptors() == true) {
13043            throw new IllegalArgumentException("File descriptors passed in Intent");
13044        }
13045
13046        synchronized(this) {
13047            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13048        }
13049    }
13050
13051    public IBinder peekService(Intent service, String resolvedType) {
13052        enforceNotIsolatedCaller("peekService");
13053        // Refuse possible leaked file descriptors
13054        if (service != null && service.hasFileDescriptors() == true) {
13055            throw new IllegalArgumentException("File descriptors passed in Intent");
13056        }
13057        synchronized(this) {
13058            return mServices.peekServiceLocked(service, resolvedType);
13059        }
13060    }
13061
13062    public boolean stopServiceToken(ComponentName className, IBinder token,
13063            int startId) {
13064        synchronized(this) {
13065            return mServices.stopServiceTokenLocked(className, token, startId);
13066        }
13067    }
13068
13069    public void setServiceForeground(ComponentName className, IBinder token,
13070            int id, Notification notification, boolean removeNotification) {
13071        synchronized(this) {
13072            mServices.setServiceForegroundLocked(className, token, id, notification,
13073                    removeNotification);
13074        }
13075    }
13076
13077    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13078            boolean requireFull, String name, String callerPackage) {
13079        final int callingUserId = UserHandle.getUserId(callingUid);
13080        if (callingUserId != userId) {
13081            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13082                if ((requireFull || checkComponentPermission(
13083                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13084                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13085                        && checkComponentPermission(
13086                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13087                                callingPid, callingUid, -1, true)
13088                                != PackageManager.PERMISSION_GRANTED) {
13089                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13090                        // In this case, they would like to just execute as their
13091                        // owner user instead of failing.
13092                        userId = callingUserId;
13093                    } else {
13094                        StringBuilder builder = new StringBuilder(128);
13095                        builder.append("Permission Denial: ");
13096                        builder.append(name);
13097                        if (callerPackage != null) {
13098                            builder.append(" from ");
13099                            builder.append(callerPackage);
13100                        }
13101                        builder.append(" asks to run as user ");
13102                        builder.append(userId);
13103                        builder.append(" but is calling from user ");
13104                        builder.append(UserHandle.getUserId(callingUid));
13105                        builder.append("; this requires ");
13106                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13107                        if (!requireFull) {
13108                            builder.append(" or ");
13109                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13110                        }
13111                        String msg = builder.toString();
13112                        Slog.w(TAG, msg);
13113                        throw new SecurityException(msg);
13114                    }
13115                }
13116            }
13117            if (userId == UserHandle.USER_CURRENT
13118                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13119                // Note that we may be accessing this outside of a lock...
13120                // shouldn't be a big deal, if this is being called outside
13121                // of a locked context there is intrinsically a race with
13122                // the value the caller will receive and someone else changing it.
13123                userId = mCurrentUserId;
13124            }
13125            if (!allowAll && userId < 0) {
13126                throw new IllegalArgumentException(
13127                        "Call does not support special user #" + userId);
13128            }
13129        }
13130        return userId;
13131    }
13132
13133    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13134            String className, int flags) {
13135        boolean result = false;
13136        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13137            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13138                if (ActivityManager.checkUidPermission(
13139                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13140                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13141                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13142                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13143                            + " requests FLAG_SINGLE_USER, but app does not hold "
13144                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13145                    Slog.w(TAG, msg);
13146                    throw new SecurityException(msg);
13147                }
13148                result = true;
13149            }
13150        } else if (componentProcessName == aInfo.packageName) {
13151            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13152        } else if ("system".equals(componentProcessName)) {
13153            result = true;
13154        }
13155        if (DEBUG_MU) {
13156            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13157                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13158        }
13159        return result;
13160    }
13161
13162    public int bindService(IApplicationThread caller, IBinder token,
13163            Intent service, String resolvedType,
13164            IServiceConnection connection, int flags, int userId) {
13165        enforceNotIsolatedCaller("bindService");
13166        // Refuse possible leaked file descriptors
13167        if (service != null && service.hasFileDescriptors() == true) {
13168            throw new IllegalArgumentException("File descriptors passed in Intent");
13169        }
13170
13171        synchronized(this) {
13172            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13173                    connection, flags, userId);
13174        }
13175    }
13176
13177    public boolean unbindService(IServiceConnection connection) {
13178        synchronized (this) {
13179            return mServices.unbindServiceLocked(connection);
13180        }
13181    }
13182
13183    public void publishService(IBinder token, Intent intent, IBinder service) {
13184        // Refuse possible leaked file descriptors
13185        if (intent != null && intent.hasFileDescriptors() == true) {
13186            throw new IllegalArgumentException("File descriptors passed in Intent");
13187        }
13188
13189        synchronized(this) {
13190            if (!(token instanceof ServiceRecord)) {
13191                throw new IllegalArgumentException("Invalid service token");
13192            }
13193            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13194        }
13195    }
13196
13197    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13198        // Refuse possible leaked file descriptors
13199        if (intent != null && intent.hasFileDescriptors() == true) {
13200            throw new IllegalArgumentException("File descriptors passed in Intent");
13201        }
13202
13203        synchronized(this) {
13204            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13205        }
13206    }
13207
13208    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13209        synchronized(this) {
13210            if (!(token instanceof ServiceRecord)) {
13211                throw new IllegalArgumentException("Invalid service token");
13212            }
13213            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13214        }
13215    }
13216
13217    // =========================================================
13218    // BACKUP AND RESTORE
13219    // =========================================================
13220
13221    // Cause the target app to be launched if necessary and its backup agent
13222    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13223    // activity manager to announce its creation.
13224    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13225        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13226        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13227
13228        synchronized(this) {
13229            // !!! TODO: currently no check here that we're already bound
13230            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13231            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13232            synchronized (stats) {
13233                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13234            }
13235
13236            // Backup agent is now in use, its package can't be stopped.
13237            try {
13238                AppGlobals.getPackageManager().setPackageStoppedState(
13239                        app.packageName, false, UserHandle.getUserId(app.uid));
13240            } catch (RemoteException e) {
13241            } catch (IllegalArgumentException e) {
13242                Slog.w(TAG, "Failed trying to unstop package "
13243                        + app.packageName + ": " + e);
13244            }
13245
13246            BackupRecord r = new BackupRecord(ss, app, backupMode);
13247            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13248                    ? new ComponentName(app.packageName, app.backupAgentName)
13249                    : new ComponentName("android", "FullBackupAgent");
13250            // startProcessLocked() returns existing proc's record if it's already running
13251            ProcessRecord proc = startProcessLocked(app.processName, app,
13252                    false, 0, "backup", hostingName, false, false, false);
13253            if (proc == null) {
13254                Slog.e(TAG, "Unable to start backup agent process " + r);
13255                return false;
13256            }
13257
13258            r.app = proc;
13259            mBackupTarget = r;
13260            mBackupAppName = app.packageName;
13261
13262            // Try not to kill the process during backup
13263            updateOomAdjLocked(proc);
13264
13265            // If the process is already attached, schedule the creation of the backup agent now.
13266            // If it is not yet live, this will be done when it attaches to the framework.
13267            if (proc.thread != null) {
13268                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13269                try {
13270                    proc.thread.scheduleCreateBackupAgent(app,
13271                            compatibilityInfoForPackageLocked(app), backupMode);
13272                } catch (RemoteException e) {
13273                    // Will time out on the backup manager side
13274                }
13275            } else {
13276                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13277            }
13278            // Invariants: at this point, the target app process exists and the application
13279            // is either already running or in the process of coming up.  mBackupTarget and
13280            // mBackupAppName describe the app, so that when it binds back to the AM we
13281            // know that it's scheduled for a backup-agent operation.
13282        }
13283
13284        return true;
13285    }
13286
13287    @Override
13288    public void clearPendingBackup() {
13289        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13290        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13291
13292        synchronized (this) {
13293            mBackupTarget = null;
13294            mBackupAppName = null;
13295        }
13296    }
13297
13298    // A backup agent has just come up
13299    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13300        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13301                + " = " + agent);
13302
13303        synchronized(this) {
13304            if (!agentPackageName.equals(mBackupAppName)) {
13305                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13306                return;
13307            }
13308        }
13309
13310        long oldIdent = Binder.clearCallingIdentity();
13311        try {
13312            IBackupManager bm = IBackupManager.Stub.asInterface(
13313                    ServiceManager.getService(Context.BACKUP_SERVICE));
13314            bm.agentConnected(agentPackageName, agent);
13315        } catch (RemoteException e) {
13316            // can't happen; the backup manager service is local
13317        } catch (Exception e) {
13318            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13319            e.printStackTrace();
13320        } finally {
13321            Binder.restoreCallingIdentity(oldIdent);
13322        }
13323    }
13324
13325    // done with this agent
13326    public void unbindBackupAgent(ApplicationInfo appInfo) {
13327        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13328        if (appInfo == null) {
13329            Slog.w(TAG, "unbind backup agent for null app");
13330            return;
13331        }
13332
13333        synchronized(this) {
13334            try {
13335                if (mBackupAppName == null) {
13336                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13337                    return;
13338                }
13339
13340                if (!mBackupAppName.equals(appInfo.packageName)) {
13341                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13342                    return;
13343                }
13344
13345                // Not backing this app up any more; reset its OOM adjustment
13346                final ProcessRecord proc = mBackupTarget.app;
13347                updateOomAdjLocked(proc);
13348
13349                // If the app crashed during backup, 'thread' will be null here
13350                if (proc.thread != null) {
13351                    try {
13352                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13353                                compatibilityInfoForPackageLocked(appInfo));
13354                    } catch (Exception e) {
13355                        Slog.e(TAG, "Exception when unbinding backup agent:");
13356                        e.printStackTrace();
13357                    }
13358                }
13359            } finally {
13360                mBackupTarget = null;
13361                mBackupAppName = null;
13362            }
13363        }
13364    }
13365    // =========================================================
13366    // BROADCASTS
13367    // =========================================================
13368
13369    private final List getStickiesLocked(String action, IntentFilter filter,
13370            List cur, int userId) {
13371        final ContentResolver resolver = mContext.getContentResolver();
13372        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13373        if (stickies == null) {
13374            return cur;
13375        }
13376        final ArrayList<Intent> list = stickies.get(action);
13377        if (list == null) {
13378            return cur;
13379        }
13380        int N = list.size();
13381        for (int i=0; i<N; i++) {
13382            Intent intent = list.get(i);
13383            if (filter.match(resolver, intent, true, TAG) >= 0) {
13384                if (cur == null) {
13385                    cur = new ArrayList<Intent>();
13386                }
13387                cur.add(intent);
13388            }
13389        }
13390        return cur;
13391    }
13392
13393    boolean isPendingBroadcastProcessLocked(int pid) {
13394        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13395                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13396    }
13397
13398    void skipPendingBroadcastLocked(int pid) {
13399            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13400            for (BroadcastQueue queue : mBroadcastQueues) {
13401                queue.skipPendingBroadcastLocked(pid);
13402            }
13403    }
13404
13405    // The app just attached; send any pending broadcasts that it should receive
13406    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13407        boolean didSomething = false;
13408        for (BroadcastQueue queue : mBroadcastQueues) {
13409            didSomething |= queue.sendPendingBroadcastsLocked(app);
13410        }
13411        return didSomething;
13412    }
13413
13414    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13415            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13416        enforceNotIsolatedCaller("registerReceiver");
13417        int callingUid;
13418        int callingPid;
13419        synchronized(this) {
13420            ProcessRecord callerApp = null;
13421            if (caller != null) {
13422                callerApp = getRecordForAppLocked(caller);
13423                if (callerApp == null) {
13424                    throw new SecurityException(
13425                            "Unable to find app for caller " + caller
13426                            + " (pid=" + Binder.getCallingPid()
13427                            + ") when registering receiver " + receiver);
13428                }
13429                if (callerApp.info.uid != Process.SYSTEM_UID &&
13430                        !callerApp.pkgList.containsKey(callerPackage) &&
13431                        !"android".equals(callerPackage)) {
13432                    throw new SecurityException("Given caller package " + callerPackage
13433                            + " is not running in process " + callerApp);
13434                }
13435                callingUid = callerApp.info.uid;
13436                callingPid = callerApp.pid;
13437            } else {
13438                callerPackage = null;
13439                callingUid = Binder.getCallingUid();
13440                callingPid = Binder.getCallingPid();
13441            }
13442
13443            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13444                    true, true, "registerReceiver", callerPackage);
13445
13446            List allSticky = null;
13447
13448            // Look for any matching sticky broadcasts...
13449            Iterator actions = filter.actionsIterator();
13450            if (actions != null) {
13451                while (actions.hasNext()) {
13452                    String action = (String)actions.next();
13453                    allSticky = getStickiesLocked(action, filter, allSticky,
13454                            UserHandle.USER_ALL);
13455                    allSticky = getStickiesLocked(action, filter, allSticky,
13456                            UserHandle.getUserId(callingUid));
13457                }
13458            } else {
13459                allSticky = getStickiesLocked(null, filter, allSticky,
13460                        UserHandle.USER_ALL);
13461                allSticky = getStickiesLocked(null, filter, allSticky,
13462                        UserHandle.getUserId(callingUid));
13463            }
13464
13465            // The first sticky in the list is returned directly back to
13466            // the client.
13467            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13468
13469            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13470                    + ": " + sticky);
13471
13472            if (receiver == null) {
13473                return sticky;
13474            }
13475
13476            ReceiverList rl
13477                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13478            if (rl == null) {
13479                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13480                        userId, receiver);
13481                if (rl.app != null) {
13482                    rl.app.receivers.add(rl);
13483                } else {
13484                    try {
13485                        receiver.asBinder().linkToDeath(rl, 0);
13486                    } catch (RemoteException e) {
13487                        return sticky;
13488                    }
13489                    rl.linkedToDeath = true;
13490                }
13491                mRegisteredReceivers.put(receiver.asBinder(), rl);
13492            } else if (rl.uid != callingUid) {
13493                throw new IllegalArgumentException(
13494                        "Receiver requested to register for uid " + callingUid
13495                        + " was previously registered for uid " + rl.uid);
13496            } else if (rl.pid != callingPid) {
13497                throw new IllegalArgumentException(
13498                        "Receiver requested to register for pid " + callingPid
13499                        + " was previously registered for pid " + rl.pid);
13500            } else if (rl.userId != userId) {
13501                throw new IllegalArgumentException(
13502                        "Receiver requested to register for user " + userId
13503                        + " was previously registered for user " + rl.userId);
13504            }
13505            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13506                    permission, callingUid, userId);
13507            rl.add(bf);
13508            if (!bf.debugCheck()) {
13509                Slog.w(TAG, "==> For Dynamic broadast");
13510            }
13511            mReceiverResolver.addFilter(bf);
13512
13513            // Enqueue broadcasts for all existing stickies that match
13514            // this filter.
13515            if (allSticky != null) {
13516                ArrayList receivers = new ArrayList();
13517                receivers.add(bf);
13518
13519                int N = allSticky.size();
13520                for (int i=0; i<N; i++) {
13521                    Intent intent = (Intent)allSticky.get(i);
13522                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13523                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13524                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13525                            null, null, false, true, true, -1);
13526                    queue.enqueueParallelBroadcastLocked(r);
13527                    queue.scheduleBroadcastsLocked();
13528                }
13529            }
13530
13531            return sticky;
13532        }
13533    }
13534
13535    public void unregisterReceiver(IIntentReceiver receiver) {
13536        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13537
13538        final long origId = Binder.clearCallingIdentity();
13539        try {
13540            boolean doTrim = false;
13541
13542            synchronized(this) {
13543                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13544                if (rl != null) {
13545                    if (rl.curBroadcast != null) {
13546                        BroadcastRecord r = rl.curBroadcast;
13547                        final boolean doNext = finishReceiverLocked(
13548                                receiver.asBinder(), r.resultCode, r.resultData,
13549                                r.resultExtras, r.resultAbort);
13550                        if (doNext) {
13551                            doTrim = true;
13552                            r.queue.processNextBroadcast(false);
13553                        }
13554                    }
13555
13556                    if (rl.app != null) {
13557                        rl.app.receivers.remove(rl);
13558                    }
13559                    removeReceiverLocked(rl);
13560                    if (rl.linkedToDeath) {
13561                        rl.linkedToDeath = false;
13562                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13563                    }
13564                }
13565            }
13566
13567            // If we actually concluded any broadcasts, we might now be able
13568            // to trim the recipients' apps from our working set
13569            if (doTrim) {
13570                trimApplications();
13571                return;
13572            }
13573
13574        } finally {
13575            Binder.restoreCallingIdentity(origId);
13576        }
13577    }
13578
13579    void removeReceiverLocked(ReceiverList rl) {
13580        mRegisteredReceivers.remove(rl.receiver.asBinder());
13581        int N = rl.size();
13582        for (int i=0; i<N; i++) {
13583            mReceiverResolver.removeFilter(rl.get(i));
13584        }
13585    }
13586
13587    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13588        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13589            ProcessRecord r = mLruProcesses.get(i);
13590            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13591                try {
13592                    r.thread.dispatchPackageBroadcast(cmd, packages);
13593                } catch (RemoteException ex) {
13594                }
13595            }
13596        }
13597    }
13598
13599    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13600            int[] users) {
13601        List<ResolveInfo> receivers = null;
13602        try {
13603            HashSet<ComponentName> singleUserReceivers = null;
13604            boolean scannedFirstReceivers = false;
13605            for (int user : users) {
13606                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13607                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13608                if (user != 0 && newReceivers != null) {
13609                    // If this is not the primary user, we need to check for
13610                    // any receivers that should be filtered out.
13611                    for (int i=0; i<newReceivers.size(); i++) {
13612                        ResolveInfo ri = newReceivers.get(i);
13613                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13614                            newReceivers.remove(i);
13615                            i--;
13616                        }
13617                    }
13618                }
13619                if (newReceivers != null && newReceivers.size() == 0) {
13620                    newReceivers = null;
13621                }
13622                if (receivers == null) {
13623                    receivers = newReceivers;
13624                } else if (newReceivers != null) {
13625                    // We need to concatenate the additional receivers
13626                    // found with what we have do far.  This would be easy,
13627                    // but we also need to de-dup any receivers that are
13628                    // singleUser.
13629                    if (!scannedFirstReceivers) {
13630                        // Collect any single user receivers we had already retrieved.
13631                        scannedFirstReceivers = true;
13632                        for (int i=0; i<receivers.size(); i++) {
13633                            ResolveInfo ri = receivers.get(i);
13634                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13635                                ComponentName cn = new ComponentName(
13636                                        ri.activityInfo.packageName, ri.activityInfo.name);
13637                                if (singleUserReceivers == null) {
13638                                    singleUserReceivers = new HashSet<ComponentName>();
13639                                }
13640                                singleUserReceivers.add(cn);
13641                            }
13642                        }
13643                    }
13644                    // Add the new results to the existing results, tracking
13645                    // and de-dupping single user receivers.
13646                    for (int i=0; i<newReceivers.size(); i++) {
13647                        ResolveInfo ri = newReceivers.get(i);
13648                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13649                            ComponentName cn = new ComponentName(
13650                                    ri.activityInfo.packageName, ri.activityInfo.name);
13651                            if (singleUserReceivers == null) {
13652                                singleUserReceivers = new HashSet<ComponentName>();
13653                            }
13654                            if (!singleUserReceivers.contains(cn)) {
13655                                singleUserReceivers.add(cn);
13656                                receivers.add(ri);
13657                            }
13658                        } else {
13659                            receivers.add(ri);
13660                        }
13661                    }
13662                }
13663            }
13664        } catch (RemoteException ex) {
13665            // pm is in same process, this will never happen.
13666        }
13667        return receivers;
13668    }
13669
13670    private final int broadcastIntentLocked(ProcessRecord callerApp,
13671            String callerPackage, Intent intent, String resolvedType,
13672            IIntentReceiver resultTo, int resultCode, String resultData,
13673            Bundle map, String requiredPermission, int appOp,
13674            boolean ordered, boolean sticky, int callingPid, int callingUid,
13675            int userId) {
13676        intent = new Intent(intent);
13677
13678        // By default broadcasts do not go to stopped apps.
13679        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13680
13681        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13682            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13683            + " ordered=" + ordered + " userid=" + userId);
13684        if ((resultTo != null) && !ordered) {
13685            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13686        }
13687
13688        userId = handleIncomingUser(callingPid, callingUid, userId,
13689                true, false, "broadcast", callerPackage);
13690
13691        // Make sure that the user who is receiving this broadcast is started.
13692        // If not, we will just skip it.
13693        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13694            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13695                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13696                Slog.w(TAG, "Skipping broadcast of " + intent
13697                        + ": user " + userId + " is stopped");
13698                return ActivityManager.BROADCAST_SUCCESS;
13699            }
13700        }
13701
13702        /*
13703         * Prevent non-system code (defined here to be non-persistent
13704         * processes) from sending protected broadcasts.
13705         */
13706        int callingAppId = UserHandle.getAppId(callingUid);
13707        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13708            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13709            callingUid == 0) {
13710            // Always okay.
13711        } else if (callerApp == null || !callerApp.persistent) {
13712            try {
13713                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13714                        intent.getAction())) {
13715                    String msg = "Permission Denial: not allowed to send broadcast "
13716                            + intent.getAction() + " from pid="
13717                            + callingPid + ", uid=" + callingUid;
13718                    Slog.w(TAG, msg);
13719                    throw new SecurityException(msg);
13720                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13721                    // Special case for compatibility: we don't want apps to send this,
13722                    // but historically it has not been protected and apps may be using it
13723                    // to poke their own app widget.  So, instead of making it protected,
13724                    // just limit it to the caller.
13725                    if (callerApp == null) {
13726                        String msg = "Permission Denial: not allowed to send broadcast "
13727                                + intent.getAction() + " from unknown caller.";
13728                        Slog.w(TAG, msg);
13729                        throw new SecurityException(msg);
13730                    } else if (intent.getComponent() != null) {
13731                        // They are good enough to send to an explicit component...  verify
13732                        // it is being sent to the calling app.
13733                        if (!intent.getComponent().getPackageName().equals(
13734                                callerApp.info.packageName)) {
13735                            String msg = "Permission Denial: not allowed to send broadcast "
13736                                    + intent.getAction() + " to "
13737                                    + intent.getComponent().getPackageName() + " from "
13738                                    + callerApp.info.packageName;
13739                            Slog.w(TAG, msg);
13740                            throw new SecurityException(msg);
13741                        }
13742                    } else {
13743                        // Limit broadcast to their own package.
13744                        intent.setPackage(callerApp.info.packageName);
13745                    }
13746                }
13747            } catch (RemoteException e) {
13748                Slog.w(TAG, "Remote exception", e);
13749                return ActivityManager.BROADCAST_SUCCESS;
13750            }
13751        }
13752
13753        // Handle special intents: if this broadcast is from the package
13754        // manager about a package being removed, we need to remove all of
13755        // its activities from the history stack.
13756        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13757                intent.getAction());
13758        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13759                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13760                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13761                || uidRemoved) {
13762            if (checkComponentPermission(
13763                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13764                    callingPid, callingUid, -1, true)
13765                    == PackageManager.PERMISSION_GRANTED) {
13766                if (uidRemoved) {
13767                    final Bundle intentExtras = intent.getExtras();
13768                    final int uid = intentExtras != null
13769                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13770                    if (uid >= 0) {
13771                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13772                        synchronized (bs) {
13773                            bs.removeUidStatsLocked(uid);
13774                        }
13775                        mAppOpsService.uidRemoved(uid);
13776                    }
13777                } else {
13778                    // If resources are unavailable just force stop all
13779                    // those packages and flush the attribute cache as well.
13780                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13781                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13782                        if (list != null && (list.length > 0)) {
13783                            for (String pkg : list) {
13784                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13785                                        "storage unmount");
13786                            }
13787                            sendPackageBroadcastLocked(
13788                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13789                        }
13790                    } else {
13791                        Uri data = intent.getData();
13792                        String ssp;
13793                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13794                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13795                                    intent.getAction());
13796                            boolean fullUninstall = removed &&
13797                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13798                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13799                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13800                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13801                                        false, fullUninstall, userId,
13802                                        removed ? "pkg removed" : "pkg changed");
13803                            }
13804                            if (removed) {
13805                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13806                                        new String[] {ssp}, userId);
13807                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13808                                    mAppOpsService.packageRemoved(
13809                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13810
13811                                    // Remove all permissions granted from/to this package
13812                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13813                                }
13814                            }
13815                        }
13816                    }
13817                }
13818            } else {
13819                String msg = "Permission Denial: " + intent.getAction()
13820                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13821                        + ", uid=" + callingUid + ")"
13822                        + " requires "
13823                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13824                Slog.w(TAG, msg);
13825                throw new SecurityException(msg);
13826            }
13827
13828        // Special case for adding a package: by default turn on compatibility
13829        // mode.
13830        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13831            Uri data = intent.getData();
13832            String ssp;
13833            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13834                mCompatModePackages.handlePackageAddedLocked(ssp,
13835                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13836            }
13837        }
13838
13839        /*
13840         * If this is the time zone changed action, queue up a message that will reset the timezone
13841         * of all currently running processes. This message will get queued up before the broadcast
13842         * happens.
13843         */
13844        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13845            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13846        }
13847
13848        /*
13849         * If the user set the time, let all running processes know.
13850         */
13851        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13852            final int is24Hour = intent.getBooleanExtra(
13853                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13854            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13855        }
13856
13857        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13858            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13859        }
13860
13861        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13862            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13863            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13864        }
13865
13866        // Add to the sticky list if requested.
13867        if (sticky) {
13868            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13869                    callingPid, callingUid)
13870                    != PackageManager.PERMISSION_GRANTED) {
13871                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13872                        + callingPid + ", uid=" + callingUid
13873                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13874                Slog.w(TAG, msg);
13875                throw new SecurityException(msg);
13876            }
13877            if (requiredPermission != null) {
13878                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13879                        + " and enforce permission " + requiredPermission);
13880                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13881            }
13882            if (intent.getComponent() != null) {
13883                throw new SecurityException(
13884                        "Sticky broadcasts can't target a specific component");
13885            }
13886            // We use userId directly here, since the "all" target is maintained
13887            // as a separate set of sticky broadcasts.
13888            if (userId != UserHandle.USER_ALL) {
13889                // But first, if this is not a broadcast to all users, then
13890                // make sure it doesn't conflict with an existing broadcast to
13891                // all users.
13892                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13893                        UserHandle.USER_ALL);
13894                if (stickies != null) {
13895                    ArrayList<Intent> list = stickies.get(intent.getAction());
13896                    if (list != null) {
13897                        int N = list.size();
13898                        int i;
13899                        for (i=0; i<N; i++) {
13900                            if (intent.filterEquals(list.get(i))) {
13901                                throw new IllegalArgumentException(
13902                                        "Sticky broadcast " + intent + " for user "
13903                                        + userId + " conflicts with existing global broadcast");
13904                            }
13905                        }
13906                    }
13907                }
13908            }
13909            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13910            if (stickies == null) {
13911                stickies = new ArrayMap<String, ArrayList<Intent>>();
13912                mStickyBroadcasts.put(userId, stickies);
13913            }
13914            ArrayList<Intent> list = stickies.get(intent.getAction());
13915            if (list == null) {
13916                list = new ArrayList<Intent>();
13917                stickies.put(intent.getAction(), list);
13918            }
13919            int N = list.size();
13920            int i;
13921            for (i=0; i<N; i++) {
13922                if (intent.filterEquals(list.get(i))) {
13923                    // This sticky already exists, replace it.
13924                    list.set(i, new Intent(intent));
13925                    break;
13926                }
13927            }
13928            if (i >= N) {
13929                list.add(new Intent(intent));
13930            }
13931        }
13932
13933        int[] users;
13934        if (userId == UserHandle.USER_ALL) {
13935            // Caller wants broadcast to go to all started users.
13936            users = mStartedUserArray;
13937        } else {
13938            // Caller wants broadcast to go to one specific user.
13939            users = new int[] {userId};
13940        }
13941
13942        // Figure out who all will receive this broadcast.
13943        List receivers = null;
13944        List<BroadcastFilter> registeredReceivers = null;
13945        // Need to resolve the intent to interested receivers...
13946        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13947                 == 0) {
13948            receivers = collectReceiverComponents(intent, resolvedType, users);
13949        }
13950        if (intent.getComponent() == null) {
13951            registeredReceivers = mReceiverResolver.queryIntent(intent,
13952                    resolvedType, false, userId);
13953        }
13954
13955        final boolean replacePending =
13956                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13957
13958        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13959                + " replacePending=" + replacePending);
13960
13961        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13962        if (!ordered && NR > 0) {
13963            // If we are not serializing this broadcast, then send the
13964            // registered receivers separately so they don't wait for the
13965            // components to be launched.
13966            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13967            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13968                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13969                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13970                    ordered, sticky, false, userId);
13971            if (DEBUG_BROADCAST) Slog.v(
13972                    TAG, "Enqueueing parallel broadcast " + r);
13973            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13974            if (!replaced) {
13975                queue.enqueueParallelBroadcastLocked(r);
13976                queue.scheduleBroadcastsLocked();
13977            }
13978            registeredReceivers = null;
13979            NR = 0;
13980        }
13981
13982        // Merge into one list.
13983        int ir = 0;
13984        if (receivers != null) {
13985            // A special case for PACKAGE_ADDED: do not allow the package
13986            // being added to see this broadcast.  This prevents them from
13987            // using this as a back door to get run as soon as they are
13988            // installed.  Maybe in the future we want to have a special install
13989            // broadcast or such for apps, but we'd like to deliberately make
13990            // this decision.
13991            String skipPackages[] = null;
13992            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13993                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13994                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13995                Uri data = intent.getData();
13996                if (data != null) {
13997                    String pkgName = data.getSchemeSpecificPart();
13998                    if (pkgName != null) {
13999                        skipPackages = new String[] { pkgName };
14000                    }
14001                }
14002            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14003                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14004            }
14005            if (skipPackages != null && (skipPackages.length > 0)) {
14006                for (String skipPackage : skipPackages) {
14007                    if (skipPackage != null) {
14008                        int NT = receivers.size();
14009                        for (int it=0; it<NT; it++) {
14010                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14011                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14012                                receivers.remove(it);
14013                                it--;
14014                                NT--;
14015                            }
14016                        }
14017                    }
14018                }
14019            }
14020
14021            int NT = receivers != null ? receivers.size() : 0;
14022            int it = 0;
14023            ResolveInfo curt = null;
14024            BroadcastFilter curr = null;
14025            while (it < NT && ir < NR) {
14026                if (curt == null) {
14027                    curt = (ResolveInfo)receivers.get(it);
14028                }
14029                if (curr == null) {
14030                    curr = registeredReceivers.get(ir);
14031                }
14032                if (curr.getPriority() >= curt.priority) {
14033                    // Insert this broadcast record into the final list.
14034                    receivers.add(it, curr);
14035                    ir++;
14036                    curr = null;
14037                    it++;
14038                    NT++;
14039                } else {
14040                    // Skip to the next ResolveInfo in the final list.
14041                    it++;
14042                    curt = null;
14043                }
14044            }
14045        }
14046        while (ir < NR) {
14047            if (receivers == null) {
14048                receivers = new ArrayList();
14049            }
14050            receivers.add(registeredReceivers.get(ir));
14051            ir++;
14052        }
14053
14054        if ((receivers != null && receivers.size() > 0)
14055                || resultTo != null) {
14056            BroadcastQueue queue = broadcastQueueForIntent(intent);
14057            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14058                    callerPackage, callingPid, callingUid, resolvedType,
14059                    requiredPermission, appOp, receivers, resultTo, resultCode,
14060                    resultData, map, ordered, sticky, false, userId);
14061            if (DEBUG_BROADCAST) Slog.v(
14062                    TAG, "Enqueueing ordered broadcast " + r
14063                    + ": prev had " + queue.mOrderedBroadcasts.size());
14064            if (DEBUG_BROADCAST) {
14065                int seq = r.intent.getIntExtra("seq", -1);
14066                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14067            }
14068            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14069            if (!replaced) {
14070                queue.enqueueOrderedBroadcastLocked(r);
14071                queue.scheduleBroadcastsLocked();
14072            }
14073        }
14074
14075        return ActivityManager.BROADCAST_SUCCESS;
14076    }
14077
14078    final Intent verifyBroadcastLocked(Intent intent) {
14079        // Refuse possible leaked file descriptors
14080        if (intent != null && intent.hasFileDescriptors() == true) {
14081            throw new IllegalArgumentException("File descriptors passed in Intent");
14082        }
14083
14084        int flags = intent.getFlags();
14085
14086        if (!mProcessesReady) {
14087            // if the caller really truly claims to know what they're doing, go
14088            // ahead and allow the broadcast without launching any receivers
14089            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14090                intent = new Intent(intent);
14091                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14092            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14093                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14094                        + " before boot completion");
14095                throw new IllegalStateException("Cannot broadcast before boot completed");
14096            }
14097        }
14098
14099        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14100            throw new IllegalArgumentException(
14101                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14102        }
14103
14104        return intent;
14105    }
14106
14107    public final int broadcastIntent(IApplicationThread caller,
14108            Intent intent, String resolvedType, IIntentReceiver resultTo,
14109            int resultCode, String resultData, Bundle map,
14110            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14111        enforceNotIsolatedCaller("broadcastIntent");
14112        synchronized(this) {
14113            intent = verifyBroadcastLocked(intent);
14114
14115            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14116            final int callingPid = Binder.getCallingPid();
14117            final int callingUid = Binder.getCallingUid();
14118            final long origId = Binder.clearCallingIdentity();
14119            int res = broadcastIntentLocked(callerApp,
14120                    callerApp != null ? callerApp.info.packageName : null,
14121                    intent, resolvedType, resultTo,
14122                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14123                    callingPid, callingUid, userId);
14124            Binder.restoreCallingIdentity(origId);
14125            return res;
14126        }
14127    }
14128
14129    int broadcastIntentInPackage(String packageName, int uid,
14130            Intent intent, String resolvedType, IIntentReceiver resultTo,
14131            int resultCode, String resultData, Bundle map,
14132            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14133        synchronized(this) {
14134            intent = verifyBroadcastLocked(intent);
14135
14136            final long origId = Binder.clearCallingIdentity();
14137            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14138                    resultTo, resultCode, resultData, map, requiredPermission,
14139                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14140            Binder.restoreCallingIdentity(origId);
14141            return res;
14142        }
14143    }
14144
14145    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14146        // Refuse possible leaked file descriptors
14147        if (intent != null && intent.hasFileDescriptors() == true) {
14148            throw new IllegalArgumentException("File descriptors passed in Intent");
14149        }
14150
14151        userId = handleIncomingUser(Binder.getCallingPid(),
14152                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14153
14154        synchronized(this) {
14155            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14156                    != PackageManager.PERMISSION_GRANTED) {
14157                String msg = "Permission Denial: unbroadcastIntent() from pid="
14158                        + Binder.getCallingPid()
14159                        + ", uid=" + Binder.getCallingUid()
14160                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14161                Slog.w(TAG, msg);
14162                throw new SecurityException(msg);
14163            }
14164            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14165            if (stickies != null) {
14166                ArrayList<Intent> list = stickies.get(intent.getAction());
14167                if (list != null) {
14168                    int N = list.size();
14169                    int i;
14170                    for (i=0; i<N; i++) {
14171                        if (intent.filterEquals(list.get(i))) {
14172                            list.remove(i);
14173                            break;
14174                        }
14175                    }
14176                    if (list.size() <= 0) {
14177                        stickies.remove(intent.getAction());
14178                    }
14179                }
14180                if (stickies.size() <= 0) {
14181                    mStickyBroadcasts.remove(userId);
14182                }
14183            }
14184        }
14185    }
14186
14187    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14188            String resultData, Bundle resultExtras, boolean resultAbort) {
14189        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14190        if (r == null) {
14191            Slog.w(TAG, "finishReceiver called but not found on queue");
14192            return false;
14193        }
14194
14195        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14196    }
14197
14198    void backgroundServicesFinishedLocked(int userId) {
14199        for (BroadcastQueue queue : mBroadcastQueues) {
14200            queue.backgroundServicesFinishedLocked(userId);
14201        }
14202    }
14203
14204    public void finishReceiver(IBinder who, int resultCode, String resultData,
14205            Bundle resultExtras, boolean resultAbort) {
14206        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14207
14208        // Refuse possible leaked file descriptors
14209        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14210            throw new IllegalArgumentException("File descriptors passed in Bundle");
14211        }
14212
14213        final long origId = Binder.clearCallingIdentity();
14214        try {
14215            boolean doNext = false;
14216            BroadcastRecord r;
14217
14218            synchronized(this) {
14219                r = broadcastRecordForReceiverLocked(who);
14220                if (r != null) {
14221                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14222                        resultData, resultExtras, resultAbort, true);
14223                }
14224            }
14225
14226            if (doNext) {
14227                r.queue.processNextBroadcast(false);
14228            }
14229            trimApplications();
14230        } finally {
14231            Binder.restoreCallingIdentity(origId);
14232        }
14233    }
14234
14235    // =========================================================
14236    // INSTRUMENTATION
14237    // =========================================================
14238
14239    public boolean startInstrumentation(ComponentName className,
14240            String profileFile, int flags, Bundle arguments,
14241            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14242            int userId) {
14243        enforceNotIsolatedCaller("startInstrumentation");
14244        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14245                userId, false, true, "startInstrumentation", null);
14246        // Refuse possible leaked file descriptors
14247        if (arguments != null && arguments.hasFileDescriptors()) {
14248            throw new IllegalArgumentException("File descriptors passed in Bundle");
14249        }
14250
14251        synchronized(this) {
14252            InstrumentationInfo ii = null;
14253            ApplicationInfo ai = null;
14254            try {
14255                ii = mContext.getPackageManager().getInstrumentationInfo(
14256                    className, STOCK_PM_FLAGS);
14257                ai = AppGlobals.getPackageManager().getApplicationInfo(
14258                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14259            } catch (PackageManager.NameNotFoundException e) {
14260            } catch (RemoteException e) {
14261            }
14262            if (ii == null) {
14263                reportStartInstrumentationFailure(watcher, className,
14264                        "Unable to find instrumentation info for: " + className);
14265                return false;
14266            }
14267            if (ai == null) {
14268                reportStartInstrumentationFailure(watcher, className,
14269                        "Unable to find instrumentation target package: " + ii.targetPackage);
14270                return false;
14271            }
14272
14273            int match = mContext.getPackageManager().checkSignatures(
14274                    ii.targetPackage, ii.packageName);
14275            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14276                String msg = "Permission Denial: starting instrumentation "
14277                        + className + " from pid="
14278                        + Binder.getCallingPid()
14279                        + ", uid=" + Binder.getCallingPid()
14280                        + " not allowed because package " + ii.packageName
14281                        + " does not have a signature matching the target "
14282                        + ii.targetPackage;
14283                reportStartInstrumentationFailure(watcher, className, msg);
14284                throw new SecurityException(msg);
14285            }
14286
14287            final long origId = Binder.clearCallingIdentity();
14288            // Instrumentation can kill and relaunch even persistent processes
14289            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14290                    "start instr");
14291            ProcessRecord app = addAppLocked(ai, false);
14292            app.instrumentationClass = className;
14293            app.instrumentationInfo = ai;
14294            app.instrumentationProfileFile = profileFile;
14295            app.instrumentationArguments = arguments;
14296            app.instrumentationWatcher = watcher;
14297            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14298            app.instrumentationResultClass = className;
14299            Binder.restoreCallingIdentity(origId);
14300        }
14301
14302        return true;
14303    }
14304
14305    /**
14306     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14307     * error to the logs, but if somebody is watching, send the report there too.  This enables
14308     * the "am" command to report errors with more information.
14309     *
14310     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14311     * @param cn The component name of the instrumentation.
14312     * @param report The error report.
14313     */
14314    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14315            ComponentName cn, String report) {
14316        Slog.w(TAG, report);
14317        try {
14318            if (watcher != null) {
14319                Bundle results = new Bundle();
14320                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14321                results.putString("Error", report);
14322                watcher.instrumentationStatus(cn, -1, results);
14323            }
14324        } catch (RemoteException e) {
14325            Slog.w(TAG, e);
14326        }
14327    }
14328
14329    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14330        if (app.instrumentationWatcher != null) {
14331            try {
14332                // NOTE:  IInstrumentationWatcher *must* be oneway here
14333                app.instrumentationWatcher.instrumentationFinished(
14334                    app.instrumentationClass,
14335                    resultCode,
14336                    results);
14337            } catch (RemoteException e) {
14338            }
14339        }
14340        if (app.instrumentationUiAutomationConnection != null) {
14341            try {
14342                app.instrumentationUiAutomationConnection.shutdown();
14343            } catch (RemoteException re) {
14344                /* ignore */
14345            }
14346            // Only a UiAutomation can set this flag and now that
14347            // it is finished we make sure it is reset to its default.
14348            mUserIsMonkey = false;
14349        }
14350        app.instrumentationWatcher = null;
14351        app.instrumentationUiAutomationConnection = null;
14352        app.instrumentationClass = null;
14353        app.instrumentationInfo = null;
14354        app.instrumentationProfileFile = null;
14355        app.instrumentationArguments = null;
14356
14357        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14358                "finished inst");
14359    }
14360
14361    public void finishInstrumentation(IApplicationThread target,
14362            int resultCode, Bundle results) {
14363        int userId = UserHandle.getCallingUserId();
14364        // Refuse possible leaked file descriptors
14365        if (results != null && results.hasFileDescriptors()) {
14366            throw new IllegalArgumentException("File descriptors passed in Intent");
14367        }
14368
14369        synchronized(this) {
14370            ProcessRecord app = getRecordForAppLocked(target);
14371            if (app == null) {
14372                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14373                return;
14374            }
14375            final long origId = Binder.clearCallingIdentity();
14376            finishInstrumentationLocked(app, resultCode, results);
14377            Binder.restoreCallingIdentity(origId);
14378        }
14379    }
14380
14381    // =========================================================
14382    // CONFIGURATION
14383    // =========================================================
14384
14385    public ConfigurationInfo getDeviceConfigurationInfo() {
14386        ConfigurationInfo config = new ConfigurationInfo();
14387        synchronized (this) {
14388            config.reqTouchScreen = mConfiguration.touchscreen;
14389            config.reqKeyboardType = mConfiguration.keyboard;
14390            config.reqNavigation = mConfiguration.navigation;
14391            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14392                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14393                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14394            }
14395            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14396                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14397                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14398            }
14399            config.reqGlEsVersion = GL_ES_VERSION;
14400        }
14401        return config;
14402    }
14403
14404    ActivityStack getFocusedStack() {
14405        return mStackSupervisor.getFocusedStack();
14406    }
14407
14408    public Configuration getConfiguration() {
14409        Configuration ci;
14410        synchronized(this) {
14411            ci = new Configuration(mConfiguration);
14412        }
14413        return ci;
14414    }
14415
14416    public void updatePersistentConfiguration(Configuration values) {
14417        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14418                "updateConfiguration()");
14419        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14420                "updateConfiguration()");
14421        if (values == null) {
14422            throw new NullPointerException("Configuration must not be null");
14423        }
14424
14425        synchronized(this) {
14426            final long origId = Binder.clearCallingIdentity();
14427            updateConfigurationLocked(values, null, true, false);
14428            Binder.restoreCallingIdentity(origId);
14429        }
14430    }
14431
14432    public void updateConfiguration(Configuration values) {
14433        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14434                "updateConfiguration()");
14435
14436        synchronized(this) {
14437            if (values == null && mWindowManager != null) {
14438                // sentinel: fetch the current configuration from the window manager
14439                values = mWindowManager.computeNewConfiguration();
14440            }
14441
14442            if (mWindowManager != null) {
14443                mProcessList.applyDisplaySize(mWindowManager);
14444            }
14445
14446            final long origId = Binder.clearCallingIdentity();
14447            if (values != null) {
14448                Settings.System.clearConfiguration(values);
14449            }
14450            updateConfigurationLocked(values, null, false, false);
14451            Binder.restoreCallingIdentity(origId);
14452        }
14453    }
14454
14455    /**
14456     * Do either or both things: (1) change the current configuration, and (2)
14457     * make sure the given activity is running with the (now) current
14458     * configuration.  Returns true if the activity has been left running, or
14459     * false if <var>starting</var> is being destroyed to match the new
14460     * configuration.
14461     * @param persistent TODO
14462     */
14463    boolean updateConfigurationLocked(Configuration values,
14464            ActivityRecord starting, boolean persistent, boolean initLocale) {
14465        int changes = 0;
14466
14467        if (values != null) {
14468            Configuration newConfig = new Configuration(mConfiguration);
14469            changes = newConfig.updateFrom(values);
14470            if (changes != 0) {
14471                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14472                    Slog.i(TAG, "Updating configuration to: " + values);
14473                }
14474
14475                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14476
14477                if (values.locale != null && !initLocale) {
14478                    saveLocaleLocked(values.locale,
14479                                     !values.locale.equals(mConfiguration.locale),
14480                                     values.userSetLocale);
14481                }
14482
14483                mConfigurationSeq++;
14484                if (mConfigurationSeq <= 0) {
14485                    mConfigurationSeq = 1;
14486                }
14487                newConfig.seq = mConfigurationSeq;
14488                mConfiguration = newConfig;
14489                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14490
14491                final Configuration configCopy = new Configuration(mConfiguration);
14492
14493                // TODO: If our config changes, should we auto dismiss any currently
14494                // showing dialogs?
14495                mShowDialogs = shouldShowDialogs(newConfig);
14496
14497                AttributeCache ac = AttributeCache.instance();
14498                if (ac != null) {
14499                    ac.updateConfiguration(configCopy);
14500                }
14501
14502                // Make sure all resources in our process are updated
14503                // right now, so that anyone who is going to retrieve
14504                // resource values after we return will be sure to get
14505                // the new ones.  This is especially important during
14506                // boot, where the first config change needs to guarantee
14507                // all resources have that config before following boot
14508                // code is executed.
14509                mSystemThread.applyConfigurationToResources(configCopy);
14510
14511                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14512                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14513                    msg.obj = new Configuration(configCopy);
14514                    mHandler.sendMessage(msg);
14515                }
14516
14517                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14518                    ProcessRecord app = mLruProcesses.get(i);
14519                    try {
14520                        if (app.thread != null) {
14521                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14522                                    + app.processName + " new config " + mConfiguration);
14523                            app.thread.scheduleConfigurationChanged(configCopy);
14524                        }
14525                    } catch (Exception e) {
14526                    }
14527                }
14528                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14529                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14530                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14531                        | Intent.FLAG_RECEIVER_FOREGROUND);
14532                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14533                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14534                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14535                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14536                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14537                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14538                    broadcastIntentLocked(null, null, intent,
14539                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14540                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14541                }
14542            }
14543        }
14544
14545        boolean kept = true;
14546        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14547        // mainStack is null during startup.
14548        if (mainStack != null) {
14549            if (changes != 0 && starting == null) {
14550                // If the configuration changed, and the caller is not already
14551                // in the process of starting an activity, then find the top
14552                // activity to check if its configuration needs to change.
14553                starting = mainStack.topRunningActivityLocked(null);
14554            }
14555
14556            if (starting != null) {
14557                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14558                // And we need to make sure at this point that all other activities
14559                // are made visible with the correct configuration.
14560                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14561            }
14562        }
14563
14564        if (values != null && mWindowManager != null) {
14565            mWindowManager.setNewConfiguration(mConfiguration);
14566        }
14567
14568        return kept;
14569    }
14570
14571    /**
14572     * Decide based on the configuration whether we should shouw the ANR,
14573     * crash, etc dialogs.  The idea is that if there is no affordnace to
14574     * press the on-screen buttons, we shouldn't show the dialog.
14575     *
14576     * A thought: SystemUI might also want to get told about this, the Power
14577     * dialog / global actions also might want different behaviors.
14578     */
14579    private static final boolean shouldShowDialogs(Configuration config) {
14580        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14581                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14582    }
14583
14584    /**
14585     * Save the locale.  You must be inside a synchronized (this) block.
14586     */
14587    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14588        if(isDiff) {
14589            SystemProperties.set("user.language", l.getLanguage());
14590            SystemProperties.set("user.region", l.getCountry());
14591        }
14592
14593        if(isPersist) {
14594            SystemProperties.set("persist.sys.language", l.getLanguage());
14595            SystemProperties.set("persist.sys.country", l.getCountry());
14596            SystemProperties.set("persist.sys.localevar", l.getVariant());
14597        }
14598    }
14599
14600    @Override
14601    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14602        ActivityRecord srec = ActivityRecord.forToken(token);
14603        return srec != null && srec.task.affinity != null &&
14604                srec.task.affinity.equals(destAffinity);
14605    }
14606
14607    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14608            Intent resultData) {
14609
14610        synchronized (this) {
14611            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14612            if (stack != null) {
14613                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14614            }
14615            return false;
14616        }
14617    }
14618
14619    public int getLaunchedFromUid(IBinder activityToken) {
14620        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14621        if (srec == null) {
14622            return -1;
14623        }
14624        return srec.launchedFromUid;
14625    }
14626
14627    public String getLaunchedFromPackage(IBinder activityToken) {
14628        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14629        if (srec == null) {
14630            return null;
14631        }
14632        return srec.launchedFromPackage;
14633    }
14634
14635    // =========================================================
14636    // LIFETIME MANAGEMENT
14637    // =========================================================
14638
14639    // Returns which broadcast queue the app is the current [or imminent] receiver
14640    // on, or 'null' if the app is not an active broadcast recipient.
14641    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14642        BroadcastRecord r = app.curReceiver;
14643        if (r != null) {
14644            return r.queue;
14645        }
14646
14647        // It's not the current receiver, but it might be starting up to become one
14648        synchronized (this) {
14649            for (BroadcastQueue queue : mBroadcastQueues) {
14650                r = queue.mPendingBroadcast;
14651                if (r != null && r.curApp == app) {
14652                    // found it; report which queue it's in
14653                    return queue;
14654                }
14655            }
14656        }
14657
14658        return null;
14659    }
14660
14661    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14662            boolean doingAll, long now) {
14663        if (mAdjSeq == app.adjSeq) {
14664            // This adjustment has already been computed.
14665            return app.curRawAdj;
14666        }
14667
14668        if (app.thread == null) {
14669            app.adjSeq = mAdjSeq;
14670            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14671            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14672            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14673        }
14674
14675        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14676        app.adjSource = null;
14677        app.adjTarget = null;
14678        app.empty = false;
14679        app.cached = false;
14680
14681        final int activitiesSize = app.activities.size();
14682
14683        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14684            // The max adjustment doesn't allow this app to be anything
14685            // below foreground, so it is not worth doing work for it.
14686            app.adjType = "fixed";
14687            app.adjSeq = mAdjSeq;
14688            app.curRawAdj = app.maxAdj;
14689            app.foregroundActivities = false;
14690            app.keeping = true;
14691            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14692            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14693            // System process can do UI, and when they do we want to have
14694            // them trim their memory after the user leaves the UI.  To
14695            // facilitate this, here we need to determine whether or not it
14696            // is currently showing UI.
14697            app.systemNoUi = true;
14698            if (app == TOP_APP) {
14699                app.systemNoUi = false;
14700            } else if (activitiesSize > 0) {
14701                for (int j = 0; j < activitiesSize; j++) {
14702                    final ActivityRecord r = app.activities.get(j);
14703                    if (r.visible) {
14704                        app.systemNoUi = false;
14705                    }
14706                }
14707            }
14708            if (!app.systemNoUi) {
14709                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14710            }
14711            return (app.curAdj=app.maxAdj);
14712        }
14713
14714        app.keeping = false;
14715        app.systemNoUi = false;
14716
14717        // Determine the importance of the process, starting with most
14718        // important to least, and assign an appropriate OOM adjustment.
14719        int adj;
14720        int schedGroup;
14721        int procState;
14722        boolean foregroundActivities = false;
14723        boolean interesting = false;
14724        BroadcastQueue queue;
14725        if (app == TOP_APP) {
14726            // The last app on the list is the foreground app.
14727            adj = ProcessList.FOREGROUND_APP_ADJ;
14728            schedGroup = Process.THREAD_GROUP_DEFAULT;
14729            app.adjType = "top-activity";
14730            foregroundActivities = true;
14731            interesting = true;
14732            procState = ActivityManager.PROCESS_STATE_TOP;
14733        } else if (app.instrumentationClass != null) {
14734            // Don't want to kill running instrumentation.
14735            adj = ProcessList.FOREGROUND_APP_ADJ;
14736            schedGroup = Process.THREAD_GROUP_DEFAULT;
14737            app.adjType = "instrumentation";
14738            interesting = true;
14739            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14740        } else if ((queue = isReceivingBroadcast(app)) != null) {
14741            // An app that is currently receiving a broadcast also
14742            // counts as being in the foreground for OOM killer purposes.
14743            // It's placed in a sched group based on the nature of the
14744            // broadcast as reflected by which queue it's active in.
14745            adj = ProcessList.FOREGROUND_APP_ADJ;
14746            schedGroup = (queue == mFgBroadcastQueue)
14747                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14748            app.adjType = "broadcast";
14749            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14750        } else if (app.executingServices.size() > 0) {
14751            // An app that is currently executing a service callback also
14752            // counts as being in the foreground.
14753            adj = ProcessList.FOREGROUND_APP_ADJ;
14754            schedGroup = app.execServicesFg ?
14755                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14756            app.adjType = "exec-service";
14757            procState = ActivityManager.PROCESS_STATE_SERVICE;
14758            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14759        } else {
14760            // As far as we know the process is empty.  We may change our mind later.
14761            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14762            // At this point we don't actually know the adjustment.  Use the cached adj
14763            // value that the caller wants us to.
14764            adj = cachedAdj;
14765            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14766            app.cached = true;
14767            app.empty = true;
14768            app.adjType = "cch-empty";
14769        }
14770
14771        // Examine all activities if not already foreground.
14772        if (!foregroundActivities && activitiesSize > 0) {
14773            for (int j = 0; j < activitiesSize; j++) {
14774                final ActivityRecord r = app.activities.get(j);
14775                if (r.app != app) {
14776                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14777                            + app + "?!?");
14778                    continue;
14779                }
14780                if (r.visible) {
14781                    // App has a visible activity; only upgrade adjustment.
14782                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14783                        adj = ProcessList.VISIBLE_APP_ADJ;
14784                        app.adjType = "visible";
14785                    }
14786                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14787                        procState = ActivityManager.PROCESS_STATE_TOP;
14788                    }
14789                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14790                    app.cached = false;
14791                    app.empty = false;
14792                    foregroundActivities = true;
14793                    break;
14794                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14795                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14796                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14797                        app.adjType = "pausing";
14798                    }
14799                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14800                        procState = ActivityManager.PROCESS_STATE_TOP;
14801                    }
14802                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14803                    app.cached = false;
14804                    app.empty = false;
14805                    foregroundActivities = true;
14806                } else if (r.state == ActivityState.STOPPING) {
14807                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14808                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14809                        app.adjType = "stopping";
14810                    }
14811                    // For the process state, we will at this point consider the
14812                    // process to be cached.  It will be cached either as an activity
14813                    // or empty depending on whether the activity is finishing.  We do
14814                    // this so that we can treat the process as cached for purposes of
14815                    // memory trimming (determing current memory level, trim command to
14816                    // send to process) since there can be an arbitrary number of stopping
14817                    // processes and they should soon all go into the cached state.
14818                    if (!r.finishing) {
14819                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14820                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14821                        }
14822                    }
14823                    app.cached = false;
14824                    app.empty = false;
14825                    foregroundActivities = true;
14826                } else {
14827                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14828                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14829                        app.adjType = "cch-act";
14830                    }
14831                }
14832            }
14833        }
14834
14835        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14836            if (app.foregroundServices) {
14837                // The user is aware of this app, so make it visible.
14838                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14839                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14840                app.cached = false;
14841                app.adjType = "fg-service";
14842                schedGroup = Process.THREAD_GROUP_DEFAULT;
14843            } else if (app.forcingToForeground != null) {
14844                // The user is aware of this app, so make it visible.
14845                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14846                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14847                app.cached = false;
14848                app.adjType = "force-fg";
14849                app.adjSource = app.forcingToForeground;
14850                schedGroup = Process.THREAD_GROUP_DEFAULT;
14851            }
14852        }
14853
14854        if (app.foregroundServices) {
14855            interesting = true;
14856        }
14857
14858        if (app == mHeavyWeightProcess) {
14859            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14860                // We don't want to kill the current heavy-weight process.
14861                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14862                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14863                app.cached = false;
14864                app.adjType = "heavy";
14865            }
14866            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14867                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14868            }
14869        }
14870
14871        if (app == mHomeProcess) {
14872            if (adj > ProcessList.HOME_APP_ADJ) {
14873                // This process is hosting what we currently consider to be the
14874                // home app, so we don't want to let it go into the background.
14875                adj = ProcessList.HOME_APP_ADJ;
14876                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14877                app.cached = false;
14878                app.adjType = "home";
14879            }
14880            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14881                procState = ActivityManager.PROCESS_STATE_HOME;
14882            }
14883        }
14884
14885        if (app == mPreviousProcess && app.activities.size() > 0) {
14886            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14887                // This was the previous process that showed UI to the user.
14888                // We want to try to keep it around more aggressively, to give
14889                // a good experience around switching between two apps.
14890                adj = ProcessList.PREVIOUS_APP_ADJ;
14891                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14892                app.cached = false;
14893                app.adjType = "previous";
14894            }
14895            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14896                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14897            }
14898        }
14899
14900        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14901                + " reason=" + app.adjType);
14902
14903        // By default, we use the computed adjustment.  It may be changed if
14904        // there are applications dependent on our services or providers, but
14905        // this gives us a baseline and makes sure we don't get into an
14906        // infinite recursion.
14907        app.adjSeq = mAdjSeq;
14908        app.curRawAdj = adj;
14909        app.hasStartedServices = false;
14910
14911        if (mBackupTarget != null && app == mBackupTarget.app) {
14912            // If possible we want to avoid killing apps while they're being backed up
14913            if (adj > ProcessList.BACKUP_APP_ADJ) {
14914                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14915                adj = ProcessList.BACKUP_APP_ADJ;
14916                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14917                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14918                }
14919                app.adjType = "backup";
14920                app.cached = false;
14921            }
14922            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14923                procState = ActivityManager.PROCESS_STATE_BACKUP;
14924            }
14925        }
14926
14927        boolean mayBeTop = false;
14928
14929        for (int is = app.services.size()-1;
14930                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14931                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14932                        || procState > ActivityManager.PROCESS_STATE_TOP);
14933                is--) {
14934            ServiceRecord s = app.services.valueAt(is);
14935            if (s.startRequested) {
14936                app.hasStartedServices = true;
14937                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14938                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14939                }
14940                if (app.hasShownUi && app != mHomeProcess) {
14941                    // If this process has shown some UI, let it immediately
14942                    // go to the LRU list because it may be pretty heavy with
14943                    // UI stuff.  We'll tag it with a label just to help
14944                    // debug and understand what is going on.
14945                    if (adj > ProcessList.SERVICE_ADJ) {
14946                        app.adjType = "cch-started-ui-services";
14947                    }
14948                } else {
14949                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14950                        // This service has seen some activity within
14951                        // recent memory, so we will keep its process ahead
14952                        // of the background processes.
14953                        if (adj > ProcessList.SERVICE_ADJ) {
14954                            adj = ProcessList.SERVICE_ADJ;
14955                            app.adjType = "started-services";
14956                            app.cached = false;
14957                        }
14958                    }
14959                    // If we have let the service slide into the background
14960                    // state, still have some text describing what it is doing
14961                    // even though the service no longer has an impact.
14962                    if (adj > ProcessList.SERVICE_ADJ) {
14963                        app.adjType = "cch-started-services";
14964                    }
14965                }
14966                // Don't kill this process because it is doing work; it
14967                // has said it is doing work.
14968                app.keeping = true;
14969            }
14970            for (int conni = s.connections.size()-1;
14971                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14972                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14973                            || procState > ActivityManager.PROCESS_STATE_TOP);
14974                    conni--) {
14975                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14976                for (int i = 0;
14977                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14978                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14979                                || procState > ActivityManager.PROCESS_STATE_TOP);
14980                        i++) {
14981                    // XXX should compute this based on the max of
14982                    // all connected clients.
14983                    ConnectionRecord cr = clist.get(i);
14984                    if (cr.binding.client == app) {
14985                        // Binding to ourself is not interesting.
14986                        continue;
14987                    }
14988                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14989                        ProcessRecord client = cr.binding.client;
14990                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14991                                TOP_APP, doingAll, now);
14992                        int clientProcState = client.curProcState;
14993                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14994                            // If the other app is cached for any reason, for purposes here
14995                            // we are going to consider it empty.  The specific cached state
14996                            // doesn't propagate except under certain conditions.
14997                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14998                        }
14999                        String adjType = null;
15000                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15001                            // Not doing bind OOM management, so treat
15002                            // this guy more like a started service.
15003                            if (app.hasShownUi && app != mHomeProcess) {
15004                                // If this process has shown some UI, let it immediately
15005                                // go to the LRU list because it may be pretty heavy with
15006                                // UI stuff.  We'll tag it with a label just to help
15007                                // debug and understand what is going on.
15008                                if (adj > clientAdj) {
15009                                    adjType = "cch-bound-ui-services";
15010                                }
15011                                app.cached = false;
15012                                clientAdj = adj;
15013                                clientProcState = procState;
15014                            } else {
15015                                if (now >= (s.lastActivity
15016                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15017                                    // This service has not seen activity within
15018                                    // recent memory, so allow it to drop to the
15019                                    // LRU list if there is no other reason to keep
15020                                    // it around.  We'll also tag it with a label just
15021                                    // to help debug and undertand what is going on.
15022                                    if (adj > clientAdj) {
15023                                        adjType = "cch-bound-services";
15024                                    }
15025                                    clientAdj = adj;
15026                                }
15027                            }
15028                        }
15029                        if (adj > clientAdj) {
15030                            // If this process has recently shown UI, and
15031                            // the process that is binding to it is less
15032                            // important than being visible, then we don't
15033                            // care about the binding as much as we care
15034                            // about letting this process get into the LRU
15035                            // list to be killed and restarted if needed for
15036                            // memory.
15037                            if (app.hasShownUi && app != mHomeProcess
15038                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15039                                adjType = "cch-bound-ui-services";
15040                            } else {
15041                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15042                                        |Context.BIND_IMPORTANT)) != 0) {
15043                                    adj = clientAdj;
15044                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15045                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15046                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15047                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15048                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15049                                    adj = clientAdj;
15050                                } else {
15051                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15052                                        adj = ProcessList.VISIBLE_APP_ADJ;
15053                                    }
15054                                }
15055                                if (!client.cached) {
15056                                    app.cached = false;
15057                                }
15058                                if (client.keeping) {
15059                                    app.keeping = true;
15060                                }
15061                                adjType = "service";
15062                            }
15063                        }
15064                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15065                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15066                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15067                            }
15068                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15069                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15070                                    // Special handling of clients who are in the top state.
15071                                    // We *may* want to consider this process to be in the
15072                                    // top state as well, but only if there is not another
15073                                    // reason for it to be running.  Being on the top is a
15074                                    // special state, meaning you are specifically running
15075                                    // for the current top app.  If the process is already
15076                                    // running in the background for some other reason, it
15077                                    // is more important to continue considering it to be
15078                                    // in the background state.
15079                                    mayBeTop = true;
15080                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15081                                } else {
15082                                    // Special handling for above-top states (persistent
15083                                    // processes).  These should not bring the current process
15084                                    // into the top state, since they are not on top.  Instead
15085                                    // give them the best state after that.
15086                                    clientProcState =
15087                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15088                                }
15089                            }
15090                        } else {
15091                            if (clientProcState <
15092                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15093                                clientProcState =
15094                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15095                            }
15096                        }
15097                        if (procState > clientProcState) {
15098                            procState = clientProcState;
15099                        }
15100                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15101                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15102                            app.pendingUiClean = true;
15103                        }
15104                        if (adjType != null) {
15105                            app.adjType = adjType;
15106                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15107                                    .REASON_SERVICE_IN_USE;
15108                            app.adjSource = cr.binding.client;
15109                            app.adjSourceOom = clientAdj;
15110                            app.adjTarget = s.name;
15111                        }
15112                    }
15113                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15114                        app.treatLikeActivity = true;
15115                    }
15116                    final ActivityRecord a = cr.activity;
15117                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15118                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15119                                (a.visible || a.state == ActivityState.RESUMED
15120                                 || a.state == ActivityState.PAUSING)) {
15121                            adj = ProcessList.FOREGROUND_APP_ADJ;
15122                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15123                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15124                            }
15125                            app.cached = false;
15126                            app.adjType = "service";
15127                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15128                                    .REASON_SERVICE_IN_USE;
15129                            app.adjSource = a;
15130                            app.adjSourceOom = adj;
15131                            app.adjTarget = s.name;
15132                        }
15133                    }
15134                }
15135            }
15136        }
15137
15138        for (int provi = app.pubProviders.size()-1;
15139                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15140                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15141                        || procState > ActivityManager.PROCESS_STATE_TOP);
15142                provi--) {
15143            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15144            for (int i = cpr.connections.size()-1;
15145                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15146                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15147                            || procState > ActivityManager.PROCESS_STATE_TOP);
15148                    i--) {
15149                ContentProviderConnection conn = cpr.connections.get(i);
15150                ProcessRecord client = conn.client;
15151                if (client == app) {
15152                    // Being our own client is not interesting.
15153                    continue;
15154                }
15155                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15156                int clientProcState = client.curProcState;
15157                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15158                    // If the other app is cached for any reason, for purposes here
15159                    // we are going to consider it empty.
15160                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15161                }
15162                if (adj > clientAdj) {
15163                    if (app.hasShownUi && app != mHomeProcess
15164                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15165                        app.adjType = "cch-ui-provider";
15166                    } else {
15167                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15168                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15169                        app.adjType = "provider";
15170                    }
15171                    app.cached &= client.cached;
15172                    app.keeping |= client.keeping;
15173                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15174                            .REASON_PROVIDER_IN_USE;
15175                    app.adjSource = client;
15176                    app.adjSourceOom = clientAdj;
15177                    app.adjTarget = cpr.name;
15178                }
15179                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15180                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15181                        // Special handling of clients who are in the top state.
15182                        // We *may* want to consider this process to be in the
15183                        // top state as well, but only if there is not another
15184                        // reason for it to be running.  Being on the top is a
15185                        // special state, meaning you are specifically running
15186                        // for the current top app.  If the process is already
15187                        // running in the background for some other reason, it
15188                        // is more important to continue considering it to be
15189                        // in the background state.
15190                        mayBeTop = true;
15191                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15192                    } else {
15193                        // Special handling for above-top states (persistent
15194                        // processes).  These should not bring the current process
15195                        // into the top state, since they are not on top.  Instead
15196                        // give them the best state after that.
15197                        clientProcState =
15198                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15199                    }
15200                }
15201                if (procState > clientProcState) {
15202                    procState = clientProcState;
15203                }
15204                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15205                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15206                }
15207            }
15208            // If the provider has external (non-framework) process
15209            // dependencies, ensure that its adjustment is at least
15210            // FOREGROUND_APP_ADJ.
15211            if (cpr.hasExternalProcessHandles()) {
15212                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15213                    adj = ProcessList.FOREGROUND_APP_ADJ;
15214                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15215                    app.cached = false;
15216                    app.keeping = true;
15217                    app.adjType = "provider";
15218                    app.adjTarget = cpr.name;
15219                }
15220                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15221                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15222                }
15223            }
15224        }
15225
15226        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15227            // A client of one of our services or providers is in the top state.  We
15228            // *may* want to be in the top state, but not if we are already running in
15229            // the background for some other reason.  For the decision here, we are going
15230            // to pick out a few specific states that we want to remain in when a client
15231            // is top (states that tend to be longer-term) and otherwise allow it to go
15232            // to the top state.
15233            switch (procState) {
15234                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15235                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15236                case ActivityManager.PROCESS_STATE_SERVICE:
15237                    // These all are longer-term states, so pull them up to the top
15238                    // of the background states, but not all the way to the top state.
15239                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15240                    break;
15241                default:
15242                    // Otherwise, top is a better choice, so take it.
15243                    procState = ActivityManager.PROCESS_STATE_TOP;
15244                    break;
15245            }
15246        }
15247
15248        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15249            if (app.hasClientActivities) {
15250                // This is a cached process, but with client activities.  Mark it so.
15251                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15252                app.adjType = "cch-client-act";
15253            } else if (app.treatLikeActivity) {
15254                // This is a cached process, but somebody wants us to treat it like it has
15255                // an activity, okay!
15256                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15257                app.adjType = "cch-as-act";
15258            }
15259        }
15260
15261        if (adj == ProcessList.SERVICE_ADJ) {
15262            if (doingAll) {
15263                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15264                mNewNumServiceProcs++;
15265                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15266                if (!app.serviceb) {
15267                    // This service isn't far enough down on the LRU list to
15268                    // normally be a B service, but if we are low on RAM and it
15269                    // is large we want to force it down since we would prefer to
15270                    // keep launcher over it.
15271                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15272                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15273                        app.serviceHighRam = true;
15274                        app.serviceb = true;
15275                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15276                    } else {
15277                        mNewNumAServiceProcs++;
15278                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15279                    }
15280                } else {
15281                    app.serviceHighRam = false;
15282                }
15283            }
15284            if (app.serviceb) {
15285                adj = ProcessList.SERVICE_B_ADJ;
15286            }
15287        }
15288
15289        app.curRawAdj = adj;
15290
15291        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15292        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15293        if (adj > app.maxAdj) {
15294            adj = app.maxAdj;
15295            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15296                schedGroup = Process.THREAD_GROUP_DEFAULT;
15297            }
15298        }
15299        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15300            app.keeping = true;
15301        }
15302
15303        // Do final modification to adj.  Everything we do between here and applying
15304        // the final setAdj must be done in this function, because we will also use
15305        // it when computing the final cached adj later.  Note that we don't need to
15306        // worry about this for max adj above, since max adj will always be used to
15307        // keep it out of the cached vaues.
15308        adj = app.modifyRawOomAdj(adj);
15309
15310        app.curProcState = procState;
15311
15312        int importance = app.memImportance;
15313        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15314            app.curAdj = adj;
15315            app.curSchedGroup = schedGroup;
15316            if (!interesting) {
15317                // For this reporting, if there is not something explicitly
15318                // interesting in this process then we will push it to the
15319                // background importance.
15320                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15321            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15322                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15323            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15324                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15325            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15326                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15327            } else if (adj >= ProcessList.SERVICE_ADJ) {
15328                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15329            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15330                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15331            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15332                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15333            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15334                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15335            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15336                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15337            } else {
15338                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15339            }
15340        }
15341
15342        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15343        if (foregroundActivities != app.foregroundActivities) {
15344            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15345        }
15346        if (changes != 0) {
15347            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15348            app.memImportance = importance;
15349            app.foregroundActivities = foregroundActivities;
15350            int i = mPendingProcessChanges.size()-1;
15351            ProcessChangeItem item = null;
15352            while (i >= 0) {
15353                item = mPendingProcessChanges.get(i);
15354                if (item.pid == app.pid) {
15355                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15356                    break;
15357                }
15358                i--;
15359            }
15360            if (i < 0) {
15361                // No existing item in pending changes; need a new one.
15362                final int NA = mAvailProcessChanges.size();
15363                if (NA > 0) {
15364                    item = mAvailProcessChanges.remove(NA-1);
15365                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15366                } else {
15367                    item = new ProcessChangeItem();
15368                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15369                }
15370                item.changes = 0;
15371                item.pid = app.pid;
15372                item.uid = app.info.uid;
15373                if (mPendingProcessChanges.size() == 0) {
15374                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15375                            "*** Enqueueing dispatch processes changed!");
15376                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15377                }
15378                mPendingProcessChanges.add(item);
15379            }
15380            item.changes |= changes;
15381            item.importance = importance;
15382            item.foregroundActivities = foregroundActivities;
15383            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15384                    + Integer.toHexString(System.identityHashCode(item))
15385                    + " " + app.toShortString() + ": changes=" + item.changes
15386                    + " importance=" + item.importance
15387                    + " foreground=" + item.foregroundActivities
15388                    + " type=" + app.adjType + " source=" + app.adjSource
15389                    + " target=" + app.adjTarget);
15390        }
15391
15392        return app.curRawAdj;
15393    }
15394
15395    /**
15396     * Schedule PSS collection of a process.
15397     */
15398    void requestPssLocked(ProcessRecord proc, int procState) {
15399        if (mPendingPssProcesses.contains(proc)) {
15400            return;
15401        }
15402        if (mPendingPssProcesses.size() == 0) {
15403            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15404        }
15405        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15406        proc.pssProcState = procState;
15407        mPendingPssProcesses.add(proc);
15408    }
15409
15410    /**
15411     * Schedule PSS collection of all processes.
15412     */
15413    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15414        if (!always) {
15415            if (now < (mLastFullPssTime +
15416                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15417                return;
15418            }
15419        }
15420        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15421        mLastFullPssTime = now;
15422        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15423        mPendingPssProcesses.clear();
15424        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15425            ProcessRecord app = mLruProcesses.get(i);
15426            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15427                app.pssProcState = app.setProcState;
15428                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15429                        isSleeping(), now);
15430                mPendingPssProcesses.add(app);
15431            }
15432        }
15433        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15434    }
15435
15436    /**
15437     * Ask a given process to GC right now.
15438     */
15439    final void performAppGcLocked(ProcessRecord app) {
15440        try {
15441            app.lastRequestedGc = SystemClock.uptimeMillis();
15442            if (app.thread != null) {
15443                if (app.reportLowMemory) {
15444                    app.reportLowMemory = false;
15445                    app.thread.scheduleLowMemory();
15446                } else {
15447                    app.thread.processInBackground();
15448                }
15449            }
15450        } catch (Exception e) {
15451            // whatever.
15452        }
15453    }
15454
15455    /**
15456     * Returns true if things are idle enough to perform GCs.
15457     */
15458    private final boolean canGcNowLocked() {
15459        boolean processingBroadcasts = false;
15460        for (BroadcastQueue q : mBroadcastQueues) {
15461            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15462                processingBroadcasts = true;
15463            }
15464        }
15465        return !processingBroadcasts
15466                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15467    }
15468
15469    /**
15470     * Perform GCs on all processes that are waiting for it, but only
15471     * if things are idle.
15472     */
15473    final void performAppGcsLocked() {
15474        final int N = mProcessesToGc.size();
15475        if (N <= 0) {
15476            return;
15477        }
15478        if (canGcNowLocked()) {
15479            while (mProcessesToGc.size() > 0) {
15480                ProcessRecord proc = mProcessesToGc.remove(0);
15481                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15482                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15483                            <= SystemClock.uptimeMillis()) {
15484                        // To avoid spamming the system, we will GC processes one
15485                        // at a time, waiting a few seconds between each.
15486                        performAppGcLocked(proc);
15487                        scheduleAppGcsLocked();
15488                        return;
15489                    } else {
15490                        // It hasn't been long enough since we last GCed this
15491                        // process...  put it in the list to wait for its time.
15492                        addProcessToGcListLocked(proc);
15493                        break;
15494                    }
15495                }
15496            }
15497
15498            scheduleAppGcsLocked();
15499        }
15500    }
15501
15502    /**
15503     * If all looks good, perform GCs on all processes waiting for them.
15504     */
15505    final void performAppGcsIfAppropriateLocked() {
15506        if (canGcNowLocked()) {
15507            performAppGcsLocked();
15508            return;
15509        }
15510        // Still not idle, wait some more.
15511        scheduleAppGcsLocked();
15512    }
15513
15514    /**
15515     * Schedule the execution of all pending app GCs.
15516     */
15517    final void scheduleAppGcsLocked() {
15518        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15519
15520        if (mProcessesToGc.size() > 0) {
15521            // Schedule a GC for the time to the next process.
15522            ProcessRecord proc = mProcessesToGc.get(0);
15523            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15524
15525            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15526            long now = SystemClock.uptimeMillis();
15527            if (when < (now+GC_TIMEOUT)) {
15528                when = now + GC_TIMEOUT;
15529            }
15530            mHandler.sendMessageAtTime(msg, when);
15531        }
15532    }
15533
15534    /**
15535     * Add a process to the array of processes waiting to be GCed.  Keeps the
15536     * list in sorted order by the last GC time.  The process can't already be
15537     * on the list.
15538     */
15539    final void addProcessToGcListLocked(ProcessRecord proc) {
15540        boolean added = false;
15541        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15542            if (mProcessesToGc.get(i).lastRequestedGc <
15543                    proc.lastRequestedGc) {
15544                added = true;
15545                mProcessesToGc.add(i+1, proc);
15546                break;
15547            }
15548        }
15549        if (!added) {
15550            mProcessesToGc.add(0, proc);
15551        }
15552    }
15553
15554    /**
15555     * Set up to ask a process to GC itself.  This will either do it
15556     * immediately, or put it on the list of processes to gc the next
15557     * time things are idle.
15558     */
15559    final void scheduleAppGcLocked(ProcessRecord app) {
15560        long now = SystemClock.uptimeMillis();
15561        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15562            return;
15563        }
15564        if (!mProcessesToGc.contains(app)) {
15565            addProcessToGcListLocked(app);
15566            scheduleAppGcsLocked();
15567        }
15568    }
15569
15570    final void checkExcessivePowerUsageLocked(boolean doKills) {
15571        updateCpuStatsNow();
15572
15573        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15574        boolean doWakeKills = doKills;
15575        boolean doCpuKills = doKills;
15576        if (mLastPowerCheckRealtime == 0) {
15577            doWakeKills = false;
15578        }
15579        if (mLastPowerCheckUptime == 0) {
15580            doCpuKills = false;
15581        }
15582        if (stats.isScreenOn()) {
15583            doWakeKills = false;
15584        }
15585        final long curRealtime = SystemClock.elapsedRealtime();
15586        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15587        final long curUptime = SystemClock.uptimeMillis();
15588        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15589        mLastPowerCheckRealtime = curRealtime;
15590        mLastPowerCheckUptime = curUptime;
15591        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15592            doWakeKills = false;
15593        }
15594        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15595            doCpuKills = false;
15596        }
15597        int i = mLruProcesses.size();
15598        while (i > 0) {
15599            i--;
15600            ProcessRecord app = mLruProcesses.get(i);
15601            if (!app.keeping) {
15602                long wtime;
15603                synchronized (stats) {
15604                    wtime = stats.getProcessWakeTime(app.info.uid,
15605                            app.pid, curRealtime);
15606                }
15607                long wtimeUsed = wtime - app.lastWakeTime;
15608                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15609                if (DEBUG_POWER) {
15610                    StringBuilder sb = new StringBuilder(128);
15611                    sb.append("Wake for ");
15612                    app.toShortString(sb);
15613                    sb.append(": over ");
15614                    TimeUtils.formatDuration(realtimeSince, sb);
15615                    sb.append(" used ");
15616                    TimeUtils.formatDuration(wtimeUsed, sb);
15617                    sb.append(" (");
15618                    sb.append((wtimeUsed*100)/realtimeSince);
15619                    sb.append("%)");
15620                    Slog.i(TAG, sb.toString());
15621                    sb.setLength(0);
15622                    sb.append("CPU for ");
15623                    app.toShortString(sb);
15624                    sb.append(": over ");
15625                    TimeUtils.formatDuration(uptimeSince, sb);
15626                    sb.append(" used ");
15627                    TimeUtils.formatDuration(cputimeUsed, sb);
15628                    sb.append(" (");
15629                    sb.append((cputimeUsed*100)/uptimeSince);
15630                    sb.append("%)");
15631                    Slog.i(TAG, sb.toString());
15632                }
15633                // If a process has held a wake lock for more
15634                // than 50% of the time during this period,
15635                // that sounds bad.  Kill!
15636                if (doWakeKills && realtimeSince > 0
15637                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15638                    synchronized (stats) {
15639                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15640                                realtimeSince, wtimeUsed);
15641                    }
15642                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15643                            + " during " + realtimeSince);
15644                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15645                } else if (doCpuKills && uptimeSince > 0
15646                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15647                    synchronized (stats) {
15648                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15649                                uptimeSince, cputimeUsed);
15650                    }
15651                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15652                            + " during " + uptimeSince);
15653                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15654                } else {
15655                    app.lastWakeTime = wtime;
15656                    app.lastCpuTime = app.curCpuTime;
15657                }
15658            }
15659        }
15660    }
15661
15662    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15663            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15664        boolean success = true;
15665
15666        if (app.curRawAdj != app.setRawAdj) {
15667            if (wasKeeping && !app.keeping) {
15668                // This app is no longer something we want to keep.  Note
15669                // its current wake lock time to later know to kill it if
15670                // it is not behaving well.
15671                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15672                synchronized (stats) {
15673                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15674                            app.pid, SystemClock.elapsedRealtime());
15675                }
15676                app.lastCpuTime = app.curCpuTime;
15677            }
15678
15679            app.setRawAdj = app.curRawAdj;
15680        }
15681
15682        if (app.curAdj != app.setAdj) {
15683            ProcessList.setOomAdj(app.pid, app.curAdj);
15684            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15685                TAG, "Set " + app.pid + " " + app.processName +
15686                " adj " + app.curAdj + ": " + app.adjType);
15687            app.setAdj = app.curAdj;
15688        }
15689
15690        if (app.setSchedGroup != app.curSchedGroup) {
15691            app.setSchedGroup = app.curSchedGroup;
15692            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15693                    "Setting process group of " + app.processName
15694                    + " to " + app.curSchedGroup);
15695            if (app.waitingToKill != null &&
15696                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15697                killUnneededProcessLocked(app, app.waitingToKill);
15698                success = false;
15699            } else {
15700                if (true) {
15701                    long oldId = Binder.clearCallingIdentity();
15702                    try {
15703                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15704                    } catch (Exception e) {
15705                        Slog.w(TAG, "Failed setting process group of " + app.pid
15706                                + " to " + app.curSchedGroup);
15707                        e.printStackTrace();
15708                    } finally {
15709                        Binder.restoreCallingIdentity(oldId);
15710                    }
15711                } else {
15712                    if (app.thread != null) {
15713                        try {
15714                            app.thread.setSchedulingGroup(app.curSchedGroup);
15715                        } catch (RemoteException e) {
15716                        }
15717                    }
15718                }
15719                Process.setSwappiness(app.pid,
15720                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15721            }
15722        }
15723        if (app.repProcState != app.curProcState) {
15724            app.repProcState = app.curProcState;
15725            if (!reportingProcessState && app.thread != null) {
15726                try {
15727                    if (false) {
15728                        //RuntimeException h = new RuntimeException("here");
15729                        Slog.i(TAG, "Sending new process state " + app.repProcState
15730                                + " to " + app /*, h*/);
15731                    }
15732                    app.thread.setProcessState(app.repProcState);
15733                } catch (RemoteException e) {
15734                }
15735            }
15736        }
15737        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15738                app.setProcState)) {
15739            app.lastStateTime = now;
15740            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15741                    isSleeping(), now);
15742            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15743                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15744                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15745                    + (app.nextPssTime-now) + ": " + app);
15746        } else {
15747            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15748                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15749                requestPssLocked(app, app.setProcState);
15750                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15751                        isSleeping(), now);
15752            } else if (false && DEBUG_PSS) {
15753                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15754            }
15755        }
15756        if (app.setProcState != app.curProcState) {
15757            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15758                    "Proc state change of " + app.processName
15759                    + " to " + app.curProcState);
15760            app.setProcState = app.curProcState;
15761            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15762                app.notCachedSinceIdle = false;
15763            }
15764            if (!doingAll) {
15765                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15766            } else {
15767                app.procStateChanged = true;
15768            }
15769        }
15770        return success;
15771    }
15772
15773    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15774        if (proc.thread != null && proc.baseProcessTracker != null) {
15775            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15776        }
15777    }
15778
15779    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15780            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15781        if (app.thread == null) {
15782            return false;
15783        }
15784
15785        final boolean wasKeeping = app.keeping;
15786
15787        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15788
15789        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15790                reportingProcessState, now);
15791    }
15792
15793    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15794            boolean oomAdj) {
15795        if (isForeground != proc.foregroundServices) {
15796            proc.foregroundServices = isForeground;
15797            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15798                    proc.info.uid);
15799            if (isForeground) {
15800                if (curProcs == null) {
15801                    curProcs = new ArrayList<ProcessRecord>();
15802                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15803                }
15804                if (!curProcs.contains(proc)) {
15805                    curProcs.add(proc);
15806                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15807                            proc.info.packageName, proc.info.uid);
15808                }
15809            } else {
15810                if (curProcs != null) {
15811                    if (curProcs.remove(proc)) {
15812                        mBatteryStatsService.noteEvent(
15813                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15814                                proc.info.packageName, proc.info.uid);
15815                        if (curProcs.size() <= 0) {
15816                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15817                        }
15818                    }
15819                }
15820            }
15821            if (oomAdj) {
15822                updateOomAdjLocked();
15823            }
15824        }
15825    }
15826
15827    private final ActivityRecord resumedAppLocked() {
15828        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15829        String pkg;
15830        int uid;
15831        if (act != null && !act.sleeping) {
15832            pkg = act.packageName;
15833            uid = act.info.applicationInfo.uid;
15834        } else {
15835            pkg = null;
15836            uid = -1;
15837        }
15838        // Has the UID or resumed package name changed?
15839        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15840                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15841            if (mCurResumedPackage != null) {
15842                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15843                        mCurResumedPackage, mCurResumedUid);
15844            }
15845            mCurResumedPackage = pkg;
15846            mCurResumedUid = uid;
15847            if (mCurResumedPackage != null) {
15848                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15849                        mCurResumedPackage, mCurResumedUid);
15850            }
15851        }
15852        return act;
15853    }
15854
15855    final boolean updateOomAdjLocked(ProcessRecord app) {
15856        return updateOomAdjLocked(app, false);
15857    }
15858
15859    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15860        final ActivityRecord TOP_ACT = resumedAppLocked();
15861        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15862        final boolean wasCached = app.cached;
15863
15864        mAdjSeq++;
15865
15866        // This is the desired cached adjusment we want to tell it to use.
15867        // If our app is currently cached, we know it, and that is it.  Otherwise,
15868        // we don't know it yet, and it needs to now be cached we will then
15869        // need to do a complete oom adj.
15870        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15871                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15872        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15873                SystemClock.uptimeMillis());
15874        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15875            // Changed to/from cached state, so apps after it in the LRU
15876            // list may also be changed.
15877            updateOomAdjLocked();
15878        }
15879        return success;
15880    }
15881
15882    final void updateOomAdjLocked() {
15883        final ActivityRecord TOP_ACT = resumedAppLocked();
15884        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15885        final long now = SystemClock.uptimeMillis();
15886        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15887        final int N = mLruProcesses.size();
15888
15889        if (false) {
15890            RuntimeException e = new RuntimeException();
15891            e.fillInStackTrace();
15892            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15893        }
15894
15895        mAdjSeq++;
15896        mNewNumServiceProcs = 0;
15897        mNewNumAServiceProcs = 0;
15898
15899        final int emptyProcessLimit;
15900        final int cachedProcessLimit;
15901        if (mProcessLimit <= 0) {
15902            emptyProcessLimit = cachedProcessLimit = 0;
15903        } else if (mProcessLimit == 1) {
15904            emptyProcessLimit = 1;
15905            cachedProcessLimit = 0;
15906        } else {
15907            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15908            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15909        }
15910
15911        // Let's determine how many processes we have running vs.
15912        // how many slots we have for background processes; we may want
15913        // to put multiple processes in a slot of there are enough of
15914        // them.
15915        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15916                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15917        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15918        if (numEmptyProcs > cachedProcessLimit) {
15919            // If there are more empty processes than our limit on cached
15920            // processes, then use the cached process limit for the factor.
15921            // This ensures that the really old empty processes get pushed
15922            // down to the bottom, so if we are running low on memory we will
15923            // have a better chance at keeping around more cached processes
15924            // instead of a gazillion empty processes.
15925            numEmptyProcs = cachedProcessLimit;
15926        }
15927        int emptyFactor = numEmptyProcs/numSlots;
15928        if (emptyFactor < 1) emptyFactor = 1;
15929        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15930        if (cachedFactor < 1) cachedFactor = 1;
15931        int stepCached = 0;
15932        int stepEmpty = 0;
15933        int numCached = 0;
15934        int numEmpty = 0;
15935        int numTrimming = 0;
15936
15937        mNumNonCachedProcs = 0;
15938        mNumCachedHiddenProcs = 0;
15939
15940        // First update the OOM adjustment for each of the
15941        // application processes based on their current state.
15942        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15943        int nextCachedAdj = curCachedAdj+1;
15944        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15945        int nextEmptyAdj = curEmptyAdj+2;
15946        for (int i=N-1; i>=0; i--) {
15947            ProcessRecord app = mLruProcesses.get(i);
15948            if (!app.killedByAm && app.thread != null) {
15949                app.procStateChanged = false;
15950                final boolean wasKeeping = app.keeping;
15951                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15952
15953                // If we haven't yet assigned the final cached adj
15954                // to the process, do that now.
15955                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15956                    switch (app.curProcState) {
15957                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15958                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15959                            // This process is a cached process holding activities...
15960                            // assign it the next cached value for that type, and then
15961                            // step that cached level.
15962                            app.curRawAdj = curCachedAdj;
15963                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15964                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15965                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15966                                    + ")");
15967                            if (curCachedAdj != nextCachedAdj) {
15968                                stepCached++;
15969                                if (stepCached >= cachedFactor) {
15970                                    stepCached = 0;
15971                                    curCachedAdj = nextCachedAdj;
15972                                    nextCachedAdj += 2;
15973                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15974                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15975                                    }
15976                                }
15977                            }
15978                            break;
15979                        default:
15980                            // For everything else, assign next empty cached process
15981                            // level and bump that up.  Note that this means that
15982                            // long-running services that have dropped down to the
15983                            // cached level will be treated as empty (since their process
15984                            // state is still as a service), which is what we want.
15985                            app.curRawAdj = curEmptyAdj;
15986                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15987                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15988                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15989                                    + ")");
15990                            if (curEmptyAdj != nextEmptyAdj) {
15991                                stepEmpty++;
15992                                if (stepEmpty >= emptyFactor) {
15993                                    stepEmpty = 0;
15994                                    curEmptyAdj = nextEmptyAdj;
15995                                    nextEmptyAdj += 2;
15996                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15997                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15998                                    }
15999                                }
16000                            }
16001                            break;
16002                    }
16003                }
16004
16005                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
16006
16007                // Count the number of process types.
16008                switch (app.curProcState) {
16009                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16010                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16011                        mNumCachedHiddenProcs++;
16012                        numCached++;
16013                        if (numCached > cachedProcessLimit) {
16014                            killUnneededProcessLocked(app, "cached #" + numCached);
16015                        }
16016                        break;
16017                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16018                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16019                                && app.lastActivityTime < oldTime) {
16020                            killUnneededProcessLocked(app, "empty for "
16021                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16022                                    / 1000) + "s");
16023                        } else {
16024                            numEmpty++;
16025                            if (numEmpty > emptyProcessLimit) {
16026                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16027                            }
16028                        }
16029                        break;
16030                    default:
16031                        mNumNonCachedProcs++;
16032                        break;
16033                }
16034
16035                if (app.isolated && app.services.size() <= 0) {
16036                    // If this is an isolated process, and there are no
16037                    // services running in it, then the process is no longer
16038                    // needed.  We agressively kill these because we can by
16039                    // definition not re-use the same process again, and it is
16040                    // good to avoid having whatever code was running in them
16041                    // left sitting around after no longer needed.
16042                    killUnneededProcessLocked(app, "isolated not needed");
16043                }
16044
16045                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16046                        && !app.killedByAm) {
16047                    numTrimming++;
16048                }
16049            }
16050        }
16051
16052        mNumServiceProcs = mNewNumServiceProcs;
16053
16054        // Now determine the memory trimming level of background processes.
16055        // Unfortunately we need to start at the back of the list to do this
16056        // properly.  We only do this if the number of background apps we
16057        // are managing to keep around is less than half the maximum we desire;
16058        // if we are keeping a good number around, we'll let them use whatever
16059        // memory they want.
16060        final int numCachedAndEmpty = numCached + numEmpty;
16061        int memFactor;
16062        if (numCached <= ProcessList.TRIM_CACHED_APPS
16063                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16064            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16065                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16066            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16067                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16068            } else {
16069                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16070            }
16071        } else {
16072            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16073        }
16074        // We always allow the memory level to go up (better).  We only allow it to go
16075        // down if we are in a state where that is allowed, *and* the total number of processes
16076        // has gone down since last time.
16077        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16078                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16079                + " last=" + mLastNumProcesses);
16080        if (memFactor > mLastMemoryLevel) {
16081            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16082                memFactor = mLastMemoryLevel;
16083                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16084            }
16085        }
16086        mLastMemoryLevel = memFactor;
16087        mLastNumProcesses = mLruProcesses.size();
16088        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16089        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16090        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16091            if (mLowRamStartTime == 0) {
16092                mLowRamStartTime = now;
16093            }
16094            int step = 0;
16095            int fgTrimLevel;
16096            switch (memFactor) {
16097                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16098                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16099                    break;
16100                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16101                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16102                    break;
16103                default:
16104                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16105                    break;
16106            }
16107            int factor = numTrimming/3;
16108            int minFactor = 2;
16109            if (mHomeProcess != null) minFactor++;
16110            if (mPreviousProcess != null) minFactor++;
16111            if (factor < minFactor) factor = minFactor;
16112            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16113            for (int i=N-1; i>=0; i--) {
16114                ProcessRecord app = mLruProcesses.get(i);
16115                if (allChanged || app.procStateChanged) {
16116                    setProcessTrackerState(app, trackerMemFactor, now);
16117                    app.procStateChanged = false;
16118                }
16119                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16120                        && !app.killedByAm) {
16121                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16122                        try {
16123                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16124                                    "Trimming memory of " + app.processName
16125                                    + " to " + curLevel);
16126                            app.thread.scheduleTrimMemory(curLevel);
16127                        } catch (RemoteException e) {
16128                        }
16129                        if (false) {
16130                            // For now we won't do this; our memory trimming seems
16131                            // to be good enough at this point that destroying
16132                            // activities causes more harm than good.
16133                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16134                                    && app != mHomeProcess && app != mPreviousProcess) {
16135                                // Need to do this on its own message because the stack may not
16136                                // be in a consistent state at this point.
16137                                // For these apps we will also finish their activities
16138                                // to help them free memory.
16139                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16140                            }
16141                        }
16142                    }
16143                    app.trimMemoryLevel = curLevel;
16144                    step++;
16145                    if (step >= factor) {
16146                        step = 0;
16147                        switch (curLevel) {
16148                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16149                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16150                                break;
16151                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16152                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16153                                break;
16154                        }
16155                    }
16156                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16157                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16158                            && app.thread != null) {
16159                        try {
16160                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16161                                    "Trimming memory of heavy-weight " + app.processName
16162                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16163                            app.thread.scheduleTrimMemory(
16164                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16165                        } catch (RemoteException e) {
16166                        }
16167                    }
16168                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16169                } else {
16170                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16171                            || app.systemNoUi) && app.pendingUiClean) {
16172                        // If this application is now in the background and it
16173                        // had done UI, then give it the special trim level to
16174                        // have it free UI resources.
16175                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16176                        if (app.trimMemoryLevel < level && app.thread != null) {
16177                            try {
16178                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16179                                        "Trimming memory of bg-ui " + app.processName
16180                                        + " to " + level);
16181                                app.thread.scheduleTrimMemory(level);
16182                            } catch (RemoteException e) {
16183                            }
16184                        }
16185                        app.pendingUiClean = false;
16186                    }
16187                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16188                        try {
16189                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16190                                    "Trimming memory of fg " + app.processName
16191                                    + " to " + fgTrimLevel);
16192                            app.thread.scheduleTrimMemory(fgTrimLevel);
16193                        } catch (RemoteException e) {
16194                        }
16195                    }
16196                    app.trimMemoryLevel = fgTrimLevel;
16197                }
16198            }
16199        } else {
16200            if (mLowRamStartTime != 0) {
16201                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16202                mLowRamStartTime = 0;
16203            }
16204            for (int i=N-1; i>=0; i--) {
16205                ProcessRecord app = mLruProcesses.get(i);
16206                if (allChanged || app.procStateChanged) {
16207                    setProcessTrackerState(app, trackerMemFactor, now);
16208                    app.procStateChanged = false;
16209                }
16210                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16211                        || app.systemNoUi) && app.pendingUiClean) {
16212                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16213                            && app.thread != null) {
16214                        try {
16215                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16216                                    "Trimming memory of ui hidden " + app.processName
16217                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16218                            app.thread.scheduleTrimMemory(
16219                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16220                        } catch (RemoteException e) {
16221                        }
16222                    }
16223                    app.pendingUiClean = false;
16224                }
16225                app.trimMemoryLevel = 0;
16226            }
16227        }
16228
16229        if (mAlwaysFinishActivities) {
16230            // Need to do this on its own message because the stack may not
16231            // be in a consistent state at this point.
16232            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16233        }
16234
16235        if (allChanged) {
16236            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16237        }
16238
16239        if (mProcessStats.shouldWriteNowLocked(now)) {
16240            mHandler.post(new Runnable() {
16241                @Override public void run() {
16242                    synchronized (ActivityManagerService.this) {
16243                        mProcessStats.writeStateAsyncLocked();
16244                    }
16245                }
16246            });
16247        }
16248
16249        if (DEBUG_OOM_ADJ) {
16250            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16251        }
16252    }
16253
16254    final void trimApplications() {
16255        synchronized (this) {
16256            int i;
16257
16258            // First remove any unused application processes whose package
16259            // has been removed.
16260            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16261                final ProcessRecord app = mRemovedProcesses.get(i);
16262                if (app.activities.size() == 0
16263                        && app.curReceiver == null && app.services.size() == 0) {
16264                    Slog.i(
16265                        TAG, "Exiting empty application process "
16266                        + app.processName + " ("
16267                        + (app.thread != null ? app.thread.asBinder() : null)
16268                        + ")\n");
16269                    if (app.pid > 0 && app.pid != MY_PID) {
16270                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16271                                app.processName, app.setAdj, "empty");
16272                        app.killedByAm = true;
16273                        Process.killProcessQuiet(app.pid);
16274                    } else {
16275                        try {
16276                            app.thread.scheduleExit();
16277                        } catch (Exception e) {
16278                            // Ignore exceptions.
16279                        }
16280                    }
16281                    cleanUpApplicationRecordLocked(app, false, true, -1);
16282                    mRemovedProcesses.remove(i);
16283
16284                    if (app.persistent) {
16285                        if (app.persistent) {
16286                            addAppLocked(app.info, false);
16287                        }
16288                    }
16289                }
16290            }
16291
16292            // Now update the oom adj for all processes.
16293            updateOomAdjLocked();
16294        }
16295    }
16296
16297    /** This method sends the specified signal to each of the persistent apps */
16298    public void signalPersistentProcesses(int sig) throws RemoteException {
16299        if (sig != Process.SIGNAL_USR1) {
16300            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16301        }
16302
16303        synchronized (this) {
16304            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16305                    != PackageManager.PERMISSION_GRANTED) {
16306                throw new SecurityException("Requires permission "
16307                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16308            }
16309
16310            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16311                ProcessRecord r = mLruProcesses.get(i);
16312                if (r.thread != null && r.persistent) {
16313                    Process.sendSignal(r.pid, sig);
16314                }
16315            }
16316        }
16317    }
16318
16319    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16320        if (proc == null || proc == mProfileProc) {
16321            proc = mProfileProc;
16322            path = mProfileFile;
16323            profileType = mProfileType;
16324            clearProfilerLocked();
16325        }
16326        if (proc == null) {
16327            return;
16328        }
16329        try {
16330            proc.thread.profilerControl(false, path, null, profileType);
16331        } catch (RemoteException e) {
16332            throw new IllegalStateException("Process disappeared");
16333        }
16334    }
16335
16336    private void clearProfilerLocked() {
16337        if (mProfileFd != null) {
16338            try {
16339                mProfileFd.close();
16340            } catch (IOException e) {
16341            }
16342        }
16343        mProfileApp = null;
16344        mProfileProc = null;
16345        mProfileFile = null;
16346        mProfileType = 0;
16347        mAutoStopProfiler = false;
16348    }
16349
16350    public boolean profileControl(String process, int userId, boolean start,
16351            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16352
16353        try {
16354            synchronized (this) {
16355                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16356                // its own permission.
16357                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16358                        != PackageManager.PERMISSION_GRANTED) {
16359                    throw new SecurityException("Requires permission "
16360                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16361                }
16362
16363                if (start && fd == null) {
16364                    throw new IllegalArgumentException("null fd");
16365                }
16366
16367                ProcessRecord proc = null;
16368                if (process != null) {
16369                    proc = findProcessLocked(process, userId, "profileControl");
16370                }
16371
16372                if (start && (proc == null || proc.thread == null)) {
16373                    throw new IllegalArgumentException("Unknown process: " + process);
16374                }
16375
16376                if (start) {
16377                    stopProfilerLocked(null, null, 0);
16378                    setProfileApp(proc.info, proc.processName, path, fd, false);
16379                    mProfileProc = proc;
16380                    mProfileType = profileType;
16381                    try {
16382                        fd = fd.dup();
16383                    } catch (IOException e) {
16384                        fd = null;
16385                    }
16386                    proc.thread.profilerControl(start, path, fd, profileType);
16387                    fd = null;
16388                    mProfileFd = null;
16389                } else {
16390                    stopProfilerLocked(proc, path, profileType);
16391                    if (fd != null) {
16392                        try {
16393                            fd.close();
16394                        } catch (IOException e) {
16395                        }
16396                    }
16397                }
16398
16399                return true;
16400            }
16401        } catch (RemoteException e) {
16402            throw new IllegalStateException("Process disappeared");
16403        } finally {
16404            if (fd != null) {
16405                try {
16406                    fd.close();
16407                } catch (IOException e) {
16408                }
16409            }
16410        }
16411    }
16412
16413    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16414        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16415                userId, true, true, callName, null);
16416        ProcessRecord proc = null;
16417        try {
16418            int pid = Integer.parseInt(process);
16419            synchronized (mPidsSelfLocked) {
16420                proc = mPidsSelfLocked.get(pid);
16421            }
16422        } catch (NumberFormatException e) {
16423        }
16424
16425        if (proc == null) {
16426            ArrayMap<String, SparseArray<ProcessRecord>> all
16427                    = mProcessNames.getMap();
16428            SparseArray<ProcessRecord> procs = all.get(process);
16429            if (procs != null && procs.size() > 0) {
16430                proc = procs.valueAt(0);
16431                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16432                    for (int i=1; i<procs.size(); i++) {
16433                        ProcessRecord thisProc = procs.valueAt(i);
16434                        if (thisProc.userId == userId) {
16435                            proc = thisProc;
16436                            break;
16437                        }
16438                    }
16439                }
16440            }
16441        }
16442
16443        return proc;
16444    }
16445
16446    public boolean dumpHeap(String process, int userId, boolean managed,
16447            String path, ParcelFileDescriptor fd) throws RemoteException {
16448
16449        try {
16450            synchronized (this) {
16451                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16452                // its own permission (same as profileControl).
16453                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16454                        != PackageManager.PERMISSION_GRANTED) {
16455                    throw new SecurityException("Requires permission "
16456                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16457                }
16458
16459                if (fd == null) {
16460                    throw new IllegalArgumentException("null fd");
16461                }
16462
16463                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16464                if (proc == null || proc.thread == null) {
16465                    throw new IllegalArgumentException("Unknown process: " + process);
16466                }
16467
16468                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16469                if (!isDebuggable) {
16470                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16471                        throw new SecurityException("Process not debuggable: " + proc);
16472                    }
16473                }
16474
16475                proc.thread.dumpHeap(managed, path, fd);
16476                fd = null;
16477                return true;
16478            }
16479        } catch (RemoteException e) {
16480            throw new IllegalStateException("Process disappeared");
16481        } finally {
16482            if (fd != null) {
16483                try {
16484                    fd.close();
16485                } catch (IOException e) {
16486                }
16487            }
16488        }
16489    }
16490
16491    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16492    public void monitor() {
16493        synchronized (this) { }
16494    }
16495
16496    void onCoreSettingsChange(Bundle settings) {
16497        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16498            ProcessRecord processRecord = mLruProcesses.get(i);
16499            try {
16500                if (processRecord.thread != null) {
16501                    processRecord.thread.setCoreSettings(settings);
16502                }
16503            } catch (RemoteException re) {
16504                /* ignore */
16505            }
16506        }
16507    }
16508
16509    // Multi-user methods
16510
16511    /**
16512     * Start user, if its not already running, but don't bring it to foreground.
16513     */
16514    @Override
16515    public boolean startUserInBackground(final int userId) {
16516        return startUser(userId, /* foreground */ false);
16517    }
16518
16519    /**
16520     * Refreshes the list of users related to the current user when either a
16521     * user switch happens or when a new related user is started in the
16522     * background.
16523     */
16524    private void updateCurrentProfileIdsLocked() {
16525        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16526                mCurrentUserId, false /* enabledOnly */);
16527        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16528        for (int i = 0; i < currentProfileIds.length; i++) {
16529            currentProfileIds[i] = profiles.get(i).id;
16530        }
16531        mCurrentProfileIds = currentProfileIds;
16532    }
16533
16534    private Set getProfileIdsLocked(int userId) {
16535        Set userIds = new HashSet<Integer>();
16536        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16537                userId, false /* enabledOnly */);
16538        for (UserInfo user : profiles) {
16539            userIds.add(Integer.valueOf(user.id));
16540        }
16541        return userIds;
16542    }
16543
16544    @Override
16545    public boolean switchUser(final int userId) {
16546        return startUser(userId, /* foregound */ true);
16547    }
16548
16549    private boolean startUser(final int userId, boolean foreground) {
16550        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16551                != PackageManager.PERMISSION_GRANTED) {
16552            String msg = "Permission Denial: switchUser() from pid="
16553                    + Binder.getCallingPid()
16554                    + ", uid=" + Binder.getCallingUid()
16555                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16556            Slog.w(TAG, msg);
16557            throw new SecurityException(msg);
16558        }
16559
16560        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16561
16562        final long ident = Binder.clearCallingIdentity();
16563        try {
16564            synchronized (this) {
16565                final int oldUserId = mCurrentUserId;
16566                if (oldUserId == userId) {
16567                    return true;
16568                }
16569
16570                mStackSupervisor.setLockTaskModeLocked(null);
16571
16572                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16573                if (userInfo == null) {
16574                    Slog.w(TAG, "No user info for user #" + userId);
16575                    return false;
16576                }
16577
16578                if (foreground) {
16579                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16580                            R.anim.screen_user_enter);
16581                }
16582
16583                boolean needStart = false;
16584
16585                // If the user we are switching to is not currently started, then
16586                // we need to start it now.
16587                if (mStartedUsers.get(userId) == null) {
16588                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16589                    updateStartedUserArrayLocked();
16590                    needStart = true;
16591                }
16592
16593                final Integer userIdInt = Integer.valueOf(userId);
16594                mUserLru.remove(userIdInt);
16595                mUserLru.add(userIdInt);
16596
16597                if (foreground) {
16598                    mCurrentUserId = userId;
16599                    updateCurrentProfileIdsLocked();
16600                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16601                    // Once the internal notion of the active user has switched, we lock the device
16602                    // with the option to show the user switcher on the keyguard.
16603                    mWindowManager.lockNow(null);
16604                } else {
16605                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16606                    updateCurrentProfileIdsLocked();
16607                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16608                    mUserLru.remove(currentUserIdInt);
16609                    mUserLru.add(currentUserIdInt);
16610                }
16611
16612                final UserStartedState uss = mStartedUsers.get(userId);
16613
16614                // Make sure user is in the started state.  If it is currently
16615                // stopping, we need to knock that off.
16616                if (uss.mState == UserStartedState.STATE_STOPPING) {
16617                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16618                    // so we can just fairly silently bring the user back from
16619                    // the almost-dead.
16620                    uss.mState = UserStartedState.STATE_RUNNING;
16621                    updateStartedUserArrayLocked();
16622                    needStart = true;
16623                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16624                    // This means ACTION_SHUTDOWN has been sent, so we will
16625                    // need to treat this as a new boot of the user.
16626                    uss.mState = UserStartedState.STATE_BOOTING;
16627                    updateStartedUserArrayLocked();
16628                    needStart = true;
16629                }
16630
16631                if (uss.mState == UserStartedState.STATE_BOOTING) {
16632                    // Booting up a new user, need to tell system services about it.
16633                    // Note that this is on the same handler as scheduling of broadcasts,
16634                    // which is important because it needs to go first.
16635                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16636                }
16637
16638                if (foreground) {
16639                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16640                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16641                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16642                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16643                            oldUserId, userId, uss));
16644                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16645                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16646                }
16647
16648                if (needStart) {
16649                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16650                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16651                            | Intent.FLAG_RECEIVER_FOREGROUND);
16652                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16653                    broadcastIntentLocked(null, null, intent,
16654                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16655                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16656                }
16657
16658                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16659                    if (userId != 0) {
16660                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16661                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16662                        broadcastIntentLocked(null, null, intent, null,
16663                                new IIntentReceiver.Stub() {
16664                                    public void performReceive(Intent intent, int resultCode,
16665                                            String data, Bundle extras, boolean ordered,
16666                                            boolean sticky, int sendingUser) {
16667                                        userInitialized(uss, userId);
16668                                    }
16669                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16670                                true, false, MY_PID, Process.SYSTEM_UID,
16671                                userId);
16672                        uss.initializing = true;
16673                    } else {
16674                        getUserManagerLocked().makeInitialized(userInfo.id);
16675                    }
16676                }
16677
16678                if (foreground) {
16679                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16680                    if (homeInFront) {
16681                        startHomeActivityLocked(userId);
16682                    } else {
16683                        mStackSupervisor.resumeTopActivitiesLocked();
16684                    }
16685                    EventLogTags.writeAmSwitchUser(userId);
16686                    getUserManagerLocked().userForeground(userId);
16687                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16688                }
16689
16690                if (needStart) {
16691                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16692                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16693                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16694                    broadcastIntentLocked(null, null, intent,
16695                            null, new IIntentReceiver.Stub() {
16696                                @Override
16697                                public void performReceive(Intent intent, int resultCode, String data,
16698                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16699                                        throws RemoteException {
16700                                }
16701                            }, 0, null, null,
16702                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16703                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16704                }
16705            }
16706        } finally {
16707            Binder.restoreCallingIdentity(ident);
16708        }
16709
16710        return true;
16711    }
16712
16713    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16714        long ident = Binder.clearCallingIdentity();
16715        try {
16716            Intent intent;
16717            if (oldUserId >= 0) {
16718                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16719                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16720                        | Intent.FLAG_RECEIVER_FOREGROUND);
16721                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16722                broadcastIntentLocked(null, null, intent,
16723                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16724                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16725            }
16726            if (newUserId >= 0) {
16727                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16728                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16729                        | Intent.FLAG_RECEIVER_FOREGROUND);
16730                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16731                broadcastIntentLocked(null, null, intent,
16732                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16733                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16734                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16735                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16736                        | Intent.FLAG_RECEIVER_FOREGROUND);
16737                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16738                broadcastIntentLocked(null, null, intent,
16739                        null, null, 0, null, null,
16740                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16741                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16742            }
16743        } finally {
16744            Binder.restoreCallingIdentity(ident);
16745        }
16746    }
16747
16748    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16749            final int newUserId) {
16750        final int N = mUserSwitchObservers.beginBroadcast();
16751        if (N > 0) {
16752            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16753                int mCount = 0;
16754                @Override
16755                public void sendResult(Bundle data) throws RemoteException {
16756                    synchronized (ActivityManagerService.this) {
16757                        if (mCurUserSwitchCallback == this) {
16758                            mCount++;
16759                            if (mCount == N) {
16760                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16761                            }
16762                        }
16763                    }
16764                }
16765            };
16766            synchronized (this) {
16767                uss.switching = true;
16768                mCurUserSwitchCallback = callback;
16769            }
16770            for (int i=0; i<N; i++) {
16771                try {
16772                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16773                            newUserId, callback);
16774                } catch (RemoteException e) {
16775                }
16776            }
16777        } else {
16778            synchronized (this) {
16779                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16780            }
16781        }
16782        mUserSwitchObservers.finishBroadcast();
16783    }
16784
16785    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16786        synchronized (this) {
16787            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16788            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16789        }
16790    }
16791
16792    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16793        mCurUserSwitchCallback = null;
16794        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16795        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16796                oldUserId, newUserId, uss));
16797    }
16798
16799    void userInitialized(UserStartedState uss, int newUserId) {
16800        completeSwitchAndInitalize(uss, newUserId, true, false);
16801    }
16802
16803    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16804        completeSwitchAndInitalize(uss, newUserId, false, true);
16805    }
16806
16807    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16808            boolean clearInitializing, boolean clearSwitching) {
16809        boolean unfrozen = false;
16810        synchronized (this) {
16811            if (clearInitializing) {
16812                uss.initializing = false;
16813                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16814            }
16815            if (clearSwitching) {
16816                uss.switching = false;
16817            }
16818            if (!uss.switching && !uss.initializing) {
16819                mWindowManager.stopFreezingScreen();
16820                unfrozen = true;
16821            }
16822        }
16823        if (unfrozen) {
16824            final int N = mUserSwitchObservers.beginBroadcast();
16825            for (int i=0; i<N; i++) {
16826                try {
16827                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16828                } catch (RemoteException e) {
16829                }
16830            }
16831            mUserSwitchObservers.finishBroadcast();
16832        }
16833    }
16834
16835    void scheduleStartProfilesLocked() {
16836        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16837            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16838                    DateUtils.SECOND_IN_MILLIS);
16839        }
16840    }
16841
16842    void startProfilesLocked() {
16843        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16844        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16845                mCurrentUserId, false /* enabledOnly */);
16846        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16847        for (UserInfo user : profiles) {
16848            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16849                    && user.id != mCurrentUserId) {
16850                toStart.add(user);
16851            }
16852        }
16853        final int n = toStart.size();
16854        int i = 0;
16855        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16856            startUserInBackground(toStart.get(i).id);
16857        }
16858        if (i < n) {
16859            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16860        }
16861    }
16862
16863    void finishUserSwitch(UserStartedState uss) {
16864        synchronized (this) {
16865            if (uss.mState == UserStartedState.STATE_BOOTING
16866                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16867                uss.mState = UserStartedState.STATE_RUNNING;
16868                final int userId = uss.mHandle.getIdentifier();
16869                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16870                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16871                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16872                broadcastIntentLocked(null, null, intent,
16873                        null, null, 0, null, null,
16874                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16875                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16876            }
16877
16878            startProfilesLocked();
16879
16880            int num = mUserLru.size();
16881            int i = 0;
16882            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16883                Integer oldUserId = mUserLru.get(i);
16884                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16885                if (oldUss == null) {
16886                    // Shouldn't happen, but be sane if it does.
16887                    mUserLru.remove(i);
16888                    num--;
16889                    continue;
16890                }
16891                if (oldUss.mState == UserStartedState.STATE_STOPPING
16892                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16893                    // This user is already stopping, doesn't count.
16894                    num--;
16895                    i++;
16896                    continue;
16897                }
16898                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16899                    // Owner and current can't be stopped, but count as running.
16900                    i++;
16901                    continue;
16902                }
16903                // This is a user to be stopped.
16904                stopUserLocked(oldUserId, null);
16905                num--;
16906                i++;
16907            }
16908        }
16909    }
16910
16911    @Override
16912    public int stopUser(final int userId, final IStopUserCallback callback) {
16913        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16914                != PackageManager.PERMISSION_GRANTED) {
16915            String msg = "Permission Denial: switchUser() from pid="
16916                    + Binder.getCallingPid()
16917                    + ", uid=" + Binder.getCallingUid()
16918                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16919            Slog.w(TAG, msg);
16920            throw new SecurityException(msg);
16921        }
16922        if (userId <= 0) {
16923            throw new IllegalArgumentException("Can't stop primary user " + userId);
16924        }
16925        synchronized (this) {
16926            return stopUserLocked(userId, callback);
16927        }
16928    }
16929
16930    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16931        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16932        if (mCurrentUserId == userId) {
16933            return ActivityManager.USER_OP_IS_CURRENT;
16934        }
16935
16936        final UserStartedState uss = mStartedUsers.get(userId);
16937        if (uss == null) {
16938            // User is not started, nothing to do...  but we do need to
16939            // callback if requested.
16940            if (callback != null) {
16941                mHandler.post(new Runnable() {
16942                    @Override
16943                    public void run() {
16944                        try {
16945                            callback.userStopped(userId);
16946                        } catch (RemoteException e) {
16947                        }
16948                    }
16949                });
16950            }
16951            return ActivityManager.USER_OP_SUCCESS;
16952        }
16953
16954        if (callback != null) {
16955            uss.mStopCallbacks.add(callback);
16956        }
16957
16958        if (uss.mState != UserStartedState.STATE_STOPPING
16959                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16960            uss.mState = UserStartedState.STATE_STOPPING;
16961            updateStartedUserArrayLocked();
16962
16963            long ident = Binder.clearCallingIdentity();
16964            try {
16965                // We are going to broadcast ACTION_USER_STOPPING and then
16966                // once that is done send a final ACTION_SHUTDOWN and then
16967                // stop the user.
16968                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16969                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16970                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16971                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16972                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16973                // This is the result receiver for the final shutdown broadcast.
16974                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16975                    @Override
16976                    public void performReceive(Intent intent, int resultCode, String data,
16977                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16978                        finishUserStop(uss);
16979                    }
16980                };
16981                // This is the result receiver for the initial stopping broadcast.
16982                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16983                    @Override
16984                    public void performReceive(Intent intent, int resultCode, String data,
16985                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16986                        // On to the next.
16987                        synchronized (ActivityManagerService.this) {
16988                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16989                                // Whoops, we are being started back up.  Abort, abort!
16990                                return;
16991                            }
16992                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16993                        }
16994                        mSystemServiceManager.stopUser(userId);
16995                        broadcastIntentLocked(null, null, shutdownIntent,
16996                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16997                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16998                    }
16999                };
17000                // Kick things off.
17001                broadcastIntentLocked(null, null, stoppingIntent,
17002                        null, stoppingReceiver, 0, null, null,
17003                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17004                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17005            } finally {
17006                Binder.restoreCallingIdentity(ident);
17007            }
17008        }
17009
17010        return ActivityManager.USER_OP_SUCCESS;
17011    }
17012
17013    void finishUserStop(UserStartedState uss) {
17014        final int userId = uss.mHandle.getIdentifier();
17015        boolean stopped;
17016        ArrayList<IStopUserCallback> callbacks;
17017        synchronized (this) {
17018            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17019            if (mStartedUsers.get(userId) != uss) {
17020                stopped = false;
17021            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17022                stopped = false;
17023            } else {
17024                stopped = true;
17025                // User can no longer run.
17026                mStartedUsers.remove(userId);
17027                mUserLru.remove(Integer.valueOf(userId));
17028                updateStartedUserArrayLocked();
17029
17030                // Clean up all state and processes associated with the user.
17031                // Kill all the processes for the user.
17032                forceStopUserLocked(userId, "finish user");
17033            }
17034        }
17035
17036        for (int i=0; i<callbacks.size(); i++) {
17037            try {
17038                if (stopped) callbacks.get(i).userStopped(userId);
17039                else callbacks.get(i).userStopAborted(userId);
17040            } catch (RemoteException e) {
17041            }
17042        }
17043
17044        if (stopped) {
17045            mSystemServiceManager.cleanupUser(userId);
17046            synchronized (this) {
17047                mStackSupervisor.removeUserLocked(userId);
17048            }
17049        }
17050    }
17051
17052    @Override
17053    public UserInfo getCurrentUser() {
17054        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17055                != PackageManager.PERMISSION_GRANTED) && (
17056                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17057                != PackageManager.PERMISSION_GRANTED)) {
17058            String msg = "Permission Denial: getCurrentUser() from pid="
17059                    + Binder.getCallingPid()
17060                    + ", uid=" + Binder.getCallingUid()
17061                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17062            Slog.w(TAG, msg);
17063            throw new SecurityException(msg);
17064        }
17065        synchronized (this) {
17066            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17067        }
17068    }
17069
17070    int getCurrentUserIdLocked() {
17071        return mCurrentUserId;
17072    }
17073
17074    @Override
17075    public boolean isUserRunning(int userId, boolean orStopped) {
17076        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17077                != PackageManager.PERMISSION_GRANTED) {
17078            String msg = "Permission Denial: isUserRunning() from pid="
17079                    + Binder.getCallingPid()
17080                    + ", uid=" + Binder.getCallingUid()
17081                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17082            Slog.w(TAG, msg);
17083            throw new SecurityException(msg);
17084        }
17085        synchronized (this) {
17086            return isUserRunningLocked(userId, orStopped);
17087        }
17088    }
17089
17090    boolean isUserRunningLocked(int userId, boolean orStopped) {
17091        UserStartedState state = mStartedUsers.get(userId);
17092        if (state == null) {
17093            return false;
17094        }
17095        if (orStopped) {
17096            return true;
17097        }
17098        return state.mState != UserStartedState.STATE_STOPPING
17099                && state.mState != UserStartedState.STATE_SHUTDOWN;
17100    }
17101
17102    @Override
17103    public int[] getRunningUserIds() {
17104        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17105                != PackageManager.PERMISSION_GRANTED) {
17106            String msg = "Permission Denial: isUserRunning() from pid="
17107                    + Binder.getCallingPid()
17108                    + ", uid=" + Binder.getCallingUid()
17109                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17110            Slog.w(TAG, msg);
17111            throw new SecurityException(msg);
17112        }
17113        synchronized (this) {
17114            return mStartedUserArray;
17115        }
17116    }
17117
17118    private void updateStartedUserArrayLocked() {
17119        int num = 0;
17120        for (int i=0; i<mStartedUsers.size();  i++) {
17121            UserStartedState uss = mStartedUsers.valueAt(i);
17122            // This list does not include stopping users.
17123            if (uss.mState != UserStartedState.STATE_STOPPING
17124                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17125                num++;
17126            }
17127        }
17128        mStartedUserArray = new int[num];
17129        num = 0;
17130        for (int i=0; i<mStartedUsers.size();  i++) {
17131            UserStartedState uss = mStartedUsers.valueAt(i);
17132            if (uss.mState != UserStartedState.STATE_STOPPING
17133                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17134                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17135                num++;
17136            }
17137        }
17138    }
17139
17140    @Override
17141    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17142        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17143                != PackageManager.PERMISSION_GRANTED) {
17144            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17145                    + Binder.getCallingPid()
17146                    + ", uid=" + Binder.getCallingUid()
17147                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17148            Slog.w(TAG, msg);
17149            throw new SecurityException(msg);
17150        }
17151
17152        mUserSwitchObservers.register(observer);
17153    }
17154
17155    @Override
17156    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17157        mUserSwitchObservers.unregister(observer);
17158    }
17159
17160    private boolean userExists(int userId) {
17161        if (userId == 0) {
17162            return true;
17163        }
17164        UserManagerService ums = getUserManagerLocked();
17165        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17166    }
17167
17168    int[] getUsersLocked() {
17169        UserManagerService ums = getUserManagerLocked();
17170        return ums != null ? ums.getUserIds() : new int[] { 0 };
17171    }
17172
17173    UserManagerService getUserManagerLocked() {
17174        if (mUserManager == null) {
17175            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17176            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17177        }
17178        return mUserManager;
17179    }
17180
17181    private int applyUserId(int uid, int userId) {
17182        return UserHandle.getUid(userId, uid);
17183    }
17184
17185    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17186        if (info == null) return null;
17187        ApplicationInfo newInfo = new ApplicationInfo(info);
17188        newInfo.uid = applyUserId(info.uid, userId);
17189        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17190                + info.packageName;
17191        return newInfo;
17192    }
17193
17194    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17195        if (aInfo == null
17196                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17197            return aInfo;
17198        }
17199
17200        ActivityInfo info = new ActivityInfo(aInfo);
17201        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17202        return info;
17203    }
17204
17205    private final class LocalService extends ActivityManagerInternal {
17206        @Override
17207        public void goingToSleep() {
17208            ActivityManagerService.this.goingToSleep();
17209        }
17210
17211        @Override
17212        public void wakingUp() {
17213            ActivityManagerService.this.wakingUp();
17214        }
17215    }
17216}
17217