ActivityManagerService.java revision 684bf34ee8acc41931fac23762b13e14a22011db
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_PROCESS_STATE = 1<<1;
1021        int changes;
1022        int uid;
1023        int pid;
1024        int processState;
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_PROCESS_STATE) != 0) {
3204                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3205                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3206                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3207                        }
3208                    }
3209                } catch (RemoteException e) {
3210                }
3211            }
3212        }
3213        mProcessObservers.finishBroadcast();
3214    }
3215
3216    private void dispatchProcessDied(int pid, int uid) {
3217        int i = mProcessObservers.beginBroadcast();
3218        while (i > 0) {
3219            i--;
3220            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3221            if (observer != null) {
3222                try {
3223                    observer.onProcessDied(pid, uid);
3224                } catch (RemoteException e) {
3225                }
3226            }
3227        }
3228        mProcessObservers.finishBroadcast();
3229    }
3230
3231    final void doPendingActivityLaunchesLocked(boolean doResume) {
3232        final int N = mPendingActivityLaunches.size();
3233        if (N <= 0) {
3234            return;
3235        }
3236        for (int i=0; i<N; i++) {
3237            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3238            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3239                    doResume && i == (N-1), null);
3240        }
3241        mPendingActivityLaunches.clear();
3242    }
3243
3244    @Override
3245    public final int startActivity(IApplicationThread caller, String callingPackage,
3246            Intent intent, String resolvedType, IBinder resultTo,
3247            String resultWho, int requestCode, int startFlags,
3248            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3249        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3250                resultWho, requestCode,
3251                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3252    }
3253
3254    @Override
3255    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3256            Intent intent, String resolvedType, IBinder resultTo,
3257            String resultWho, int requestCode, int startFlags,
3258            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3259        enforceNotIsolatedCaller("startActivity");
3260        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3261                false, true, "startActivity", null);
3262        // TODO: Switch to user app stacks here.
3263        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3264                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3265                null, null, options, userId, null);
3266    }
3267
3268    @Override
3269    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3270            Intent intent, String resolvedType, IBinder resultTo,
3271            String resultWho, int requestCode, int startFlags, String profileFile,
3272            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3273        enforceNotIsolatedCaller("startActivityAndWait");
3274        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3275                false, true, "startActivityAndWait", null);
3276        WaitResult res = new WaitResult();
3277        // TODO: Switch to user app stacks here.
3278        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3279                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3280                res, null, options, UserHandle.getCallingUserId(), null);
3281        return res;
3282    }
3283
3284    @Override
3285    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3286            Intent intent, String resolvedType, IBinder resultTo,
3287            String resultWho, int requestCode, int startFlags, Configuration config,
3288            Bundle options, int userId) {
3289        enforceNotIsolatedCaller("startActivityWithConfig");
3290        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3291                false, true, "startActivityWithConfig", null);
3292        // TODO: Switch to user app stacks here.
3293        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3294                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3295                null, null, null, config, options, userId, null);
3296        return ret;
3297    }
3298
3299    @Override
3300    public int startActivityIntentSender(IApplicationThread caller,
3301            IntentSender intent, Intent fillInIntent, String resolvedType,
3302            IBinder resultTo, String resultWho, int requestCode,
3303            int flagsMask, int flagsValues, Bundle options) {
3304        enforceNotIsolatedCaller("startActivityIntentSender");
3305        // Refuse possible leaked file descriptors
3306        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3307            throw new IllegalArgumentException("File descriptors passed in Intent");
3308        }
3309
3310        IIntentSender sender = intent.getTarget();
3311        if (!(sender instanceof PendingIntentRecord)) {
3312            throw new IllegalArgumentException("Bad PendingIntent object");
3313        }
3314
3315        PendingIntentRecord pir = (PendingIntentRecord)sender;
3316
3317        synchronized (this) {
3318            // If this is coming from the currently resumed activity, it is
3319            // effectively saying that app switches are allowed at this point.
3320            final ActivityStack stack = getFocusedStack();
3321            if (stack.mResumedActivity != null &&
3322                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3323                mAppSwitchesAllowedTime = 0;
3324            }
3325        }
3326        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3327                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3328        return ret;
3329    }
3330
3331    @Override
3332    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3333            Intent intent, String resolvedType, IVoiceInteractionSession session,
3334            IVoiceInteractor interactor, int startFlags, String profileFile,
3335            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3336        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3337                != PackageManager.PERMISSION_GRANTED) {
3338            String msg = "Permission Denial: startVoiceActivity() from pid="
3339                    + Binder.getCallingPid()
3340                    + ", uid=" + Binder.getCallingUid()
3341                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3342            Slog.w(TAG, msg);
3343            throw new SecurityException(msg);
3344        }
3345        if (session == null || interactor == null) {
3346            throw new NullPointerException("null session or interactor");
3347        }
3348        userId = handleIncomingUser(callingPid, callingUid, userId,
3349                false, true, "startVoiceActivity", null);
3350        // TODO: Switch to user app stacks here.
3351        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3352                resolvedType, session, interactor, null, null, 0, startFlags,
3353                profileFile, profileFd, null, null, options, userId, null);
3354    }
3355
3356    @Override
3357    public boolean startNextMatchingActivity(IBinder callingActivity,
3358            Intent intent, Bundle options) {
3359        // Refuse possible leaked file descriptors
3360        if (intent != null && intent.hasFileDescriptors() == true) {
3361            throw new IllegalArgumentException("File descriptors passed in Intent");
3362        }
3363
3364        synchronized (this) {
3365            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3366            if (r == null) {
3367                ActivityOptions.abort(options);
3368                return false;
3369            }
3370            if (r.app == null || r.app.thread == null) {
3371                // The caller is not running...  d'oh!
3372                ActivityOptions.abort(options);
3373                return false;
3374            }
3375            intent = new Intent(intent);
3376            // The caller is not allowed to change the data.
3377            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3378            // And we are resetting to find the next component...
3379            intent.setComponent(null);
3380
3381            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3382
3383            ActivityInfo aInfo = null;
3384            try {
3385                List<ResolveInfo> resolves =
3386                    AppGlobals.getPackageManager().queryIntentActivities(
3387                            intent, r.resolvedType,
3388                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3389                            UserHandle.getCallingUserId());
3390
3391                // Look for the original activity in the list...
3392                final int N = resolves != null ? resolves.size() : 0;
3393                for (int i=0; i<N; i++) {
3394                    ResolveInfo rInfo = resolves.get(i);
3395                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3396                            && rInfo.activityInfo.name.equals(r.info.name)) {
3397                        // We found the current one...  the next matching is
3398                        // after it.
3399                        i++;
3400                        if (i<N) {
3401                            aInfo = resolves.get(i).activityInfo;
3402                        }
3403                        if (debug) {
3404                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3405                                    + "/" + r.info.name);
3406                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3407                                    + "/" + aInfo.name);
3408                        }
3409                        break;
3410                    }
3411                }
3412            } catch (RemoteException e) {
3413            }
3414
3415            if (aInfo == null) {
3416                // Nobody who is next!
3417                ActivityOptions.abort(options);
3418                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3419                return false;
3420            }
3421
3422            intent.setComponent(new ComponentName(
3423                    aInfo.applicationInfo.packageName, aInfo.name));
3424            intent.setFlags(intent.getFlags()&~(
3425                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3426                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3427                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3428                    Intent.FLAG_ACTIVITY_NEW_TASK));
3429
3430            // Okay now we need to start the new activity, replacing the
3431            // currently running activity.  This is a little tricky because
3432            // we want to start the new one as if the current one is finished,
3433            // but not finish the current one first so that there is no flicker.
3434            // And thus...
3435            final boolean wasFinishing = r.finishing;
3436            r.finishing = true;
3437
3438            // Propagate reply information over to the new activity.
3439            final ActivityRecord resultTo = r.resultTo;
3440            final String resultWho = r.resultWho;
3441            final int requestCode = r.requestCode;
3442            r.resultTo = null;
3443            if (resultTo != null) {
3444                resultTo.removeResultsLocked(r, resultWho, requestCode);
3445            }
3446
3447            final long origId = Binder.clearCallingIdentity();
3448            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3449                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3450                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3451                    options, false, null, null);
3452            Binder.restoreCallingIdentity(origId);
3453
3454            r.finishing = wasFinishing;
3455            if (res != ActivityManager.START_SUCCESS) {
3456                return false;
3457            }
3458            return true;
3459        }
3460    }
3461
3462    final int startActivityInPackage(int uid, String callingPackage,
3463            Intent intent, String resolvedType, IBinder resultTo,
3464            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3465                    IActivityContainer container) {
3466
3467        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3468                false, true, "startActivityInPackage", null);
3469
3470        // TODO: Switch to user app stacks here.
3471        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3472                null, null, resultTo, resultWho, requestCode, startFlags,
3473                null, null, null, null, options, userId, container);
3474        return ret;
3475    }
3476
3477    @Override
3478    public final int startActivities(IApplicationThread caller, String callingPackage,
3479            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3480            int userId) {
3481        enforceNotIsolatedCaller("startActivities");
3482        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3483                false, true, "startActivity", null);
3484        // TODO: Switch to user app stacks here.
3485        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3486                resolvedTypes, resultTo, options, userId);
3487        return ret;
3488    }
3489
3490    final int startActivitiesInPackage(int uid, String callingPackage,
3491            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3492            Bundle options, int userId) {
3493
3494        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3495                false, true, "startActivityInPackage", null);
3496        // TODO: Switch to user app stacks here.
3497        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3498                resultTo, options, userId);
3499        return ret;
3500    }
3501
3502    final void addRecentTaskLocked(TaskRecord task) {
3503        int N = mRecentTasks.size();
3504        // Quick case: check if the top-most recent task is the same.
3505        if (N > 0 && mRecentTasks.get(0) == task) {
3506            return;
3507        }
3508        // Another quick case: never add voice sessions.
3509        if (task.voiceSession != null) {
3510            return;
3511        }
3512        // Remove any existing entries that are the same kind of task.
3513        final Intent intent = task.intent;
3514        final boolean document = intent != null && intent.isDocument();
3515        for (int i=0; i<N; i++) {
3516            TaskRecord tr = mRecentTasks.get(i);
3517            if (task != tr) {
3518                if (task.userId != tr.userId) {
3519                    continue;
3520                }
3521                final Intent trIntent = tr.intent;
3522                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3523                    (intent == null || !intent.filterEquals(trIntent))) {
3524                    continue;
3525                }
3526                if (document || trIntent != null && trIntent.isDocument()) {
3527                    // Document tasks do not match other tasks.
3528                    continue;
3529                }
3530            }
3531
3532            // Either task and tr are the same or, their affinities match or their intents match
3533            // and neither of them is a document.
3534            tr.disposeThumbnail();
3535            mRecentTasks.remove(i);
3536            i--;
3537            N--;
3538            if (task.intent == null) {
3539                // If the new recent task we are adding is not fully
3540                // specified, then replace it with the existing recent task.
3541                task = tr;
3542            }
3543        }
3544        if (N >= MAX_RECENT_TASKS) {
3545            mRecentTasks.remove(N-1).disposeThumbnail();
3546        }
3547        mRecentTasks.add(0, task);
3548    }
3549
3550    @Override
3551    public void reportActivityFullyDrawn(IBinder token) {
3552        synchronized (this) {
3553            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3554            if (r == null) {
3555                return;
3556            }
3557            r.reportFullyDrawnLocked();
3558        }
3559    }
3560
3561    @Override
3562    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3563        synchronized (this) {
3564            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3565            if (r == null) {
3566                return;
3567            }
3568            final long origId = Binder.clearCallingIdentity();
3569            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3570            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3571                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3572            if (config != null) {
3573                r.frozenBeforeDestroy = true;
3574                if (!updateConfigurationLocked(config, r, false, false)) {
3575                    mStackSupervisor.resumeTopActivitiesLocked();
3576                }
3577            }
3578            Binder.restoreCallingIdentity(origId);
3579        }
3580    }
3581
3582    @Override
3583    public int getRequestedOrientation(IBinder token) {
3584        synchronized (this) {
3585            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3586            if (r == null) {
3587                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3588            }
3589            return mWindowManager.getAppOrientation(r.appToken);
3590        }
3591    }
3592
3593    /**
3594     * This is the internal entry point for handling Activity.finish().
3595     *
3596     * @param token The Binder token referencing the Activity we want to finish.
3597     * @param resultCode Result code, if any, from this Activity.
3598     * @param resultData Result data (Intent), if any, from this Activity.
3599     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3600     *            the root Activity in the task.
3601     *
3602     * @return Returns true if the activity successfully finished, or false if it is still running.
3603     */
3604    @Override
3605    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3606            boolean finishTask) {
3607        // Refuse possible leaked file descriptors
3608        if (resultData != null && resultData.hasFileDescriptors() == true) {
3609            throw new IllegalArgumentException("File descriptors passed in Intent");
3610        }
3611
3612        synchronized(this) {
3613            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3614            if (r == null) {
3615                return true;
3616            }
3617            // Keep track of the root activity of the task before we finish it
3618            TaskRecord tr = r.task;
3619            ActivityRecord rootR = tr.getRootActivity();
3620            if (mController != null) {
3621                // Find the first activity that is not finishing.
3622                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3623                if (next != null) {
3624                    // ask watcher if this is allowed
3625                    boolean resumeOK = true;
3626                    try {
3627                        resumeOK = mController.activityResuming(next.packageName);
3628                    } catch (RemoteException e) {
3629                        mController = null;
3630                        Watchdog.getInstance().setActivityController(null);
3631                    }
3632
3633                    if (!resumeOK) {
3634                        return false;
3635                    }
3636                }
3637            }
3638            final long origId = Binder.clearCallingIdentity();
3639            try {
3640                boolean res;
3641                if (finishTask && r == rootR) {
3642                    // If requested, remove the task that is associated to this activity only if it
3643                    // was the root activity in the task.  The result code and data is ignored because
3644                    // we don't support returning them across task boundaries.
3645                    res = removeTaskByIdLocked(tr.taskId, 0);
3646                } else {
3647                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3648                            resultData, "app-request", true);
3649                }
3650                return res;
3651            } finally {
3652                Binder.restoreCallingIdentity(origId);
3653            }
3654        }
3655    }
3656
3657    @Override
3658    public final void finishHeavyWeightApp() {
3659        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3660                != PackageManager.PERMISSION_GRANTED) {
3661            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3662                    + Binder.getCallingPid()
3663                    + ", uid=" + Binder.getCallingUid()
3664                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3665            Slog.w(TAG, msg);
3666            throw new SecurityException(msg);
3667        }
3668
3669        synchronized(this) {
3670            if (mHeavyWeightProcess == null) {
3671                return;
3672            }
3673
3674            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3675                    mHeavyWeightProcess.activities);
3676            for (int i=0; i<activities.size(); i++) {
3677                ActivityRecord r = activities.get(i);
3678                if (!r.finishing) {
3679                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3680                            null, "finish-heavy", true);
3681                }
3682            }
3683
3684            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3685                    mHeavyWeightProcess.userId, 0));
3686            mHeavyWeightProcess = null;
3687        }
3688    }
3689
3690    @Override
3691    public void crashApplication(int uid, int initialPid, String packageName,
3692            String message) {
3693        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3694                != PackageManager.PERMISSION_GRANTED) {
3695            String msg = "Permission Denial: crashApplication() from pid="
3696                    + Binder.getCallingPid()
3697                    + ", uid=" + Binder.getCallingUid()
3698                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3699            Slog.w(TAG, msg);
3700            throw new SecurityException(msg);
3701        }
3702
3703        synchronized(this) {
3704            ProcessRecord proc = null;
3705
3706            // Figure out which process to kill.  We don't trust that initialPid
3707            // still has any relation to current pids, so must scan through the
3708            // list.
3709            synchronized (mPidsSelfLocked) {
3710                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3711                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3712                    if (p.uid != uid) {
3713                        continue;
3714                    }
3715                    if (p.pid == initialPid) {
3716                        proc = p;
3717                        break;
3718                    }
3719                    if (p.pkgList.containsKey(packageName)) {
3720                        proc = p;
3721                    }
3722                }
3723            }
3724
3725            if (proc == null) {
3726                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3727                        + " initialPid=" + initialPid
3728                        + " packageName=" + packageName);
3729                return;
3730            }
3731
3732            if (proc.thread != null) {
3733                if (proc.pid == Process.myPid()) {
3734                    Log.w(TAG, "crashApplication: trying to crash self!");
3735                    return;
3736                }
3737                long ident = Binder.clearCallingIdentity();
3738                try {
3739                    proc.thread.scheduleCrash(message);
3740                } catch (RemoteException e) {
3741                }
3742                Binder.restoreCallingIdentity(ident);
3743            }
3744        }
3745    }
3746
3747    @Override
3748    public final void finishSubActivity(IBinder token, String resultWho,
3749            int requestCode) {
3750        synchronized(this) {
3751            final long origId = Binder.clearCallingIdentity();
3752            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3753            if (r != null) {
3754                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3755            }
3756            Binder.restoreCallingIdentity(origId);
3757        }
3758    }
3759
3760    @Override
3761    public boolean finishActivityAffinity(IBinder token) {
3762        synchronized(this) {
3763            final long origId = Binder.clearCallingIdentity();
3764            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3765            boolean res = false;
3766            if (r != null) {
3767                res = r.task.stack.finishActivityAffinityLocked(r);
3768            }
3769            Binder.restoreCallingIdentity(origId);
3770            return res;
3771        }
3772    }
3773
3774    @Override
3775    public boolean willActivityBeVisible(IBinder token) {
3776        synchronized(this) {
3777            ActivityStack stack = ActivityRecord.getStackLocked(token);
3778            if (stack != null) {
3779                return stack.willActivityBeVisibleLocked(token);
3780            }
3781            return false;
3782        }
3783    }
3784
3785    @Override
3786    public void overridePendingTransition(IBinder token, String packageName,
3787            int enterAnim, int exitAnim) {
3788        synchronized(this) {
3789            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3790            if (self == null) {
3791                return;
3792            }
3793
3794            final long origId = Binder.clearCallingIdentity();
3795
3796            if (self.state == ActivityState.RESUMED
3797                    || self.state == ActivityState.PAUSING) {
3798                mWindowManager.overridePendingAppTransition(packageName,
3799                        enterAnim, exitAnim, null);
3800            }
3801
3802            Binder.restoreCallingIdentity(origId);
3803        }
3804    }
3805
3806    /**
3807     * Main function for removing an existing process from the activity manager
3808     * as a result of that process going away.  Clears out all connections
3809     * to the process.
3810     */
3811    private final void handleAppDiedLocked(ProcessRecord app,
3812            boolean restarting, boolean allowRestart) {
3813        int pid = app.pid;
3814        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3815        if (!restarting) {
3816            removeLruProcessLocked(app);
3817            if (pid > 0) {
3818                ProcessList.remove(pid);
3819            }
3820        }
3821
3822        if (mProfileProc == app) {
3823            clearProfilerLocked();
3824        }
3825
3826        // Remove this application's activities from active lists.
3827        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3828
3829        app.activities.clear();
3830
3831        if (app.instrumentationClass != null) {
3832            Slog.w(TAG, "Crash of app " + app.processName
3833                  + " running instrumentation " + app.instrumentationClass);
3834            Bundle info = new Bundle();
3835            info.putString("shortMsg", "Process crashed.");
3836            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3837        }
3838
3839        if (!restarting) {
3840            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3841                // If there was nothing to resume, and we are not already
3842                // restarting this process, but there is a visible activity that
3843                // is hosted by the process...  then make sure all visible
3844                // activities are running, taking care of restarting this
3845                // process.
3846                if (hasVisibleActivities) {
3847                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3848                }
3849            }
3850        }
3851    }
3852
3853    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3854        IBinder threadBinder = thread.asBinder();
3855        // Find the application record.
3856        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3857            ProcessRecord rec = mLruProcesses.get(i);
3858            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3859                return i;
3860            }
3861        }
3862        return -1;
3863    }
3864
3865    final ProcessRecord getRecordForAppLocked(
3866            IApplicationThread thread) {
3867        if (thread == null) {
3868            return null;
3869        }
3870
3871        int appIndex = getLRURecordIndexForAppLocked(thread);
3872        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3873    }
3874
3875    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3876        // If there are no longer any background processes running,
3877        // and the app that died was not running instrumentation,
3878        // then tell everyone we are now low on memory.
3879        boolean haveBg = false;
3880        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3881            ProcessRecord rec = mLruProcesses.get(i);
3882            if (rec.thread != null
3883                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3884                haveBg = true;
3885                break;
3886            }
3887        }
3888
3889        if (!haveBg) {
3890            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3891            if (doReport) {
3892                long now = SystemClock.uptimeMillis();
3893                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3894                    doReport = false;
3895                } else {
3896                    mLastMemUsageReportTime = now;
3897                }
3898            }
3899            final ArrayList<ProcessMemInfo> memInfos
3900                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3901            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3902            long now = SystemClock.uptimeMillis();
3903            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3904                ProcessRecord rec = mLruProcesses.get(i);
3905                if (rec == dyingProc || rec.thread == null) {
3906                    continue;
3907                }
3908                if (doReport) {
3909                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3910                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3911                }
3912                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3913                    // The low memory report is overriding any current
3914                    // state for a GC request.  Make sure to do
3915                    // heavy/important/visible/foreground processes first.
3916                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3917                        rec.lastRequestedGc = 0;
3918                    } else {
3919                        rec.lastRequestedGc = rec.lastLowMemory;
3920                    }
3921                    rec.reportLowMemory = true;
3922                    rec.lastLowMemory = now;
3923                    mProcessesToGc.remove(rec);
3924                    addProcessToGcListLocked(rec);
3925                }
3926            }
3927            if (doReport) {
3928                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3929                mHandler.sendMessage(msg);
3930            }
3931            scheduleAppGcsLocked();
3932        }
3933    }
3934
3935    final void appDiedLocked(ProcessRecord app, int pid,
3936            IApplicationThread thread) {
3937
3938        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3939        synchronized (stats) {
3940            stats.noteProcessDiedLocked(app.info.uid, pid);
3941        }
3942
3943        // Clean up already done if the process has been re-started.
3944        if (app.pid == pid && app.thread != null &&
3945                app.thread.asBinder() == thread.asBinder()) {
3946            boolean doLowMem = app.instrumentationClass == null;
3947            boolean doOomAdj = doLowMem;
3948            if (!app.killedByAm) {
3949                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3950                        + ") has died.");
3951                mAllowLowerMemLevel = true;
3952            } else {
3953                // Note that we always want to do oom adj to update our state with the
3954                // new number of procs.
3955                mAllowLowerMemLevel = false;
3956                doLowMem = false;
3957            }
3958            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3959            if (DEBUG_CLEANUP) Slog.v(
3960                TAG, "Dying app: " + app + ", pid: " + pid
3961                + ", thread: " + thread.asBinder());
3962            handleAppDiedLocked(app, false, true);
3963
3964            if (doOomAdj) {
3965                updateOomAdjLocked();
3966            }
3967            if (doLowMem) {
3968                doLowMemReportIfNeededLocked(app);
3969            }
3970        } else if (app.pid != pid) {
3971            // A new process has already been started.
3972            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3973                    + ") has died and restarted (pid " + app.pid + ").");
3974            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3975        } else if (DEBUG_PROCESSES) {
3976            Slog.d(TAG, "Received spurious death notification for thread "
3977                    + thread.asBinder());
3978        }
3979    }
3980
3981    /**
3982     * If a stack trace dump file is configured, dump process stack traces.
3983     * @param clearTraces causes the dump file to be erased prior to the new
3984     *    traces being written, if true; when false, the new traces will be
3985     *    appended to any existing file content.
3986     * @param firstPids of dalvik VM processes to dump stack traces for first
3987     * @param lastPids of dalvik VM processes to dump stack traces for last
3988     * @param nativeProcs optional list of native process names to dump stack crawls
3989     * @return file containing stack traces, or null if no dump file is configured
3990     */
3991    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3992            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3993        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3994        if (tracesPath == null || tracesPath.length() == 0) {
3995            return null;
3996        }
3997
3998        File tracesFile = new File(tracesPath);
3999        try {
4000            File tracesDir = tracesFile.getParentFile();
4001            if (!tracesDir.exists()) {
4002                tracesFile.mkdirs();
4003                if (!SELinux.restorecon(tracesDir)) {
4004                    return null;
4005                }
4006            }
4007            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4008
4009            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4010            tracesFile.createNewFile();
4011            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4012        } catch (IOException e) {
4013            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4014            return null;
4015        }
4016
4017        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4018        return tracesFile;
4019    }
4020
4021    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4022            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4023        // Use a FileObserver to detect when traces finish writing.
4024        // The order of traces is considered important to maintain for legibility.
4025        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4026            @Override
4027            public synchronized void onEvent(int event, String path) { notify(); }
4028        };
4029
4030        try {
4031            observer.startWatching();
4032
4033            // First collect all of the stacks of the most important pids.
4034            if (firstPids != null) {
4035                try {
4036                    int num = firstPids.size();
4037                    for (int i = 0; i < num; i++) {
4038                        synchronized (observer) {
4039                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4040                            observer.wait(200);  // Wait for write-close, give up after 200msec
4041                        }
4042                    }
4043                } catch (InterruptedException e) {
4044                    Log.wtf(TAG, e);
4045                }
4046            }
4047
4048            // Next collect the stacks of the native pids
4049            if (nativeProcs != null) {
4050                int[] pids = Process.getPidsForCommands(nativeProcs);
4051                if (pids != null) {
4052                    for (int pid : pids) {
4053                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4054                    }
4055                }
4056            }
4057
4058            // Lastly, measure CPU usage.
4059            if (processCpuTracker != null) {
4060                processCpuTracker.init();
4061                System.gc();
4062                processCpuTracker.update();
4063                try {
4064                    synchronized (processCpuTracker) {
4065                        processCpuTracker.wait(500); // measure over 1/2 second.
4066                    }
4067                } catch (InterruptedException e) {
4068                }
4069                processCpuTracker.update();
4070
4071                // We'll take the stack crawls of just the top apps using CPU.
4072                final int N = processCpuTracker.countWorkingStats();
4073                int numProcs = 0;
4074                for (int i=0; i<N && numProcs<5; i++) {
4075                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4076                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4077                        numProcs++;
4078                        try {
4079                            synchronized (observer) {
4080                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4081                                observer.wait(200);  // Wait for write-close, give up after 200msec
4082                            }
4083                        } catch (InterruptedException e) {
4084                            Log.wtf(TAG, e);
4085                        }
4086
4087                    }
4088                }
4089            }
4090        } finally {
4091            observer.stopWatching();
4092        }
4093    }
4094
4095    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4096        if (true || IS_USER_BUILD) {
4097            return;
4098        }
4099        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4100        if (tracesPath == null || tracesPath.length() == 0) {
4101            return;
4102        }
4103
4104        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4105        StrictMode.allowThreadDiskWrites();
4106        try {
4107            final File tracesFile = new File(tracesPath);
4108            final File tracesDir = tracesFile.getParentFile();
4109            final File tracesTmp = new File(tracesDir, "__tmp__");
4110            try {
4111                if (!tracesDir.exists()) {
4112                    tracesFile.mkdirs();
4113                    if (!SELinux.restorecon(tracesDir.getPath())) {
4114                        return;
4115                    }
4116                }
4117                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4118
4119                if (tracesFile.exists()) {
4120                    tracesTmp.delete();
4121                    tracesFile.renameTo(tracesTmp);
4122                }
4123                StringBuilder sb = new StringBuilder();
4124                Time tobj = new Time();
4125                tobj.set(System.currentTimeMillis());
4126                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4127                sb.append(": ");
4128                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4129                sb.append(" since ");
4130                sb.append(msg);
4131                FileOutputStream fos = new FileOutputStream(tracesFile);
4132                fos.write(sb.toString().getBytes());
4133                if (app == null) {
4134                    fos.write("\n*** No application process!".getBytes());
4135                }
4136                fos.close();
4137                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4138            } catch (IOException e) {
4139                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4140                return;
4141            }
4142
4143            if (app != null) {
4144                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4145                firstPids.add(app.pid);
4146                dumpStackTraces(tracesPath, firstPids, null, null, null);
4147            }
4148
4149            File lastTracesFile = null;
4150            File curTracesFile = null;
4151            for (int i=9; i>=0; i--) {
4152                String name = String.format(Locale.US, "slow%02d.txt", i);
4153                curTracesFile = new File(tracesDir, name);
4154                if (curTracesFile.exists()) {
4155                    if (lastTracesFile != null) {
4156                        curTracesFile.renameTo(lastTracesFile);
4157                    } else {
4158                        curTracesFile.delete();
4159                    }
4160                }
4161                lastTracesFile = curTracesFile;
4162            }
4163            tracesFile.renameTo(curTracesFile);
4164            if (tracesTmp.exists()) {
4165                tracesTmp.renameTo(tracesFile);
4166            }
4167        } finally {
4168            StrictMode.setThreadPolicy(oldPolicy);
4169        }
4170    }
4171
4172    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4173            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4174        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4175        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4176
4177        if (mController != null) {
4178            try {
4179                // 0 == continue, -1 = kill process immediately
4180                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4181                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4182            } catch (RemoteException e) {
4183                mController = null;
4184                Watchdog.getInstance().setActivityController(null);
4185            }
4186        }
4187
4188        long anrTime = SystemClock.uptimeMillis();
4189        if (MONITOR_CPU_USAGE) {
4190            updateCpuStatsNow();
4191        }
4192
4193        synchronized (this) {
4194            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4195            if (mShuttingDown) {
4196                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4197                return;
4198            } else if (app.notResponding) {
4199                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4200                return;
4201            } else if (app.crashing) {
4202                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4203                return;
4204            }
4205
4206            // In case we come through here for the same app before completing
4207            // this one, mark as anring now so we will bail out.
4208            app.notResponding = true;
4209
4210            // Log the ANR to the event log.
4211            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4212                    app.processName, app.info.flags, annotation);
4213
4214            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4215            firstPids.add(app.pid);
4216
4217            int parentPid = app.pid;
4218            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4219            if (parentPid != app.pid) firstPids.add(parentPid);
4220
4221            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4222
4223            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4224                ProcessRecord r = mLruProcesses.get(i);
4225                if (r != null && r.thread != null) {
4226                    int pid = r.pid;
4227                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4228                        if (r.persistent) {
4229                            firstPids.add(pid);
4230                        } else {
4231                            lastPids.put(pid, Boolean.TRUE);
4232                        }
4233                    }
4234                }
4235            }
4236        }
4237
4238        // Log the ANR to the main log.
4239        StringBuilder info = new StringBuilder();
4240        info.setLength(0);
4241        info.append("ANR in ").append(app.processName);
4242        if (activity != null && activity.shortComponentName != null) {
4243            info.append(" (").append(activity.shortComponentName).append(")");
4244        }
4245        info.append("\n");
4246        info.append("PID: ").append(app.pid).append("\n");
4247        if (annotation != null) {
4248            info.append("Reason: ").append(annotation).append("\n");
4249        }
4250        if (parent != null && parent != activity) {
4251            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4252        }
4253
4254        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4255
4256        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4257                NATIVE_STACKS_OF_INTEREST);
4258
4259        String cpuInfo = null;
4260        if (MONITOR_CPU_USAGE) {
4261            updateCpuStatsNow();
4262            synchronized (mProcessCpuThread) {
4263                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4264            }
4265            info.append(processCpuTracker.printCurrentLoad());
4266            info.append(cpuInfo);
4267        }
4268
4269        info.append(processCpuTracker.printCurrentState(anrTime));
4270
4271        Slog.e(TAG, info.toString());
4272        if (tracesFile == null) {
4273            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4274            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4275        }
4276
4277        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4278                cpuInfo, tracesFile, null);
4279
4280        if (mController != null) {
4281            try {
4282                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4283                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4284                if (res != 0) {
4285                    if (res < 0 && app.pid != MY_PID) {
4286                        Process.killProcess(app.pid);
4287                    } else {
4288                        synchronized (this) {
4289                            mServices.scheduleServiceTimeoutLocked(app);
4290                        }
4291                    }
4292                    return;
4293                }
4294            } catch (RemoteException e) {
4295                mController = null;
4296                Watchdog.getInstance().setActivityController(null);
4297            }
4298        }
4299
4300        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4301        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4302                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4303
4304        synchronized (this) {
4305            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4306                killUnneededProcessLocked(app, "background ANR");
4307                return;
4308            }
4309
4310            // Set the app's notResponding state, and look up the errorReportReceiver
4311            makeAppNotRespondingLocked(app,
4312                    activity != null ? activity.shortComponentName : null,
4313                    annotation != null ? "ANR " + annotation : "ANR",
4314                    info.toString());
4315
4316            // Bring up the infamous App Not Responding dialog
4317            Message msg = Message.obtain();
4318            HashMap<String, Object> map = new HashMap<String, Object>();
4319            msg.what = SHOW_NOT_RESPONDING_MSG;
4320            msg.obj = map;
4321            msg.arg1 = aboveSystem ? 1 : 0;
4322            map.put("app", app);
4323            if (activity != null) {
4324                map.put("activity", activity);
4325            }
4326
4327            mHandler.sendMessage(msg);
4328        }
4329    }
4330
4331    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4332        if (!mLaunchWarningShown) {
4333            mLaunchWarningShown = true;
4334            mHandler.post(new Runnable() {
4335                @Override
4336                public void run() {
4337                    synchronized (ActivityManagerService.this) {
4338                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4339                        d.show();
4340                        mHandler.postDelayed(new Runnable() {
4341                            @Override
4342                            public void run() {
4343                                synchronized (ActivityManagerService.this) {
4344                                    d.dismiss();
4345                                    mLaunchWarningShown = false;
4346                                }
4347                            }
4348                        }, 4000);
4349                    }
4350                }
4351            });
4352        }
4353    }
4354
4355    @Override
4356    public boolean clearApplicationUserData(final String packageName,
4357            final IPackageDataObserver observer, int userId) {
4358        enforceNotIsolatedCaller("clearApplicationUserData");
4359        int uid = Binder.getCallingUid();
4360        int pid = Binder.getCallingPid();
4361        userId = handleIncomingUser(pid, uid,
4362                userId, false, true, "clearApplicationUserData", null);
4363        long callingId = Binder.clearCallingIdentity();
4364        try {
4365            IPackageManager pm = AppGlobals.getPackageManager();
4366            int pkgUid = -1;
4367            synchronized(this) {
4368                try {
4369                    pkgUid = pm.getPackageUid(packageName, userId);
4370                } catch (RemoteException e) {
4371                }
4372                if (pkgUid == -1) {
4373                    Slog.w(TAG, "Invalid packageName: " + packageName);
4374                    if (observer != null) {
4375                        try {
4376                            observer.onRemoveCompleted(packageName, false);
4377                        } catch (RemoteException e) {
4378                            Slog.i(TAG, "Observer no longer exists.");
4379                        }
4380                    }
4381                    return false;
4382                }
4383                if (uid == pkgUid || checkComponentPermission(
4384                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4385                        pid, uid, -1, true)
4386                        == PackageManager.PERMISSION_GRANTED) {
4387                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4388                } else {
4389                    throw new SecurityException("PID " + pid + " does not have permission "
4390                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4391                                    + " of package " + packageName);
4392                }
4393            }
4394
4395            try {
4396                // Clear application user data
4397                pm.clearApplicationUserData(packageName, observer, userId);
4398
4399                // Remove all permissions granted from/to this package
4400                removeUriPermissionsForPackageLocked(packageName, userId, true);
4401
4402                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4403                        Uri.fromParts("package", packageName, null));
4404                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4405                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4406                        null, null, 0, null, null, null, false, false, userId);
4407            } catch (RemoteException e) {
4408            }
4409        } finally {
4410            Binder.restoreCallingIdentity(callingId);
4411        }
4412        return true;
4413    }
4414
4415    @Override
4416    public void killBackgroundProcesses(final String packageName, int userId) {
4417        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4418                != PackageManager.PERMISSION_GRANTED &&
4419                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4420                        != PackageManager.PERMISSION_GRANTED) {
4421            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4422                    + Binder.getCallingPid()
4423                    + ", uid=" + Binder.getCallingUid()
4424                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4425            Slog.w(TAG, msg);
4426            throw new SecurityException(msg);
4427        }
4428
4429        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4430                userId, true, true, "killBackgroundProcesses", null);
4431        long callingId = Binder.clearCallingIdentity();
4432        try {
4433            IPackageManager pm = AppGlobals.getPackageManager();
4434            synchronized(this) {
4435                int appId = -1;
4436                try {
4437                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4438                } catch (RemoteException e) {
4439                }
4440                if (appId == -1) {
4441                    Slog.w(TAG, "Invalid packageName: " + packageName);
4442                    return;
4443                }
4444                killPackageProcessesLocked(packageName, appId, userId,
4445                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4446            }
4447        } finally {
4448            Binder.restoreCallingIdentity(callingId);
4449        }
4450    }
4451
4452    @Override
4453    public void killAllBackgroundProcesses() {
4454        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4455                != PackageManager.PERMISSION_GRANTED) {
4456            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4457                    + Binder.getCallingPid()
4458                    + ", uid=" + Binder.getCallingUid()
4459                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4460            Slog.w(TAG, msg);
4461            throw new SecurityException(msg);
4462        }
4463
4464        long callingId = Binder.clearCallingIdentity();
4465        try {
4466            synchronized(this) {
4467                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4468                final int NP = mProcessNames.getMap().size();
4469                for (int ip=0; ip<NP; ip++) {
4470                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4471                    final int NA = apps.size();
4472                    for (int ia=0; ia<NA; ia++) {
4473                        ProcessRecord app = apps.valueAt(ia);
4474                        if (app.persistent) {
4475                            // we don't kill persistent processes
4476                            continue;
4477                        }
4478                        if (app.removed) {
4479                            procs.add(app);
4480                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4481                            app.removed = true;
4482                            procs.add(app);
4483                        }
4484                    }
4485                }
4486
4487                int N = procs.size();
4488                for (int i=0; i<N; i++) {
4489                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4490                }
4491                mAllowLowerMemLevel = true;
4492                updateOomAdjLocked();
4493                doLowMemReportIfNeededLocked(null);
4494            }
4495        } finally {
4496            Binder.restoreCallingIdentity(callingId);
4497        }
4498    }
4499
4500    @Override
4501    public void forceStopPackage(final String packageName, int userId) {
4502        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4503                != PackageManager.PERMISSION_GRANTED) {
4504            String msg = "Permission Denial: forceStopPackage() from pid="
4505                    + Binder.getCallingPid()
4506                    + ", uid=" + Binder.getCallingUid()
4507                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4508            Slog.w(TAG, msg);
4509            throw new SecurityException(msg);
4510        }
4511        final int callingPid = Binder.getCallingPid();
4512        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4513                userId, true, true, "forceStopPackage", null);
4514        long callingId = Binder.clearCallingIdentity();
4515        try {
4516            IPackageManager pm = AppGlobals.getPackageManager();
4517            synchronized(this) {
4518                int[] users = userId == UserHandle.USER_ALL
4519                        ? getUsersLocked() : new int[] { userId };
4520                for (int user : users) {
4521                    int pkgUid = -1;
4522                    try {
4523                        pkgUid = pm.getPackageUid(packageName, user);
4524                    } catch (RemoteException e) {
4525                    }
4526                    if (pkgUid == -1) {
4527                        Slog.w(TAG, "Invalid packageName: " + packageName);
4528                        continue;
4529                    }
4530                    try {
4531                        pm.setPackageStoppedState(packageName, true, user);
4532                    } catch (RemoteException e) {
4533                    } catch (IllegalArgumentException e) {
4534                        Slog.w(TAG, "Failed trying to unstop package "
4535                                + packageName + ": " + e);
4536                    }
4537                    if (isUserRunningLocked(user, false)) {
4538                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4539                    }
4540                }
4541            }
4542        } finally {
4543            Binder.restoreCallingIdentity(callingId);
4544        }
4545    }
4546
4547    /*
4548     * The pkg name and app id have to be specified.
4549     */
4550    @Override
4551    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4552        if (pkg == null) {
4553            return;
4554        }
4555        // Make sure the uid is valid.
4556        if (appid < 0) {
4557            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4558            return;
4559        }
4560        int callerUid = Binder.getCallingUid();
4561        // Only the system server can kill an application
4562        if (callerUid == Process.SYSTEM_UID) {
4563            // Post an aysnc message to kill the application
4564            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4565            msg.arg1 = appid;
4566            msg.arg2 = 0;
4567            Bundle bundle = new Bundle();
4568            bundle.putString("pkg", pkg);
4569            bundle.putString("reason", reason);
4570            msg.obj = bundle;
4571            mHandler.sendMessage(msg);
4572        } else {
4573            throw new SecurityException(callerUid + " cannot kill pkg: " +
4574                    pkg);
4575        }
4576    }
4577
4578    @Override
4579    public void closeSystemDialogs(String reason) {
4580        enforceNotIsolatedCaller("closeSystemDialogs");
4581
4582        final int pid = Binder.getCallingPid();
4583        final int uid = Binder.getCallingUid();
4584        final long origId = Binder.clearCallingIdentity();
4585        try {
4586            synchronized (this) {
4587                // Only allow this from foreground processes, so that background
4588                // applications can't abuse it to prevent system UI from being shown.
4589                if (uid >= Process.FIRST_APPLICATION_UID) {
4590                    ProcessRecord proc;
4591                    synchronized (mPidsSelfLocked) {
4592                        proc = mPidsSelfLocked.get(pid);
4593                    }
4594                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4595                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4596                                + " from background process " + proc);
4597                        return;
4598                    }
4599                }
4600                closeSystemDialogsLocked(reason);
4601            }
4602        } finally {
4603            Binder.restoreCallingIdentity(origId);
4604        }
4605    }
4606
4607    void closeSystemDialogsLocked(String reason) {
4608        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4609        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4610                | Intent.FLAG_RECEIVER_FOREGROUND);
4611        if (reason != null) {
4612            intent.putExtra("reason", reason);
4613        }
4614        mWindowManager.closeSystemDialogs(reason);
4615
4616        mStackSupervisor.closeSystemDialogsLocked();
4617
4618        broadcastIntentLocked(null, null, intent, null,
4619                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4620                Process.SYSTEM_UID, UserHandle.USER_ALL);
4621    }
4622
4623    @Override
4624    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4625        enforceNotIsolatedCaller("getProcessMemoryInfo");
4626        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4627        for (int i=pids.length-1; i>=0; i--) {
4628            ProcessRecord proc;
4629            int oomAdj;
4630            synchronized (this) {
4631                synchronized (mPidsSelfLocked) {
4632                    proc = mPidsSelfLocked.get(pids[i]);
4633                    oomAdj = proc != null ? proc.setAdj : 0;
4634                }
4635            }
4636            infos[i] = new Debug.MemoryInfo();
4637            Debug.getMemoryInfo(pids[i], infos[i]);
4638            if (proc != null) {
4639                synchronized (this) {
4640                    if (proc.thread != null && proc.setAdj == oomAdj) {
4641                        // Record this for posterity if the process has been stable.
4642                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4643                                infos[i].getTotalUss(), false, proc.pkgList);
4644                    }
4645                }
4646            }
4647        }
4648        return infos;
4649    }
4650
4651    @Override
4652    public long[] getProcessPss(int[] pids) {
4653        enforceNotIsolatedCaller("getProcessPss");
4654        long[] pss = new long[pids.length];
4655        for (int i=pids.length-1; i>=0; i--) {
4656            ProcessRecord proc;
4657            int oomAdj;
4658            synchronized (this) {
4659                synchronized (mPidsSelfLocked) {
4660                    proc = mPidsSelfLocked.get(pids[i]);
4661                    oomAdj = proc != null ? proc.setAdj : 0;
4662                }
4663            }
4664            long[] tmpUss = new long[1];
4665            pss[i] = Debug.getPss(pids[i], tmpUss);
4666            if (proc != null) {
4667                synchronized (this) {
4668                    if (proc.thread != null && proc.setAdj == oomAdj) {
4669                        // Record this for posterity if the process has been stable.
4670                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4671                    }
4672                }
4673            }
4674        }
4675        return pss;
4676    }
4677
4678    @Override
4679    public void killApplicationProcess(String processName, int uid) {
4680        if (processName == null) {
4681            return;
4682        }
4683
4684        int callerUid = Binder.getCallingUid();
4685        // Only the system server can kill an application
4686        if (callerUid == Process.SYSTEM_UID) {
4687            synchronized (this) {
4688                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4689                if (app != null && app.thread != null) {
4690                    try {
4691                        app.thread.scheduleSuicide();
4692                    } catch (RemoteException e) {
4693                        // If the other end already died, then our work here is done.
4694                    }
4695                } else {
4696                    Slog.w(TAG, "Process/uid not found attempting kill of "
4697                            + processName + " / " + uid);
4698                }
4699            }
4700        } else {
4701            throw new SecurityException(callerUid + " cannot kill app process: " +
4702                    processName);
4703        }
4704    }
4705
4706    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4707        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4708                false, true, false, false, UserHandle.getUserId(uid), reason);
4709        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4710                Uri.fromParts("package", packageName, null));
4711        if (!mProcessesReady) {
4712            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4713                    | Intent.FLAG_RECEIVER_FOREGROUND);
4714        }
4715        intent.putExtra(Intent.EXTRA_UID, uid);
4716        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4717        broadcastIntentLocked(null, null, intent,
4718                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4719                false, false,
4720                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4721    }
4722
4723    private void forceStopUserLocked(int userId, String reason) {
4724        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4725        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4726        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4727                | Intent.FLAG_RECEIVER_FOREGROUND);
4728        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4729        broadcastIntentLocked(null, null, intent,
4730                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4731                false, false,
4732                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4733    }
4734
4735    private final boolean killPackageProcessesLocked(String packageName, int appId,
4736            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4737            boolean doit, boolean evenPersistent, String reason) {
4738        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4739
4740        // Remove all processes this package may have touched: all with the
4741        // same UID (except for the system or root user), and all whose name
4742        // matches the package name.
4743        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4744        final int NP = mProcessNames.getMap().size();
4745        for (int ip=0; ip<NP; ip++) {
4746            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4747            final int NA = apps.size();
4748            for (int ia=0; ia<NA; ia++) {
4749                ProcessRecord app = apps.valueAt(ia);
4750                if (app.persistent && !evenPersistent) {
4751                    // we don't kill persistent processes
4752                    continue;
4753                }
4754                if (app.removed) {
4755                    if (doit) {
4756                        procs.add(app);
4757                    }
4758                    continue;
4759                }
4760
4761                // Skip process if it doesn't meet our oom adj requirement.
4762                if (app.setAdj < minOomAdj) {
4763                    continue;
4764                }
4765
4766                // If no package is specified, we call all processes under the
4767                // give user id.
4768                if (packageName == null) {
4769                    if (app.userId != userId) {
4770                        continue;
4771                    }
4772                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4773                        continue;
4774                    }
4775                // Package has been specified, we want to hit all processes
4776                // that match it.  We need to qualify this by the processes
4777                // that are running under the specified app and user ID.
4778                } else {
4779                    if (UserHandle.getAppId(app.uid) != appId) {
4780                        continue;
4781                    }
4782                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4783                        continue;
4784                    }
4785                    if (!app.pkgList.containsKey(packageName)) {
4786                        continue;
4787                    }
4788                }
4789
4790                // Process has passed all conditions, kill it!
4791                if (!doit) {
4792                    return true;
4793                }
4794                app.removed = true;
4795                procs.add(app);
4796            }
4797        }
4798
4799        int N = procs.size();
4800        for (int i=0; i<N; i++) {
4801            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4802        }
4803        updateOomAdjLocked();
4804        return N > 0;
4805    }
4806
4807    private final boolean forceStopPackageLocked(String name, int appId,
4808            boolean callerWillRestart, boolean purgeCache, boolean doit,
4809            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4810        int i;
4811        int N;
4812
4813        if (userId == UserHandle.USER_ALL && name == null) {
4814            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4815        }
4816
4817        if (appId < 0 && name != null) {
4818            try {
4819                appId = UserHandle.getAppId(
4820                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4821            } catch (RemoteException e) {
4822            }
4823        }
4824
4825        if (doit) {
4826            if (name != null) {
4827                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4828                        + " user=" + userId + ": " + reason);
4829            } else {
4830                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4831            }
4832
4833            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4834            for (int ip=pmap.size()-1; ip>=0; ip--) {
4835                SparseArray<Long> ba = pmap.valueAt(ip);
4836                for (i=ba.size()-1; i>=0; i--) {
4837                    boolean remove = false;
4838                    final int entUid = ba.keyAt(i);
4839                    if (name != null) {
4840                        if (userId == UserHandle.USER_ALL) {
4841                            if (UserHandle.getAppId(entUid) == appId) {
4842                                remove = true;
4843                            }
4844                        } else {
4845                            if (entUid == UserHandle.getUid(userId, appId)) {
4846                                remove = true;
4847                            }
4848                        }
4849                    } else if (UserHandle.getUserId(entUid) == userId) {
4850                        remove = true;
4851                    }
4852                    if (remove) {
4853                        ba.removeAt(i);
4854                    }
4855                }
4856                if (ba.size() == 0) {
4857                    pmap.removeAt(ip);
4858                }
4859            }
4860        }
4861
4862        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4863                -100, callerWillRestart, true, doit, evenPersistent,
4864                name == null ? ("stop user " + userId) : ("stop " + name));
4865
4866        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4867            if (!doit) {
4868                return true;
4869            }
4870            didSomething = true;
4871        }
4872
4873        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4874            if (!doit) {
4875                return true;
4876            }
4877            didSomething = true;
4878        }
4879
4880        if (name == null) {
4881            // Remove all sticky broadcasts from this user.
4882            mStickyBroadcasts.remove(userId);
4883        }
4884
4885        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4886        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4887                userId, providers)) {
4888            if (!doit) {
4889                return true;
4890            }
4891            didSomething = true;
4892        }
4893        N = providers.size();
4894        for (i=0; i<N; i++) {
4895            removeDyingProviderLocked(null, providers.get(i), true);
4896        }
4897
4898        // Remove transient permissions granted from/to this package/user
4899        removeUriPermissionsForPackageLocked(name, userId, false);
4900
4901        if (name == null || uninstalling) {
4902            // Remove pending intents.  For now we only do this when force
4903            // stopping users, because we have some problems when doing this
4904            // for packages -- app widgets are not currently cleaned up for
4905            // such packages, so they can be left with bad pending intents.
4906            if (mIntentSenderRecords.size() > 0) {
4907                Iterator<WeakReference<PendingIntentRecord>> it
4908                        = mIntentSenderRecords.values().iterator();
4909                while (it.hasNext()) {
4910                    WeakReference<PendingIntentRecord> wpir = it.next();
4911                    if (wpir == null) {
4912                        it.remove();
4913                        continue;
4914                    }
4915                    PendingIntentRecord pir = wpir.get();
4916                    if (pir == null) {
4917                        it.remove();
4918                        continue;
4919                    }
4920                    if (name == null) {
4921                        // Stopping user, remove all objects for the user.
4922                        if (pir.key.userId != userId) {
4923                            // Not the same user, skip it.
4924                            continue;
4925                        }
4926                    } else {
4927                        if (UserHandle.getAppId(pir.uid) != appId) {
4928                            // Different app id, skip it.
4929                            continue;
4930                        }
4931                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4932                            // Different user, skip it.
4933                            continue;
4934                        }
4935                        if (!pir.key.packageName.equals(name)) {
4936                            // Different package, skip it.
4937                            continue;
4938                        }
4939                    }
4940                    if (!doit) {
4941                        return true;
4942                    }
4943                    didSomething = true;
4944                    it.remove();
4945                    pir.canceled = true;
4946                    if (pir.key.activity != null) {
4947                        pir.key.activity.pendingResults.remove(pir.ref);
4948                    }
4949                }
4950            }
4951        }
4952
4953        if (doit) {
4954            if (purgeCache && name != null) {
4955                AttributeCache ac = AttributeCache.instance();
4956                if (ac != null) {
4957                    ac.removePackage(name);
4958                }
4959            }
4960            if (mBooted) {
4961                mStackSupervisor.resumeTopActivitiesLocked();
4962                mStackSupervisor.scheduleIdleLocked();
4963            }
4964        }
4965
4966        return didSomething;
4967    }
4968
4969    private final boolean removeProcessLocked(ProcessRecord app,
4970            boolean callerWillRestart, boolean allowRestart, String reason) {
4971        final String name = app.processName;
4972        final int uid = app.uid;
4973        if (DEBUG_PROCESSES) Slog.d(
4974            TAG, "Force removing proc " + app.toShortString() + " (" + name
4975            + "/" + uid + ")");
4976
4977        mProcessNames.remove(name, uid);
4978        mIsolatedProcesses.remove(app.uid);
4979        if (mHeavyWeightProcess == app) {
4980            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4981                    mHeavyWeightProcess.userId, 0));
4982            mHeavyWeightProcess = null;
4983        }
4984        boolean needRestart = false;
4985        if (app.pid > 0 && app.pid != MY_PID) {
4986            int pid = app.pid;
4987            synchronized (mPidsSelfLocked) {
4988                mPidsSelfLocked.remove(pid);
4989                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4990            }
4991            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4992                    app.processName, app.info.uid);
4993            if (app.isolated) {
4994                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4995            }
4996            killUnneededProcessLocked(app, reason);
4997            handleAppDiedLocked(app, true, allowRestart);
4998            removeLruProcessLocked(app);
4999
5000            if (app.persistent && !app.isolated) {
5001                if (!callerWillRestart) {
5002                    addAppLocked(app.info, false);
5003                } else {
5004                    needRestart = true;
5005                }
5006            }
5007        } else {
5008            mRemovedProcesses.add(app);
5009        }
5010
5011        return needRestart;
5012    }
5013
5014    private final void processStartTimedOutLocked(ProcessRecord app) {
5015        final int pid = app.pid;
5016        boolean gone = false;
5017        synchronized (mPidsSelfLocked) {
5018            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5019            if (knownApp != null && knownApp.thread == null) {
5020                mPidsSelfLocked.remove(pid);
5021                gone = true;
5022            }
5023        }
5024
5025        if (gone) {
5026            Slog.w(TAG, "Process " + app + " failed to attach");
5027            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5028                    pid, app.uid, app.processName);
5029            mProcessNames.remove(app.processName, app.uid);
5030            mIsolatedProcesses.remove(app.uid);
5031            if (mHeavyWeightProcess == app) {
5032                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5033                        mHeavyWeightProcess.userId, 0));
5034                mHeavyWeightProcess = null;
5035            }
5036            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5037                    app.processName, app.info.uid);
5038            if (app.isolated) {
5039                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5040            }
5041            // Take care of any launching providers waiting for this process.
5042            checkAppInLaunchingProvidersLocked(app, true);
5043            // Take care of any services that are waiting for the process.
5044            mServices.processStartTimedOutLocked(app);
5045            killUnneededProcessLocked(app, "start timeout");
5046            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5047                Slog.w(TAG, "Unattached app died before backup, skipping");
5048                try {
5049                    IBackupManager bm = IBackupManager.Stub.asInterface(
5050                            ServiceManager.getService(Context.BACKUP_SERVICE));
5051                    bm.agentDisconnected(app.info.packageName);
5052                } catch (RemoteException e) {
5053                    // Can't happen; the backup manager is local
5054                }
5055            }
5056            if (isPendingBroadcastProcessLocked(pid)) {
5057                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5058                skipPendingBroadcastLocked(pid);
5059            }
5060        } else {
5061            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5062        }
5063    }
5064
5065    private final boolean attachApplicationLocked(IApplicationThread thread,
5066            int pid) {
5067
5068        // Find the application record that is being attached...  either via
5069        // the pid if we are running in multiple processes, or just pull the
5070        // next app record if we are emulating process with anonymous threads.
5071        ProcessRecord app;
5072        if (pid != MY_PID && pid >= 0) {
5073            synchronized (mPidsSelfLocked) {
5074                app = mPidsSelfLocked.get(pid);
5075            }
5076        } else {
5077            app = null;
5078        }
5079
5080        if (app == null) {
5081            Slog.w(TAG, "No pending application record for pid " + pid
5082                    + " (IApplicationThread " + thread + "); dropping process");
5083            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5084            if (pid > 0 && pid != MY_PID) {
5085                Process.killProcessQuiet(pid);
5086            } else {
5087                try {
5088                    thread.scheduleExit();
5089                } catch (Exception e) {
5090                    // Ignore exceptions.
5091                }
5092            }
5093            return false;
5094        }
5095
5096        // If this application record is still attached to a previous
5097        // process, clean it up now.
5098        if (app.thread != null) {
5099            handleAppDiedLocked(app, true, true);
5100        }
5101
5102        // Tell the process all about itself.
5103
5104        if (localLOGV) Slog.v(
5105                TAG, "Binding process pid " + pid + " to record " + app);
5106
5107        final String processName = app.processName;
5108        try {
5109            AppDeathRecipient adr = new AppDeathRecipient(
5110                    app, pid, thread);
5111            thread.asBinder().linkToDeath(adr, 0);
5112            app.deathRecipient = adr;
5113        } catch (RemoteException e) {
5114            app.resetPackageList(mProcessStats);
5115            startProcessLocked(app, "link fail", processName);
5116            return false;
5117        }
5118
5119        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5120
5121        app.makeActive(thread, mProcessStats);
5122        app.curAdj = app.setAdj = -100;
5123        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5124        app.forcingToForeground = null;
5125        updateProcessForegroundLocked(app, false, false);
5126        app.hasShownUi = false;
5127        app.debugging = false;
5128        app.cached = false;
5129
5130        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5131
5132        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5133        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5134
5135        if (!normalMode) {
5136            Slog.i(TAG, "Launching preboot mode app: " + app);
5137        }
5138
5139        if (localLOGV) Slog.v(
5140            TAG, "New app record " + app
5141            + " thread=" + thread.asBinder() + " pid=" + pid);
5142        try {
5143            int testMode = IApplicationThread.DEBUG_OFF;
5144            if (mDebugApp != null && mDebugApp.equals(processName)) {
5145                testMode = mWaitForDebugger
5146                    ? IApplicationThread.DEBUG_WAIT
5147                    : IApplicationThread.DEBUG_ON;
5148                app.debugging = true;
5149                if (mDebugTransient) {
5150                    mDebugApp = mOrigDebugApp;
5151                    mWaitForDebugger = mOrigWaitForDebugger;
5152                }
5153            }
5154            String profileFile = app.instrumentationProfileFile;
5155            ParcelFileDescriptor profileFd = null;
5156            boolean profileAutoStop = false;
5157            if (mProfileApp != null && mProfileApp.equals(processName)) {
5158                mProfileProc = app;
5159                profileFile = mProfileFile;
5160                profileFd = mProfileFd;
5161                profileAutoStop = mAutoStopProfiler;
5162            }
5163            boolean enableOpenGlTrace = false;
5164            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5165                enableOpenGlTrace = true;
5166                mOpenGlTraceApp = null;
5167            }
5168
5169            // If the app is being launched for restore or full backup, set it up specially
5170            boolean isRestrictedBackupMode = false;
5171            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5172                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5173                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5174                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5175            }
5176
5177            ensurePackageDexOpt(app.instrumentationInfo != null
5178                    ? app.instrumentationInfo.packageName
5179                    : app.info.packageName);
5180            if (app.instrumentationClass != null) {
5181                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5182            }
5183            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5184                    + processName + " with config " + mConfiguration);
5185            ApplicationInfo appInfo = app.instrumentationInfo != null
5186                    ? app.instrumentationInfo : app.info;
5187            app.compat = compatibilityInfoForPackageLocked(appInfo);
5188            if (profileFd != null) {
5189                profileFd = profileFd.dup();
5190            }
5191            thread.bindApplication(processName, appInfo, providers,
5192                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5193                    app.instrumentationArguments, app.instrumentationWatcher,
5194                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5195                    isRestrictedBackupMode || !normalMode, app.persistent,
5196                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5197                    mCoreSettingsObserver.getCoreSettingsLocked());
5198            updateLruProcessLocked(app, false, null);
5199            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5200        } catch (Exception e) {
5201            // todo: Yikes!  What should we do?  For now we will try to
5202            // start another process, but that could easily get us in
5203            // an infinite loop of restarting processes...
5204            Slog.w(TAG, "Exception thrown during bind!", e);
5205
5206            app.resetPackageList(mProcessStats);
5207            app.unlinkDeathRecipient();
5208            startProcessLocked(app, "bind fail", processName);
5209            return false;
5210        }
5211
5212        // Remove this record from the list of starting applications.
5213        mPersistentStartingProcesses.remove(app);
5214        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5215                "Attach application locked removing on hold: " + app);
5216        mProcessesOnHold.remove(app);
5217
5218        boolean badApp = false;
5219        boolean didSomething = false;
5220
5221        // See if the top visible activity is waiting to run in this process...
5222        if (normalMode) {
5223            try {
5224                if (mStackSupervisor.attachApplicationLocked(app)) {
5225                    didSomething = true;
5226                }
5227            } catch (Exception e) {
5228                badApp = true;
5229            }
5230        }
5231
5232        // Find any services that should be running in this process...
5233        if (!badApp) {
5234            try {
5235                didSomething |= mServices.attachApplicationLocked(app, processName);
5236            } catch (Exception e) {
5237                badApp = true;
5238            }
5239        }
5240
5241        // Check if a next-broadcast receiver is in this process...
5242        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5243            try {
5244                didSomething |= sendPendingBroadcastsLocked(app);
5245            } catch (Exception e) {
5246                // If the app died trying to launch the receiver we declare it 'bad'
5247                badApp = true;
5248            }
5249        }
5250
5251        // Check whether the next backup agent is in this process...
5252        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5253            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5254            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5255            try {
5256                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5257                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5258                        mBackupTarget.backupMode);
5259            } catch (Exception e) {
5260                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5261                e.printStackTrace();
5262            }
5263        }
5264
5265        if (badApp) {
5266            // todo: Also need to kill application to deal with all
5267            // kinds of exceptions.
5268            handleAppDiedLocked(app, false, true);
5269            return false;
5270        }
5271
5272        if (!didSomething) {
5273            updateOomAdjLocked();
5274        }
5275
5276        return true;
5277    }
5278
5279    @Override
5280    public final void attachApplication(IApplicationThread thread) {
5281        synchronized (this) {
5282            int callingPid = Binder.getCallingPid();
5283            final long origId = Binder.clearCallingIdentity();
5284            attachApplicationLocked(thread, callingPid);
5285            Binder.restoreCallingIdentity(origId);
5286        }
5287    }
5288
5289    @Override
5290    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5291        final long origId = Binder.clearCallingIdentity();
5292        synchronized (this) {
5293            ActivityStack stack = ActivityRecord.getStackLocked(token);
5294            if (stack != null) {
5295                ActivityRecord r =
5296                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5297                if (stopProfiling) {
5298                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5299                        try {
5300                            mProfileFd.close();
5301                        } catch (IOException e) {
5302                        }
5303                        clearProfilerLocked();
5304                    }
5305                }
5306            }
5307        }
5308        Binder.restoreCallingIdentity(origId);
5309    }
5310
5311    void enableScreenAfterBoot() {
5312        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5313                SystemClock.uptimeMillis());
5314        mWindowManager.enableScreenAfterBoot();
5315
5316        synchronized (this) {
5317            updateEventDispatchingLocked();
5318        }
5319    }
5320
5321    @Override
5322    public void showBootMessage(final CharSequence msg, final boolean always) {
5323        enforceNotIsolatedCaller("showBootMessage");
5324        mWindowManager.showBootMessage(msg, always);
5325    }
5326
5327    @Override
5328    public void dismissKeyguardOnNextActivity() {
5329        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5330        final long token = Binder.clearCallingIdentity();
5331        try {
5332            synchronized (this) {
5333                if (DEBUG_LOCKSCREEN) logLockScreen("");
5334                if (mLockScreenShown) {
5335                    mLockScreenShown = false;
5336                    comeOutOfSleepIfNeededLocked();
5337                }
5338                mStackSupervisor.setDismissKeyguard(true);
5339            }
5340        } finally {
5341            Binder.restoreCallingIdentity(token);
5342        }
5343    }
5344
5345    final void finishBooting() {
5346        // Register receivers to handle package update events
5347        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5348
5349        synchronized (this) {
5350            // Ensure that any processes we had put on hold are now started
5351            // up.
5352            final int NP = mProcessesOnHold.size();
5353            if (NP > 0) {
5354                ArrayList<ProcessRecord> procs =
5355                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5356                for (int ip=0; ip<NP; ip++) {
5357                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5358                            + procs.get(ip));
5359                    startProcessLocked(procs.get(ip), "on-hold", null);
5360                }
5361            }
5362
5363            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5364                // Start looking for apps that are abusing wake locks.
5365                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5366                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5367                // Tell anyone interested that we are done booting!
5368                SystemProperties.set("sys.boot_completed", "1");
5369                SystemProperties.set("dev.bootcomplete", "1");
5370                for (int i=0; i<mStartedUsers.size(); i++) {
5371                    UserStartedState uss = mStartedUsers.valueAt(i);
5372                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5373                        uss.mState = UserStartedState.STATE_RUNNING;
5374                        final int userId = mStartedUsers.keyAt(i);
5375                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5376                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5377                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5378                        broadcastIntentLocked(null, null, intent, null,
5379                                new IIntentReceiver.Stub() {
5380                                    @Override
5381                                    public void performReceive(Intent intent, int resultCode,
5382                                            String data, Bundle extras, boolean ordered,
5383                                            boolean sticky, int sendingUser) {
5384                                        synchronized (ActivityManagerService.this) {
5385                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5386                                                    true, false);
5387                                        }
5388                                    }
5389                                },
5390                                0, null, null,
5391                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5392                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5393                                userId);
5394                    }
5395                }
5396                scheduleStartProfilesLocked();
5397            }
5398        }
5399    }
5400
5401    final void ensureBootCompleted() {
5402        boolean booting;
5403        boolean enableScreen;
5404        synchronized (this) {
5405            booting = mBooting;
5406            mBooting = false;
5407            enableScreen = !mBooted;
5408            mBooted = true;
5409        }
5410
5411        if (booting) {
5412            finishBooting();
5413        }
5414
5415        if (enableScreen) {
5416            enableScreenAfterBoot();
5417        }
5418    }
5419
5420    @Override
5421    public final void activityResumed(IBinder token) {
5422        final long origId = Binder.clearCallingIdentity();
5423        synchronized(this) {
5424            ActivityStack stack = ActivityRecord.getStackLocked(token);
5425            if (stack != null) {
5426                ActivityRecord.activityResumedLocked(token);
5427            }
5428        }
5429        Binder.restoreCallingIdentity(origId);
5430    }
5431
5432    @Override
5433    public final void activityPaused(IBinder token) {
5434        final long origId = Binder.clearCallingIdentity();
5435        synchronized(this) {
5436            ActivityStack stack = ActivityRecord.getStackLocked(token);
5437            if (stack != null) {
5438                stack.activityPausedLocked(token, false);
5439            }
5440        }
5441        Binder.restoreCallingIdentity(origId);
5442    }
5443
5444    @Override
5445    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5446            CharSequence description) {
5447        if (localLOGV) Slog.v(
5448            TAG, "Activity stopped: token=" + token);
5449
5450        // Refuse possible leaked file descriptors
5451        if (icicle != null && icicle.hasFileDescriptors()) {
5452            throw new IllegalArgumentException("File descriptors passed in Bundle");
5453        }
5454
5455        ActivityRecord r = null;
5456
5457        final long origId = Binder.clearCallingIdentity();
5458
5459        synchronized (this) {
5460            r = ActivityRecord.isInStackLocked(token);
5461            if (r != null) {
5462                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5463            }
5464        }
5465
5466        if (r != null) {
5467            sendPendingThumbnail(r, null, null, null, false);
5468        }
5469
5470        trimApplications();
5471
5472        Binder.restoreCallingIdentity(origId);
5473    }
5474
5475    @Override
5476    public final void activityDestroyed(IBinder token) {
5477        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5478        synchronized (this) {
5479            ActivityStack stack = ActivityRecord.getStackLocked(token);
5480            if (stack != null) {
5481                stack.activityDestroyedLocked(token);
5482            }
5483        }
5484    }
5485
5486    @Override
5487    public String getCallingPackage(IBinder token) {
5488        synchronized (this) {
5489            ActivityRecord r = getCallingRecordLocked(token);
5490            return r != null ? r.info.packageName : null;
5491        }
5492    }
5493
5494    @Override
5495    public ComponentName getCallingActivity(IBinder token) {
5496        synchronized (this) {
5497            ActivityRecord r = getCallingRecordLocked(token);
5498            return r != null ? r.intent.getComponent() : null;
5499        }
5500    }
5501
5502    private ActivityRecord getCallingRecordLocked(IBinder token) {
5503        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5504        if (r == null) {
5505            return null;
5506        }
5507        return r.resultTo;
5508    }
5509
5510    @Override
5511    public ComponentName getActivityClassForToken(IBinder token) {
5512        synchronized(this) {
5513            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5514            if (r == null) {
5515                return null;
5516            }
5517            return r.intent.getComponent();
5518        }
5519    }
5520
5521    @Override
5522    public String getPackageForToken(IBinder token) {
5523        synchronized(this) {
5524            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5525            if (r == null) {
5526                return null;
5527            }
5528            return r.packageName;
5529        }
5530    }
5531
5532    @Override
5533    public IIntentSender getIntentSender(int type,
5534            String packageName, IBinder token, String resultWho,
5535            int requestCode, Intent[] intents, String[] resolvedTypes,
5536            int flags, Bundle options, int userId) {
5537        enforceNotIsolatedCaller("getIntentSender");
5538        // Refuse possible leaked file descriptors
5539        if (intents != null) {
5540            if (intents.length < 1) {
5541                throw new IllegalArgumentException("Intents array length must be >= 1");
5542            }
5543            for (int i=0; i<intents.length; i++) {
5544                Intent intent = intents[i];
5545                if (intent != null) {
5546                    if (intent.hasFileDescriptors()) {
5547                        throw new IllegalArgumentException("File descriptors passed in Intent");
5548                    }
5549                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5550                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5551                        throw new IllegalArgumentException(
5552                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5553                    }
5554                    intents[i] = new Intent(intent);
5555                }
5556            }
5557            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5558                throw new IllegalArgumentException(
5559                        "Intent array length does not match resolvedTypes length");
5560            }
5561        }
5562        if (options != null) {
5563            if (options.hasFileDescriptors()) {
5564                throw new IllegalArgumentException("File descriptors passed in options");
5565            }
5566        }
5567
5568        synchronized(this) {
5569            int callingUid = Binder.getCallingUid();
5570            int origUserId = userId;
5571            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5572                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5573                    "getIntentSender", null);
5574            if (origUserId == UserHandle.USER_CURRENT) {
5575                // We don't want to evaluate this until the pending intent is
5576                // actually executed.  However, we do want to always do the
5577                // security checking for it above.
5578                userId = UserHandle.USER_CURRENT;
5579            }
5580            try {
5581                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5582                    int uid = AppGlobals.getPackageManager()
5583                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5584                    if (!UserHandle.isSameApp(callingUid, uid)) {
5585                        String msg = "Permission Denial: getIntentSender() from pid="
5586                            + Binder.getCallingPid()
5587                            + ", uid=" + Binder.getCallingUid()
5588                            + ", (need uid=" + uid + ")"
5589                            + " is not allowed to send as package " + packageName;
5590                        Slog.w(TAG, msg);
5591                        throw new SecurityException(msg);
5592                    }
5593                }
5594
5595                return getIntentSenderLocked(type, packageName, callingUid, userId,
5596                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5597
5598            } catch (RemoteException e) {
5599                throw new SecurityException(e);
5600            }
5601        }
5602    }
5603
5604    IIntentSender getIntentSenderLocked(int type, String packageName,
5605            int callingUid, int userId, IBinder token, String resultWho,
5606            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5607            Bundle options) {
5608        if (DEBUG_MU)
5609            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5610        ActivityRecord activity = null;
5611        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5612            activity = ActivityRecord.isInStackLocked(token);
5613            if (activity == null) {
5614                return null;
5615            }
5616            if (activity.finishing) {
5617                return null;
5618            }
5619        }
5620
5621        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5622        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5623        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5624        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5625                |PendingIntent.FLAG_UPDATE_CURRENT);
5626
5627        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5628                type, packageName, activity, resultWho,
5629                requestCode, intents, resolvedTypes, flags, options, userId);
5630        WeakReference<PendingIntentRecord> ref;
5631        ref = mIntentSenderRecords.get(key);
5632        PendingIntentRecord rec = ref != null ? ref.get() : null;
5633        if (rec != null) {
5634            if (!cancelCurrent) {
5635                if (updateCurrent) {
5636                    if (rec.key.requestIntent != null) {
5637                        rec.key.requestIntent.replaceExtras(intents != null ?
5638                                intents[intents.length - 1] : null);
5639                    }
5640                    if (intents != null) {
5641                        intents[intents.length-1] = rec.key.requestIntent;
5642                        rec.key.allIntents = intents;
5643                        rec.key.allResolvedTypes = resolvedTypes;
5644                    } else {
5645                        rec.key.allIntents = null;
5646                        rec.key.allResolvedTypes = null;
5647                    }
5648                }
5649                return rec;
5650            }
5651            rec.canceled = true;
5652            mIntentSenderRecords.remove(key);
5653        }
5654        if (noCreate) {
5655            return rec;
5656        }
5657        rec = new PendingIntentRecord(this, key, callingUid);
5658        mIntentSenderRecords.put(key, rec.ref);
5659        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5660            if (activity.pendingResults == null) {
5661                activity.pendingResults
5662                        = new HashSet<WeakReference<PendingIntentRecord>>();
5663            }
5664            activity.pendingResults.add(rec.ref);
5665        }
5666        return rec;
5667    }
5668
5669    @Override
5670    public void cancelIntentSender(IIntentSender sender) {
5671        if (!(sender instanceof PendingIntentRecord)) {
5672            return;
5673        }
5674        synchronized(this) {
5675            PendingIntentRecord rec = (PendingIntentRecord)sender;
5676            try {
5677                int uid = AppGlobals.getPackageManager()
5678                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5679                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5680                    String msg = "Permission Denial: cancelIntentSender() from pid="
5681                        + Binder.getCallingPid()
5682                        + ", uid=" + Binder.getCallingUid()
5683                        + " is not allowed to cancel packges "
5684                        + rec.key.packageName;
5685                    Slog.w(TAG, msg);
5686                    throw new SecurityException(msg);
5687                }
5688            } catch (RemoteException e) {
5689                throw new SecurityException(e);
5690            }
5691            cancelIntentSenderLocked(rec, true);
5692        }
5693    }
5694
5695    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5696        rec.canceled = true;
5697        mIntentSenderRecords.remove(rec.key);
5698        if (cleanActivity && rec.key.activity != null) {
5699            rec.key.activity.pendingResults.remove(rec.ref);
5700        }
5701    }
5702
5703    @Override
5704    public String getPackageForIntentSender(IIntentSender pendingResult) {
5705        if (!(pendingResult instanceof PendingIntentRecord)) {
5706            return null;
5707        }
5708        try {
5709            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5710            return res.key.packageName;
5711        } catch (ClassCastException e) {
5712        }
5713        return null;
5714    }
5715
5716    @Override
5717    public int getUidForIntentSender(IIntentSender sender) {
5718        if (sender instanceof PendingIntentRecord) {
5719            try {
5720                PendingIntentRecord res = (PendingIntentRecord)sender;
5721                return res.uid;
5722            } catch (ClassCastException e) {
5723            }
5724        }
5725        return -1;
5726    }
5727
5728    @Override
5729    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5730        if (!(pendingResult instanceof PendingIntentRecord)) {
5731            return false;
5732        }
5733        try {
5734            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5735            if (res.key.allIntents == null) {
5736                return false;
5737            }
5738            for (int i=0; i<res.key.allIntents.length; i++) {
5739                Intent intent = res.key.allIntents[i];
5740                if (intent.getPackage() != null && intent.getComponent() != null) {
5741                    return false;
5742                }
5743            }
5744            return true;
5745        } catch (ClassCastException e) {
5746        }
5747        return false;
5748    }
5749
5750    @Override
5751    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5752        if (!(pendingResult instanceof PendingIntentRecord)) {
5753            return false;
5754        }
5755        try {
5756            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5757            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5758                return true;
5759            }
5760            return false;
5761        } catch (ClassCastException e) {
5762        }
5763        return false;
5764    }
5765
5766    @Override
5767    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5768        if (!(pendingResult instanceof PendingIntentRecord)) {
5769            return null;
5770        }
5771        try {
5772            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5773            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5774        } catch (ClassCastException e) {
5775        }
5776        return null;
5777    }
5778
5779    @Override
5780    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5781        if (!(pendingResult instanceof PendingIntentRecord)) {
5782            return null;
5783        }
5784        try {
5785            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5786            Intent intent = res.key.requestIntent;
5787            if (intent != null) {
5788                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5789                        || res.lastTagPrefix.equals(prefix))) {
5790                    return res.lastTag;
5791                }
5792                res.lastTagPrefix = prefix;
5793                StringBuilder sb = new StringBuilder(128);
5794                if (prefix != null) {
5795                    sb.append(prefix);
5796                }
5797                if (intent.getAction() != null) {
5798                    sb.append(intent.getAction());
5799                } else if (intent.getComponent() != null) {
5800                    intent.getComponent().appendShortString(sb);
5801                } else {
5802                    sb.append("?");
5803                }
5804                return res.lastTag = sb.toString();
5805            }
5806        } catch (ClassCastException e) {
5807        }
5808        return null;
5809    }
5810
5811    @Override
5812    public void setProcessLimit(int max) {
5813        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5814                "setProcessLimit()");
5815        synchronized (this) {
5816            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5817            mProcessLimitOverride = max;
5818        }
5819        trimApplications();
5820    }
5821
5822    @Override
5823    public int getProcessLimit() {
5824        synchronized (this) {
5825            return mProcessLimitOverride;
5826        }
5827    }
5828
5829    void foregroundTokenDied(ForegroundToken token) {
5830        synchronized (ActivityManagerService.this) {
5831            synchronized (mPidsSelfLocked) {
5832                ForegroundToken cur
5833                    = mForegroundProcesses.get(token.pid);
5834                if (cur != token) {
5835                    return;
5836                }
5837                mForegroundProcesses.remove(token.pid);
5838                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5839                if (pr == null) {
5840                    return;
5841                }
5842                pr.forcingToForeground = null;
5843                updateProcessForegroundLocked(pr, false, false);
5844            }
5845            updateOomAdjLocked();
5846        }
5847    }
5848
5849    @Override
5850    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5851        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5852                "setProcessForeground()");
5853        synchronized(this) {
5854            boolean changed = false;
5855
5856            synchronized (mPidsSelfLocked) {
5857                ProcessRecord pr = mPidsSelfLocked.get(pid);
5858                if (pr == null && isForeground) {
5859                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5860                    return;
5861                }
5862                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5863                if (oldToken != null) {
5864                    oldToken.token.unlinkToDeath(oldToken, 0);
5865                    mForegroundProcesses.remove(pid);
5866                    if (pr != null) {
5867                        pr.forcingToForeground = null;
5868                    }
5869                    changed = true;
5870                }
5871                if (isForeground && token != null) {
5872                    ForegroundToken newToken = new ForegroundToken() {
5873                        @Override
5874                        public void binderDied() {
5875                            foregroundTokenDied(this);
5876                        }
5877                    };
5878                    newToken.pid = pid;
5879                    newToken.token = token;
5880                    try {
5881                        token.linkToDeath(newToken, 0);
5882                        mForegroundProcesses.put(pid, newToken);
5883                        pr.forcingToForeground = token;
5884                        changed = true;
5885                    } catch (RemoteException e) {
5886                        // If the process died while doing this, we will later
5887                        // do the cleanup with the process death link.
5888                    }
5889                }
5890            }
5891
5892            if (changed) {
5893                updateOomAdjLocked();
5894            }
5895        }
5896    }
5897
5898    // =========================================================
5899    // PERMISSIONS
5900    // =========================================================
5901
5902    static class PermissionController extends IPermissionController.Stub {
5903        ActivityManagerService mActivityManagerService;
5904        PermissionController(ActivityManagerService activityManagerService) {
5905            mActivityManagerService = activityManagerService;
5906        }
5907
5908        @Override
5909        public boolean checkPermission(String permission, int pid, int uid) {
5910            return mActivityManagerService.checkPermission(permission, pid,
5911                    uid) == PackageManager.PERMISSION_GRANTED;
5912        }
5913    }
5914
5915    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5916        @Override
5917        public int checkComponentPermission(String permission, int pid, int uid,
5918                int owningUid, boolean exported) {
5919            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5920                    owningUid, exported);
5921        }
5922
5923        @Override
5924        public Object getAMSLock() {
5925            return ActivityManagerService.this;
5926        }
5927    }
5928
5929    /**
5930     * This can be called with or without the global lock held.
5931     */
5932    int checkComponentPermission(String permission, int pid, int uid,
5933            int owningUid, boolean exported) {
5934        // We might be performing an operation on behalf of an indirect binder
5935        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5936        // client identity accordingly before proceeding.
5937        Identity tlsIdentity = sCallerIdentity.get();
5938        if (tlsIdentity != null) {
5939            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5940                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5941            uid = tlsIdentity.uid;
5942            pid = tlsIdentity.pid;
5943        }
5944
5945        if (pid == MY_PID) {
5946            return PackageManager.PERMISSION_GRANTED;
5947        }
5948
5949        return ActivityManager.checkComponentPermission(permission, uid,
5950                owningUid, exported);
5951    }
5952
5953    /**
5954     * As the only public entry point for permissions checking, this method
5955     * can enforce the semantic that requesting a check on a null global
5956     * permission is automatically denied.  (Internally a null permission
5957     * string is used when calling {@link #checkComponentPermission} in cases
5958     * when only uid-based security is needed.)
5959     *
5960     * This can be called with or without the global lock held.
5961     */
5962    @Override
5963    public int checkPermission(String permission, int pid, int uid) {
5964        if (permission == null) {
5965            return PackageManager.PERMISSION_DENIED;
5966        }
5967        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5968    }
5969
5970    /**
5971     * Binder IPC calls go through the public entry point.
5972     * This can be called with or without the global lock held.
5973     */
5974    int checkCallingPermission(String permission) {
5975        return checkPermission(permission,
5976                Binder.getCallingPid(),
5977                UserHandle.getAppId(Binder.getCallingUid()));
5978    }
5979
5980    /**
5981     * This can be called with or without the global lock held.
5982     */
5983    void enforceCallingPermission(String permission, String func) {
5984        if (checkCallingPermission(permission)
5985                == PackageManager.PERMISSION_GRANTED) {
5986            return;
5987        }
5988
5989        String msg = "Permission Denial: " + func + " from pid="
5990                + Binder.getCallingPid()
5991                + ", uid=" + Binder.getCallingUid()
5992                + " requires " + permission;
5993        Slog.w(TAG, msg);
5994        throw new SecurityException(msg);
5995    }
5996
5997    /**
5998     * Determine if UID is holding permissions required to access {@link Uri} in
5999     * the given {@link ProviderInfo}. Final permission checking is always done
6000     * in {@link ContentProvider}.
6001     */
6002    private final boolean checkHoldingPermissionsLocked(
6003            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
6004        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6005                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
6006
6007        if (pi.applicationInfo.uid == uid) {
6008            return true;
6009        } else if (!pi.exported) {
6010            return false;
6011        }
6012
6013        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6014        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6015        try {
6016            // check if target holds top-level <provider> permissions
6017            if (!readMet && pi.readPermission != null
6018                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6019                readMet = true;
6020            }
6021            if (!writeMet && pi.writePermission != null
6022                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6023                writeMet = true;
6024            }
6025
6026            // track if unprotected read/write is allowed; any denied
6027            // <path-permission> below removes this ability
6028            boolean allowDefaultRead = pi.readPermission == null;
6029            boolean allowDefaultWrite = pi.writePermission == null;
6030
6031            // check if target holds any <path-permission> that match uri
6032            final PathPermission[] pps = pi.pathPermissions;
6033            if (pps != null) {
6034                final String path = uri.getPath();
6035                int i = pps.length;
6036                while (i > 0 && (!readMet || !writeMet)) {
6037                    i--;
6038                    PathPermission pp = pps[i];
6039                    if (pp.match(path)) {
6040                        if (!readMet) {
6041                            final String pprperm = pp.getReadPermission();
6042                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6043                                    + pprperm + " for " + pp.getPath()
6044                                    + ": match=" + pp.match(path)
6045                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6046                            if (pprperm != null) {
6047                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6048                                    readMet = true;
6049                                } else {
6050                                    allowDefaultRead = false;
6051                                }
6052                            }
6053                        }
6054                        if (!writeMet) {
6055                            final String ppwperm = pp.getWritePermission();
6056                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6057                                    + ppwperm + " for " + pp.getPath()
6058                                    + ": match=" + pp.match(path)
6059                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6060                            if (ppwperm != null) {
6061                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6062                                    writeMet = true;
6063                                } else {
6064                                    allowDefaultWrite = false;
6065                                }
6066                            }
6067                        }
6068                    }
6069                }
6070            }
6071
6072            // grant unprotected <provider> read/write, if not blocked by
6073            // <path-permission> above
6074            if (allowDefaultRead) readMet = true;
6075            if (allowDefaultWrite) writeMet = true;
6076
6077        } catch (RemoteException e) {
6078            return false;
6079        }
6080
6081        return readMet && writeMet;
6082    }
6083
6084    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6085        ProviderInfo pi = null;
6086        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6087        if (cpr != null) {
6088            pi = cpr.info;
6089        } else {
6090            try {
6091                pi = AppGlobals.getPackageManager().resolveContentProvider(
6092                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6093            } catch (RemoteException ex) {
6094            }
6095        }
6096        return pi;
6097    }
6098
6099    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6100        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6101        if (targetUris != null) {
6102            return targetUris.get(uri);
6103        }
6104        return null;
6105    }
6106
6107    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6108            String targetPkg, int targetUid, GrantUri uri) {
6109        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6110        if (targetUris == null) {
6111            targetUris = Maps.newArrayMap();
6112            mGrantedUriPermissions.put(targetUid, targetUris);
6113        }
6114
6115        UriPermission perm = targetUris.get(uri);
6116        if (perm == null) {
6117            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6118            targetUris.put(uri, perm);
6119        }
6120
6121        return perm;
6122    }
6123
6124    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6125        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6126        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6127                : UriPermission.STRENGTH_OWNED;
6128
6129        // Root gets to do everything.
6130        if (uid == 0) {
6131            return true;
6132        }
6133
6134        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6135        if (perms == null) return false;
6136
6137        // First look for exact match
6138        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6139        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6140            return true;
6141        }
6142
6143        // No exact match, look for prefixes
6144        final int N = perms.size();
6145        for (int i = 0; i < N; i++) {
6146            final UriPermission perm = perms.valueAt(i);
6147            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6148                    && perm.getStrength(modeFlags) >= minStrength) {
6149                return true;
6150            }
6151        }
6152
6153        return false;
6154    }
6155
6156    @Override
6157    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6158        enforceNotIsolatedCaller("checkUriPermission");
6159
6160        // Another redirected-binder-call permissions check as in
6161        // {@link checkComponentPermission}.
6162        Identity tlsIdentity = sCallerIdentity.get();
6163        if (tlsIdentity != null) {
6164            uid = tlsIdentity.uid;
6165            pid = tlsIdentity.pid;
6166        }
6167
6168        // Our own process gets to do everything.
6169        if (pid == MY_PID) {
6170            return PackageManager.PERMISSION_GRANTED;
6171        }
6172        synchronized (this) {
6173            return checkUriPermissionLocked(uri, uid, modeFlags)
6174                    ? PackageManager.PERMISSION_GRANTED
6175                    : PackageManager.PERMISSION_DENIED;
6176        }
6177    }
6178
6179    /**
6180     * Check if the targetPkg can be granted permission to access uri by
6181     * the callingUid using the given modeFlags.  Throws a security exception
6182     * if callingUid is not allowed to do this.  Returns the uid of the target
6183     * if the URI permission grant should be performed; returns -1 if it is not
6184     * needed (for example targetPkg already has permission to access the URI).
6185     * If you already know the uid of the target, you can supply it in
6186     * lastTargetUid else set that to -1.
6187     */
6188    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6189            Uri uri, final int modeFlags, int lastTargetUid) {
6190        if (!Intent.isAccessUriMode(modeFlags)) {
6191            return -1;
6192        }
6193
6194        if (targetPkg != null) {
6195            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6196                    "Checking grant " + targetPkg + " permission to " + uri);
6197        }
6198
6199        final IPackageManager pm = AppGlobals.getPackageManager();
6200
6201        // If this is not a content: uri, we can't do anything with it.
6202        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6203            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6204                    "Can't grant URI permission for non-content URI: " + uri);
6205            return -1;
6206        }
6207
6208        final String authority = uri.getAuthority();
6209        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6210        if (pi == null) {
6211            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6212            return -1;
6213        }
6214
6215        int targetUid = lastTargetUid;
6216        if (targetUid < 0 && targetPkg != null) {
6217            try {
6218                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6219                if (targetUid < 0) {
6220                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6221                            "Can't grant URI permission no uid for: " + targetPkg);
6222                    return -1;
6223                }
6224            } catch (RemoteException ex) {
6225                return -1;
6226            }
6227        }
6228
6229        if (targetUid >= 0) {
6230            // First...  does the target actually need this permission?
6231            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6232                // No need to grant the target this permission.
6233                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6234                        "Target " + targetPkg + " already has full permission to " + uri);
6235                return -1;
6236            }
6237        } else {
6238            // First...  there is no target package, so can anyone access it?
6239            boolean allowed = pi.exported;
6240            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6241                if (pi.readPermission != null) {
6242                    allowed = false;
6243                }
6244            }
6245            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6246                if (pi.writePermission != null) {
6247                    allowed = false;
6248                }
6249            }
6250            if (allowed) {
6251                return -1;
6252            }
6253        }
6254
6255        // Second...  is the provider allowing granting of URI permissions?
6256        if (!pi.grantUriPermissions) {
6257            throw new SecurityException("Provider " + pi.packageName
6258                    + "/" + pi.name
6259                    + " does not allow granting of Uri permissions (uri "
6260                    + uri + ")");
6261        }
6262        if (pi.uriPermissionPatterns != null) {
6263            final int N = pi.uriPermissionPatterns.length;
6264            boolean allowed = false;
6265            for (int i=0; i<N; i++) {
6266                if (pi.uriPermissionPatterns[i] != null
6267                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6268                    allowed = true;
6269                    break;
6270                }
6271            }
6272            if (!allowed) {
6273                throw new SecurityException("Provider " + pi.packageName
6274                        + "/" + pi.name
6275                        + " does not allow granting of permission to path of Uri "
6276                        + uri);
6277            }
6278        }
6279
6280        // Third...  does the caller itself have permission to access
6281        // this uri?
6282        if (callingUid != Process.myUid()) {
6283            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6284                // Require they hold a strong enough Uri permission
6285                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6286                    throw new SecurityException("Uid " + callingUid
6287                            + " does not have permission to uri " + uri);
6288                }
6289            }
6290        }
6291
6292        return targetUid;
6293    }
6294
6295    @Override
6296    public int checkGrantUriPermission(int callingUid, String targetPkg,
6297            Uri uri, final int modeFlags) {
6298        enforceNotIsolatedCaller("checkGrantUriPermission");
6299        synchronized(this) {
6300            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6301        }
6302    }
6303
6304    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6305            final int modeFlags, UriPermissionOwner owner) {
6306        if (!Intent.isAccessUriMode(modeFlags)) {
6307            return;
6308        }
6309
6310        // So here we are: the caller has the assumed permission
6311        // to the uri, and the target doesn't.  Let's now give this to
6312        // the target.
6313
6314        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6315                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6316
6317        final String authority = uri.getAuthority();
6318        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6319        if (pi == null) {
6320            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6321            return;
6322        }
6323
6324        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6325        final UriPermission perm = findOrCreateUriPermissionLocked(
6326                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6327        perm.grantModes(modeFlags, owner);
6328    }
6329
6330    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6331            final int modeFlags, UriPermissionOwner owner) {
6332        if (targetPkg == null) {
6333            throw new NullPointerException("targetPkg");
6334        }
6335
6336        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6337        if (targetUid < 0) {
6338            return;
6339        }
6340
6341        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6342    }
6343
6344    static class NeededUriGrants extends ArrayList<Uri> {
6345        final String targetPkg;
6346        final int targetUid;
6347        final int flags;
6348
6349        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6350            this.targetPkg = targetPkg;
6351            this.targetUid = targetUid;
6352            this.flags = flags;
6353        }
6354    }
6355
6356    /**
6357     * Like checkGrantUriPermissionLocked, but takes an Intent.
6358     */
6359    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6360            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6361        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6362                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6363                + " clip=" + (intent != null ? intent.getClipData() : null)
6364                + " from " + intent + "; flags=0x"
6365                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6366
6367        if (targetPkg == null) {
6368            throw new NullPointerException("targetPkg");
6369        }
6370
6371        if (intent == null) {
6372            return null;
6373        }
6374        Uri data = intent.getData();
6375        ClipData clip = intent.getClipData();
6376        if (data == null && clip == null) {
6377            return null;
6378        }
6379
6380        if (data != null) {
6381            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6382                mode, needed != null ? needed.targetUid : -1);
6383            if (targetUid > 0) {
6384                if (needed == null) {
6385                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6386                }
6387                needed.add(data);
6388            }
6389        }
6390        if (clip != null) {
6391            for (int i=0; i<clip.getItemCount(); i++) {
6392                Uri uri = clip.getItemAt(i).getUri();
6393                if (uri != null) {
6394                    int targetUid = -1;
6395                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6396                            mode, needed != null ? needed.targetUid : -1);
6397                    if (targetUid > 0) {
6398                        if (needed == null) {
6399                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6400                        }
6401                        needed.add(uri);
6402                    }
6403                } else {
6404                    Intent clipIntent = clip.getItemAt(i).getIntent();
6405                    if (clipIntent != null) {
6406                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6407                                callingUid, targetPkg, clipIntent, mode, needed);
6408                        if (newNeeded != null) {
6409                            needed = newNeeded;
6410                        }
6411                    }
6412                }
6413            }
6414        }
6415
6416        return needed;
6417    }
6418
6419    /**
6420     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6421     */
6422    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6423            UriPermissionOwner owner) {
6424        if (needed != null) {
6425            for (int i=0; i<needed.size(); i++) {
6426                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6427                        needed.get(i), needed.flags, owner);
6428            }
6429        }
6430    }
6431
6432    void grantUriPermissionFromIntentLocked(int callingUid,
6433            String targetPkg, Intent intent, UriPermissionOwner owner) {
6434        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6435                intent, intent != null ? intent.getFlags() : 0, null);
6436        if (needed == null) {
6437            return;
6438        }
6439
6440        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6441    }
6442
6443    @Override
6444    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6445            Uri uri, final int modeFlags) {
6446        enforceNotIsolatedCaller("grantUriPermission");
6447        synchronized(this) {
6448            final ProcessRecord r = getRecordForAppLocked(caller);
6449            if (r == null) {
6450                throw new SecurityException("Unable to find app for caller "
6451                        + caller
6452                        + " when granting permission to uri " + uri);
6453            }
6454            if (targetPkg == null) {
6455                throw new IllegalArgumentException("null target");
6456            }
6457            if (uri == null) {
6458                throw new IllegalArgumentException("null uri");
6459            }
6460
6461            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6462                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6463                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6464                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6465
6466            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6467        }
6468    }
6469
6470    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6471        if (perm.modeFlags == 0) {
6472            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6473                    perm.targetUid);
6474            if (perms != null) {
6475                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6476                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6477
6478                perms.remove(perm.uri);
6479                if (perms.isEmpty()) {
6480                    mGrantedUriPermissions.remove(perm.targetUid);
6481                }
6482            }
6483        }
6484    }
6485
6486    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6487        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6488
6489        final IPackageManager pm = AppGlobals.getPackageManager();
6490        final String authority = uri.getAuthority();
6491        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6492        if (pi == null) {
6493            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6494            return;
6495        }
6496
6497        // Does the caller have this permission on the URI?
6498        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6499            // Right now, if you are not the original owner of the permission,
6500            // you are not allowed to revoke it.
6501            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6502                throw new SecurityException("Uid " + callingUid
6503                        + " does not have permission to uri " + uri);
6504            //}
6505        }
6506
6507        boolean persistChanged = false;
6508
6509        // Go through all of the permissions and remove any that match.
6510        int N = mGrantedUriPermissions.size();
6511        for (int i = 0; i < N; i++) {
6512            final int targetUid = mGrantedUriPermissions.keyAt(i);
6513            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6514
6515            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6516                final UriPermission perm = it.next();
6517                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6518                    if (DEBUG_URI_PERMISSION)
6519                        Slog.v(TAG,
6520                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6521                    persistChanged |= perm.revokeModes(
6522                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6523                    if (perm.modeFlags == 0) {
6524                        it.remove();
6525                    }
6526                }
6527            }
6528
6529            if (perms.isEmpty()) {
6530                mGrantedUriPermissions.remove(targetUid);
6531                N--;
6532                i--;
6533            }
6534        }
6535
6536        if (persistChanged) {
6537            schedulePersistUriGrants();
6538        }
6539    }
6540
6541    @Override
6542    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6543            final int modeFlags) {
6544        enforceNotIsolatedCaller("revokeUriPermission");
6545        synchronized(this) {
6546            final ProcessRecord r = getRecordForAppLocked(caller);
6547            if (r == null) {
6548                throw new SecurityException("Unable to find app for caller "
6549                        + caller
6550                        + " when revoking permission to uri " + uri);
6551            }
6552            if (uri == null) {
6553                Slog.w(TAG, "revokeUriPermission: null uri");
6554                return;
6555            }
6556
6557            if (!Intent.isAccessUriMode(modeFlags)) {
6558                return;
6559            }
6560
6561            final IPackageManager pm = AppGlobals.getPackageManager();
6562            final String authority = uri.getAuthority();
6563            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6564            if (pi == null) {
6565                Slog.w(TAG, "No content provider found for permission revoke: "
6566                        + uri.toSafeString());
6567                return;
6568            }
6569
6570            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6571        }
6572    }
6573
6574    /**
6575     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6576     * given package.
6577     *
6578     * @param packageName Package name to match, or {@code null} to apply to all
6579     *            packages.
6580     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6581     *            to all users.
6582     * @param persistable If persistable grants should be removed.
6583     */
6584    private void removeUriPermissionsForPackageLocked(
6585            String packageName, int userHandle, boolean persistable) {
6586        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6587            throw new IllegalArgumentException("Must narrow by either package or user");
6588        }
6589
6590        boolean persistChanged = false;
6591
6592        int N = mGrantedUriPermissions.size();
6593        for (int i = 0; i < N; i++) {
6594            final int targetUid = mGrantedUriPermissions.keyAt(i);
6595            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6596
6597            // Only inspect grants matching user
6598            if (userHandle == UserHandle.USER_ALL
6599                    || userHandle == UserHandle.getUserId(targetUid)) {
6600                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6601                    final UriPermission perm = it.next();
6602
6603                    // Only inspect grants matching package
6604                    if (packageName == null || perm.sourcePkg.equals(packageName)
6605                            || perm.targetPkg.equals(packageName)) {
6606                        persistChanged |= perm.revokeModes(
6607                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6608
6609                        // Only remove when no modes remain; any persisted grants
6610                        // will keep this alive.
6611                        if (perm.modeFlags == 0) {
6612                            it.remove();
6613                        }
6614                    }
6615                }
6616
6617                if (perms.isEmpty()) {
6618                    mGrantedUriPermissions.remove(targetUid);
6619                    N--;
6620                    i--;
6621                }
6622            }
6623        }
6624
6625        if (persistChanged) {
6626            schedulePersistUriGrants();
6627        }
6628    }
6629
6630    @Override
6631    public IBinder newUriPermissionOwner(String name) {
6632        enforceNotIsolatedCaller("newUriPermissionOwner");
6633        synchronized(this) {
6634            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6635            return owner.getExternalTokenLocked();
6636        }
6637    }
6638
6639    @Override
6640    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6641            Uri uri, final int modeFlags) {
6642        synchronized(this) {
6643            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6644            if (owner == null) {
6645                throw new IllegalArgumentException("Unknown owner: " + token);
6646            }
6647            if (fromUid != Binder.getCallingUid()) {
6648                if (Binder.getCallingUid() != Process.myUid()) {
6649                    // Only system code can grant URI permissions on behalf
6650                    // of other users.
6651                    throw new SecurityException("nice try");
6652                }
6653            }
6654            if (targetPkg == null) {
6655                throw new IllegalArgumentException("null target");
6656            }
6657            if (uri == null) {
6658                throw new IllegalArgumentException("null uri");
6659            }
6660
6661            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6662        }
6663    }
6664
6665    @Override
6666    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6667        synchronized(this) {
6668            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6669            if (owner == null) {
6670                throw new IllegalArgumentException("Unknown owner: " + token);
6671            }
6672
6673            if (uri == null) {
6674                owner.removeUriPermissionsLocked(mode);
6675            } else {
6676                owner.removeUriPermissionLocked(uri, mode);
6677            }
6678        }
6679    }
6680
6681    private void schedulePersistUriGrants() {
6682        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6683            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6684                    10 * DateUtils.SECOND_IN_MILLIS);
6685        }
6686    }
6687
6688    private void writeGrantedUriPermissions() {
6689        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6690
6691        // Snapshot permissions so we can persist without lock
6692        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6693        synchronized (this) {
6694            final int size = mGrantedUriPermissions.size();
6695            for (int i = 0; i < size; i++) {
6696                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6697                for (UriPermission perm : perms.values()) {
6698                    if (perm.persistedModeFlags != 0) {
6699                        persist.add(perm.snapshot());
6700                    }
6701                }
6702            }
6703        }
6704
6705        FileOutputStream fos = null;
6706        try {
6707            fos = mGrantFile.startWrite();
6708
6709            XmlSerializer out = new FastXmlSerializer();
6710            out.setOutput(fos, "utf-8");
6711            out.startDocument(null, true);
6712            out.startTag(null, TAG_URI_GRANTS);
6713            for (UriPermission.Snapshot perm : persist) {
6714                out.startTag(null, TAG_URI_GRANT);
6715                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6716                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6717                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6718                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6719                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6720                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6721                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6722                out.endTag(null, TAG_URI_GRANT);
6723            }
6724            out.endTag(null, TAG_URI_GRANTS);
6725            out.endDocument();
6726
6727            mGrantFile.finishWrite(fos);
6728        } catch (IOException e) {
6729            if (fos != null) {
6730                mGrantFile.failWrite(fos);
6731            }
6732        }
6733    }
6734
6735    private void readGrantedUriPermissionsLocked() {
6736        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6737
6738        final long now = System.currentTimeMillis();
6739
6740        FileInputStream fis = null;
6741        try {
6742            fis = mGrantFile.openRead();
6743            final XmlPullParser in = Xml.newPullParser();
6744            in.setInput(fis, null);
6745
6746            int type;
6747            while ((type = in.next()) != END_DOCUMENT) {
6748                final String tag = in.getName();
6749                if (type == START_TAG) {
6750                    if (TAG_URI_GRANT.equals(tag)) {
6751                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6752                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6753                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6754                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6755                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6756                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6757                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6758
6759                        // Sanity check that provider still belongs to source package
6760                        final ProviderInfo pi = getProviderInfoLocked(
6761                                uri.getAuthority(), userHandle);
6762                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6763                            int targetUid = -1;
6764                            try {
6765                                targetUid = AppGlobals.getPackageManager()
6766                                        .getPackageUid(targetPkg, userHandle);
6767                            } catch (RemoteException e) {
6768                            }
6769                            if (targetUid != -1) {
6770                                final UriPermission perm = findOrCreateUriPermissionLocked(
6771                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6772                                perm.initPersistedModes(modeFlags, createdTime);
6773                            }
6774                        } else {
6775                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6776                                    + " but instead found " + pi);
6777                        }
6778                    }
6779                }
6780            }
6781        } catch (FileNotFoundException e) {
6782            // Missing grants is okay
6783        } catch (IOException e) {
6784            Log.wtf(TAG, "Failed reading Uri grants", e);
6785        } catch (XmlPullParserException e) {
6786            Log.wtf(TAG, "Failed reading Uri grants", e);
6787        } finally {
6788            IoUtils.closeQuietly(fis);
6789        }
6790    }
6791
6792    @Override
6793    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6794        enforceNotIsolatedCaller("takePersistableUriPermission");
6795
6796        Preconditions.checkFlagsArgument(modeFlags,
6797                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6798
6799        synchronized (this) {
6800            final int callingUid = Binder.getCallingUid();
6801            boolean persistChanged = false;
6802
6803            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6804            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6805
6806            final boolean exactValid = (exactPerm != null)
6807                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6808            final boolean prefixValid = (prefixPerm != null)
6809                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6810
6811            if (!(exactValid || prefixValid)) {
6812                throw new SecurityException("No persistable permission grants found for UID "
6813                        + callingUid + " and Uri " + uri.toSafeString());
6814            }
6815
6816            if (exactValid) {
6817                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6818            }
6819            if (prefixValid) {
6820                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6821            }
6822
6823            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6824
6825            if (persistChanged) {
6826                schedulePersistUriGrants();
6827            }
6828        }
6829    }
6830
6831    @Override
6832    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6833        enforceNotIsolatedCaller("releasePersistableUriPermission");
6834
6835        Preconditions.checkFlagsArgument(modeFlags,
6836                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6837
6838        synchronized (this) {
6839            final int callingUid = Binder.getCallingUid();
6840            boolean persistChanged = false;
6841
6842            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6843            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6844            if (exactPerm == null && prefixPerm == null) {
6845                throw new SecurityException("No permission grants found for UID " + callingUid
6846                        + " and Uri " + uri.toSafeString());
6847            }
6848
6849            if (exactPerm != null) {
6850                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6851                removeUriPermissionIfNeededLocked(exactPerm);
6852            }
6853            if (prefixPerm != null) {
6854                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6855                removeUriPermissionIfNeededLocked(prefixPerm);
6856            }
6857
6858            if (persistChanged) {
6859                schedulePersistUriGrants();
6860            }
6861        }
6862    }
6863
6864    /**
6865     * Prune any older {@link UriPermission} for the given UID until outstanding
6866     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6867     *
6868     * @return if any mutations occured that require persisting.
6869     */
6870    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6871        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6872        if (perms == null) return false;
6873        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6874
6875        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6876        for (UriPermission perm : perms.values()) {
6877            if (perm.persistedModeFlags != 0) {
6878                persisted.add(perm);
6879            }
6880        }
6881
6882        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6883        if (trimCount <= 0) return false;
6884
6885        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6886        for (int i = 0; i < trimCount; i++) {
6887            final UriPermission perm = persisted.get(i);
6888
6889            if (DEBUG_URI_PERMISSION) {
6890                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6891            }
6892
6893            perm.releasePersistableModes(~0);
6894            removeUriPermissionIfNeededLocked(perm);
6895        }
6896
6897        return true;
6898    }
6899
6900    @Override
6901    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6902            String packageName, boolean incoming) {
6903        enforceNotIsolatedCaller("getPersistedUriPermissions");
6904        Preconditions.checkNotNull(packageName, "packageName");
6905
6906        final int callingUid = Binder.getCallingUid();
6907        final IPackageManager pm = AppGlobals.getPackageManager();
6908        try {
6909            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6910            if (packageUid != callingUid) {
6911                throw new SecurityException(
6912                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6913            }
6914        } catch (RemoteException e) {
6915            throw new SecurityException("Failed to verify package name ownership");
6916        }
6917
6918        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6919        synchronized (this) {
6920            if (incoming) {
6921                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6922                        callingUid);
6923                if (perms == null) {
6924                    Slog.w(TAG, "No permission grants found for " + packageName);
6925                } else {
6926                    for (UriPermission perm : perms.values()) {
6927                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6928                            result.add(perm.buildPersistedPublicApiObject());
6929                        }
6930                    }
6931                }
6932            } else {
6933                final int size = mGrantedUriPermissions.size();
6934                for (int i = 0; i < size; i++) {
6935                    final ArrayMap<GrantUri, UriPermission> perms =
6936                            mGrantedUriPermissions.valueAt(i);
6937                    for (UriPermission perm : perms.values()) {
6938                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6939                            result.add(perm.buildPersistedPublicApiObject());
6940                        }
6941                    }
6942                }
6943            }
6944        }
6945        return new ParceledListSlice<android.content.UriPermission>(result);
6946    }
6947
6948    @Override
6949    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6950        synchronized (this) {
6951            ProcessRecord app =
6952                who != null ? getRecordForAppLocked(who) : null;
6953            if (app == null) return;
6954
6955            Message msg = Message.obtain();
6956            msg.what = WAIT_FOR_DEBUGGER_MSG;
6957            msg.obj = app;
6958            msg.arg1 = waiting ? 1 : 0;
6959            mHandler.sendMessage(msg);
6960        }
6961    }
6962
6963    @Override
6964    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6965        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6966        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6967        outInfo.availMem = Process.getFreeMemory();
6968        outInfo.totalMem = Process.getTotalMemory();
6969        outInfo.threshold = homeAppMem;
6970        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6971        outInfo.hiddenAppThreshold = cachedAppMem;
6972        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6973                ProcessList.SERVICE_ADJ);
6974        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6975                ProcessList.VISIBLE_APP_ADJ);
6976        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6977                ProcessList.FOREGROUND_APP_ADJ);
6978    }
6979
6980    // =========================================================
6981    // TASK MANAGEMENT
6982    // =========================================================
6983
6984    @Override
6985    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6986                         IThumbnailReceiver receiver) {
6987        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6988
6989        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6990        ActivityRecord topRecord = null;
6991
6992        synchronized(this) {
6993            if (localLOGV) Slog.v(
6994                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6995                + ", receiver=" + receiver);
6996
6997            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6998                    != PackageManager.PERMISSION_GRANTED) {
6999                if (receiver != null) {
7000                    // If the caller wants to wait for pending thumbnails,
7001                    // it ain't gonna get them.
7002                    try {
7003                        receiver.finished();
7004                    } catch (RemoteException ex) {
7005                    }
7006                }
7007                String msg = "Permission Denial: getTasks() from pid="
7008                        + Binder.getCallingPid()
7009                        + ", uid=" + Binder.getCallingUid()
7010                        + " requires " + android.Manifest.permission.GET_TASKS;
7011                Slog.w(TAG, msg);
7012                throw new SecurityException(msg);
7013            }
7014
7015            // TODO: Improve with MRU list from all ActivityStacks.
7016            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
7017
7018            if (!pending.pendingRecords.isEmpty()) {
7019                mPendingThumbnails.add(pending);
7020            }
7021        }
7022
7023        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
7024
7025        if (topRecord != null) {
7026            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
7027            try {
7028                IApplicationThread topThumbnail = topRecord.app.thread;
7029                topThumbnail.requestThumbnail(topRecord.appToken);
7030            } catch (Exception e) {
7031                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
7032                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
7033            }
7034        }
7035
7036        if (pending.pendingRecords.isEmpty() && receiver != null) {
7037            // In this case all thumbnails were available and the client
7038            // is being asked to be told when the remaining ones come in...
7039            // which is unusually, since the top-most currently running
7040            // activity should never have a canned thumbnail!  Oh well.
7041            try {
7042                receiver.finished();
7043            } catch (RemoteException ex) {
7044            }
7045        }
7046
7047        return list;
7048    }
7049
7050    TaskRecord getMostRecentTask() {
7051        return mRecentTasks.get(0);
7052    }
7053
7054    @Override
7055    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7056            int flags, int userId) {
7057        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7058                false, true, "getRecentTasks", null);
7059
7060        synchronized (this) {
7061            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
7062                    "getRecentTasks()");
7063            final boolean detailed = checkCallingPermission(
7064                    android.Manifest.permission.GET_DETAILED_TASKS)
7065                    == PackageManager.PERMISSION_GRANTED;
7066
7067            IPackageManager pm = AppGlobals.getPackageManager();
7068
7069            final int N = mRecentTasks.size();
7070            ArrayList<ActivityManager.RecentTaskInfo> res
7071                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7072                            maxNum < N ? maxNum : N);
7073
7074            final Set<Integer> includedUsers;
7075            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7076                includedUsers = getProfileIdsLocked(userId);
7077            } else {
7078                includedUsers = new HashSet<Integer>();
7079            }
7080            includedUsers.add(Integer.valueOf(userId));
7081            for (int i=0; i<N && maxNum > 0; i++) {
7082                TaskRecord tr = mRecentTasks.get(i);
7083                // Only add calling user or related users recent tasks
7084                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7085
7086                // Return the entry if desired by the caller.  We always return
7087                // the first entry, because callers always expect this to be the
7088                // foreground app.  We may filter others if the caller has
7089                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7090                // we should exclude the entry.
7091
7092                if (i == 0
7093                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7094                        || (tr.intent == null)
7095                        || ((tr.intent.getFlags()
7096                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7097                    ActivityManager.RecentTaskInfo rti
7098                            = new ActivityManager.RecentTaskInfo();
7099                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7100                    rti.persistentId = tr.taskId;
7101                    rti.baseIntent = new Intent(
7102                            tr.intent != null ? tr.intent : tr.affinityIntent);
7103                    if (!detailed) {
7104                        rti.baseIntent.replaceExtras((Bundle)null);
7105                    }
7106                    rti.origActivity = tr.origActivity;
7107                    rti.description = tr.lastDescription;
7108                    rti.stackId = tr.stack.mStackId;
7109                    rti.userId = tr.userId;
7110
7111                    // Traverse upwards looking for any break between main task activities and
7112                    // utility activities.
7113                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7114                    int activityNdx;
7115                    final int numActivities = activities.size();
7116                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7117                            ++activityNdx) {
7118                        final ActivityRecord r = activities.get(activityNdx);
7119                        if (r.intent != null &&
7120                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7121                                        != 0) {
7122                            break;
7123                        }
7124                    }
7125                    // Traverse downwards starting below break looking for set label and icon.
7126                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
7127                        final ActivityRecord r = activities.get(activityNdx);
7128                        if (r.activityLabel != null || r.activityIcon != null) {
7129                            rti.activityLabel = r.activityLabel;
7130                            rti.activityIcon = r.activityIcon;
7131                            break;
7132                        }
7133                    }
7134
7135                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7136                        // Check whether this activity is currently available.
7137                        try {
7138                            if (rti.origActivity != null) {
7139                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7140                                        == null) {
7141                                    continue;
7142                                }
7143                            } else if (rti.baseIntent != null) {
7144                                if (pm.queryIntentActivities(rti.baseIntent,
7145                                        null, 0, userId) == null) {
7146                                    continue;
7147                                }
7148                            }
7149                        } catch (RemoteException e) {
7150                            // Will never happen.
7151                        }
7152                    }
7153
7154                    res.add(rti);
7155                    maxNum--;
7156                }
7157            }
7158            return res;
7159        }
7160    }
7161
7162    private TaskRecord recentTaskForIdLocked(int id) {
7163        final int N = mRecentTasks.size();
7164            for (int i=0; i<N; i++) {
7165                TaskRecord tr = mRecentTasks.get(i);
7166                if (tr.taskId == id) {
7167                    return tr;
7168                }
7169            }
7170            return null;
7171    }
7172
7173    @Override
7174    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7175        synchronized (this) {
7176            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7177                    "getTaskThumbnails()");
7178            TaskRecord tr = recentTaskForIdLocked(id);
7179            if (tr != null) {
7180                return tr.getTaskThumbnailsLocked();
7181            }
7182        }
7183        return null;
7184    }
7185
7186    @Override
7187    public Bitmap getTaskTopThumbnail(int id) {
7188        synchronized (this) {
7189            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7190                    "getTaskTopThumbnail()");
7191            TaskRecord tr = recentTaskForIdLocked(id);
7192            if (tr != null) {
7193                return tr.getTaskTopThumbnailLocked();
7194            }
7195        }
7196        return null;
7197    }
7198
7199    @Override
7200    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
7201            Bitmap activityIcon) {
7202        synchronized (this) {
7203            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7204            if (r != null) {
7205                r.activityLabel = activityLabel.toString();
7206                r.activityIcon = activityIcon;
7207            }
7208        }
7209    }
7210
7211    @Override
7212    public boolean removeSubTask(int taskId, int subTaskIndex) {
7213        synchronized (this) {
7214            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7215                    "removeSubTask()");
7216            long ident = Binder.clearCallingIdentity();
7217            try {
7218                TaskRecord tr = recentTaskForIdLocked(taskId);
7219                if (tr != null) {
7220                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7221                }
7222                return false;
7223            } finally {
7224                Binder.restoreCallingIdentity(ident);
7225            }
7226        }
7227    }
7228
7229    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7230        if (!pr.killedByAm) {
7231            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7232            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7233                    pr.processName, pr.setAdj, reason);
7234            pr.killedByAm = true;
7235            Process.killProcessQuiet(pr.pid);
7236        }
7237    }
7238
7239    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7240        tr.disposeThumbnail();
7241        mRecentTasks.remove(tr);
7242        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7243        Intent baseIntent = new Intent(
7244                tr.intent != null ? tr.intent : tr.affinityIntent);
7245        ComponentName component = baseIntent.getComponent();
7246        if (component == null) {
7247            Slog.w(TAG, "Now component for base intent of task: " + tr);
7248            return;
7249        }
7250
7251        // Find any running services associated with this app.
7252        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7253
7254        if (killProcesses) {
7255            // Find any running processes associated with this app.
7256            final String pkg = component.getPackageName();
7257            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7258            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7259            for (int i=0; i<pmap.size(); i++) {
7260                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7261                for (int j=0; j<uids.size(); j++) {
7262                    ProcessRecord proc = uids.valueAt(j);
7263                    if (proc.userId != tr.userId) {
7264                        continue;
7265                    }
7266                    if (!proc.pkgList.containsKey(pkg)) {
7267                        continue;
7268                    }
7269                    procs.add(proc);
7270                }
7271            }
7272
7273            // Kill the running processes.
7274            for (int i=0; i<procs.size(); i++) {
7275                ProcessRecord pr = procs.get(i);
7276                if (pr == mHomeProcess) {
7277                    // Don't kill the home process along with tasks from the same package.
7278                    continue;
7279                }
7280                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7281                    killUnneededProcessLocked(pr, "remove task");
7282                } else {
7283                    pr.waitingToKill = "remove task";
7284                }
7285            }
7286        }
7287    }
7288
7289    /**
7290     * Removes the task with the specified task id.
7291     *
7292     * @param taskId Identifier of the task to be removed.
7293     * @param flags Additional operational flags.  May be 0 or
7294     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7295     * @return Returns true if the given task was found and removed.
7296     */
7297    private boolean removeTaskByIdLocked(int taskId, int flags) {
7298        TaskRecord tr = recentTaskForIdLocked(taskId);
7299        if (tr != null) {
7300            tr.removeTaskActivitiesLocked(-1, false);
7301            cleanUpRemovedTaskLocked(tr, flags);
7302            return true;
7303        }
7304        return false;
7305    }
7306
7307    @Override
7308    public boolean removeTask(int taskId, int flags) {
7309        synchronized (this) {
7310            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7311                    "removeTask()");
7312            long ident = Binder.clearCallingIdentity();
7313            try {
7314                return removeTaskByIdLocked(taskId, flags);
7315            } finally {
7316                Binder.restoreCallingIdentity(ident);
7317            }
7318        }
7319    }
7320
7321    /**
7322     * TODO: Add mController hook
7323     */
7324    @Override
7325    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7326        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7327                "moveTaskToFront()");
7328
7329        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7330        synchronized(this) {
7331            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7332                    Binder.getCallingUid(), "Task to front")) {
7333                ActivityOptions.abort(options);
7334                return;
7335            }
7336            final long origId = Binder.clearCallingIdentity();
7337            try {
7338                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7339                if (task == null) {
7340                    return;
7341                }
7342                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7343                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7344                    return;
7345                }
7346                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7347            } finally {
7348                Binder.restoreCallingIdentity(origId);
7349            }
7350            ActivityOptions.abort(options);
7351        }
7352    }
7353
7354    @Override
7355    public void moveTaskToBack(int taskId) {
7356        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7357                "moveTaskToBack()");
7358
7359        synchronized(this) {
7360            TaskRecord tr = recentTaskForIdLocked(taskId);
7361            if (tr != null) {
7362                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7363                ActivityStack stack = tr.stack;
7364                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7365                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7366                            Binder.getCallingUid(), "Task to back")) {
7367                        return;
7368                    }
7369                }
7370                final long origId = Binder.clearCallingIdentity();
7371                try {
7372                    stack.moveTaskToBackLocked(taskId, null);
7373                } finally {
7374                    Binder.restoreCallingIdentity(origId);
7375                }
7376            }
7377        }
7378    }
7379
7380    /**
7381     * Moves an activity, and all of the other activities within the same task, to the bottom
7382     * of the history stack.  The activity's order within the task is unchanged.
7383     *
7384     * @param token A reference to the activity we wish to move
7385     * @param nonRoot If false then this only works if the activity is the root
7386     *                of a task; if true it will work for any activity in a task.
7387     * @return Returns true if the move completed, false if not.
7388     */
7389    @Override
7390    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7391        enforceNotIsolatedCaller("moveActivityTaskToBack");
7392        synchronized(this) {
7393            final long origId = Binder.clearCallingIdentity();
7394            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7395            if (taskId >= 0) {
7396                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7397            }
7398            Binder.restoreCallingIdentity(origId);
7399        }
7400        return false;
7401    }
7402
7403    @Override
7404    public void moveTaskBackwards(int task) {
7405        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7406                "moveTaskBackwards()");
7407
7408        synchronized(this) {
7409            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7410                    Binder.getCallingUid(), "Task backwards")) {
7411                return;
7412            }
7413            final long origId = Binder.clearCallingIdentity();
7414            moveTaskBackwardsLocked(task);
7415            Binder.restoreCallingIdentity(origId);
7416        }
7417    }
7418
7419    private final void moveTaskBackwardsLocked(int task) {
7420        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7421    }
7422
7423    @Override
7424    public IBinder getHomeActivityToken() throws RemoteException {
7425        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7426                "getHomeActivityToken()");
7427        synchronized (this) {
7428            return mStackSupervisor.getHomeActivityToken();
7429        }
7430    }
7431
7432    @Override
7433    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7434            IActivityContainerCallback callback) throws RemoteException {
7435        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7436                "createActivityContainer()");
7437        synchronized (this) {
7438            if (parentActivityToken == null) {
7439                throw new IllegalArgumentException("parent token must not be null");
7440            }
7441            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7442            if (r == null) {
7443                return null;
7444            }
7445            if (callback == null) {
7446                throw new IllegalArgumentException("callback must not be null");
7447            }
7448            return mStackSupervisor.createActivityContainer(r, callback);
7449        }
7450    }
7451
7452    @Override
7453    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7454        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7455                "deleteActivityContainer()");
7456        synchronized (this) {
7457            mStackSupervisor.deleteActivityContainer(container);
7458        }
7459    }
7460
7461    @Override
7462    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7463            throws RemoteException {
7464        synchronized (this) {
7465            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7466            if (stack != null) {
7467                return stack.mActivityContainer;
7468            }
7469            return null;
7470        }
7471    }
7472
7473    @Override
7474    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7475        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7476                "moveTaskToStack()");
7477        if (stackId == HOME_STACK_ID) {
7478            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7479                    new RuntimeException("here").fillInStackTrace());
7480        }
7481        synchronized (this) {
7482            long ident = Binder.clearCallingIdentity();
7483            try {
7484                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7485                        + stackId + " toTop=" + toTop);
7486                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7487            } finally {
7488                Binder.restoreCallingIdentity(ident);
7489            }
7490        }
7491    }
7492
7493    @Override
7494    public void resizeStack(int stackBoxId, Rect bounds) {
7495        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7496                "resizeStackBox()");
7497        long ident = Binder.clearCallingIdentity();
7498        try {
7499            mWindowManager.resizeStack(stackBoxId, bounds);
7500        } finally {
7501            Binder.restoreCallingIdentity(ident);
7502        }
7503    }
7504
7505    @Override
7506    public List<StackInfo> getAllStackInfos() {
7507        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7508                "getAllStackInfos()");
7509        long ident = Binder.clearCallingIdentity();
7510        try {
7511            synchronized (this) {
7512                return mStackSupervisor.getAllStackInfosLocked();
7513            }
7514        } finally {
7515            Binder.restoreCallingIdentity(ident);
7516        }
7517    }
7518
7519    @Override
7520    public StackInfo getStackInfo(int stackId) {
7521        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7522                "getStackInfo()");
7523        long ident = Binder.clearCallingIdentity();
7524        try {
7525            synchronized (this) {
7526                return mStackSupervisor.getStackInfoLocked(stackId);
7527            }
7528        } finally {
7529            Binder.restoreCallingIdentity(ident);
7530        }
7531    }
7532
7533    @Override
7534    public boolean isInHomeStack(int taskId) {
7535        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7536                "getStackInfo()");
7537        long ident = Binder.clearCallingIdentity();
7538        try {
7539            synchronized (this) {
7540                TaskRecord tr = recentTaskForIdLocked(taskId);
7541                if (tr != null) {
7542                    return tr.stack.isHomeStack();
7543                }
7544            }
7545        } finally {
7546            Binder.restoreCallingIdentity(ident);
7547        }
7548        return false;
7549    }
7550
7551    @Override
7552    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7553        synchronized(this) {
7554            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7555        }
7556    }
7557
7558    private boolean isLockTaskAuthorized(ComponentName name) {
7559//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7560//                "startLockTaskMode()");
7561//        DevicePolicyManager dpm = (DevicePolicyManager)
7562//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7563//        return dpm != null && dpm.isLockTaskPermitted(name);
7564        return true;
7565    }
7566
7567    private void startLockTaskMode(TaskRecord task) {
7568        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7569            return;
7570        }
7571        long ident = Binder.clearCallingIdentity();
7572        try {
7573            synchronized (this) {
7574                // Since we lost lock on task, make sure it is still there.
7575                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7576                if (task != null) {
7577                    mStackSupervisor.setLockTaskModeLocked(task);
7578                }
7579            }
7580        } finally {
7581            Binder.restoreCallingIdentity(ident);
7582        }
7583    }
7584
7585    @Override
7586    public void startLockTaskMode(int taskId) {
7587        long ident = Binder.clearCallingIdentity();
7588        try {
7589            final TaskRecord task;
7590            synchronized (this) {
7591                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7592            }
7593            if (task != null) {
7594                startLockTaskMode(task);
7595            }
7596        } finally {
7597            Binder.restoreCallingIdentity(ident);
7598        }
7599    }
7600
7601    @Override
7602    public void startLockTaskMode(IBinder token) {
7603        long ident = Binder.clearCallingIdentity();
7604        try {
7605            final TaskRecord task;
7606            synchronized (this) {
7607                final ActivityRecord r = ActivityRecord.forToken(token);
7608                if (r == null) {
7609                    return;
7610                }
7611                task = r.task;
7612            }
7613            if (task != null) {
7614                startLockTaskMode(task);
7615            }
7616        } finally {
7617            Binder.restoreCallingIdentity(ident);
7618        }
7619    }
7620
7621    @Override
7622    public void stopLockTaskMode() {
7623//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7624//                "stopLockTaskMode()");
7625        synchronized (this) {
7626            mStackSupervisor.setLockTaskModeLocked(null);
7627        }
7628    }
7629
7630    @Override
7631    public boolean isInLockTaskMode() {
7632        synchronized (this) {
7633            return mStackSupervisor.isInLockTaskMode();
7634        }
7635    }
7636
7637    // =========================================================
7638    // THUMBNAILS
7639    // =========================================================
7640
7641    public void reportThumbnail(IBinder token,
7642            Bitmap thumbnail, CharSequence description) {
7643        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7644        final long origId = Binder.clearCallingIdentity();
7645        sendPendingThumbnail(null, token, thumbnail, description, true);
7646        Binder.restoreCallingIdentity(origId);
7647    }
7648
7649    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7650            Bitmap thumbnail, CharSequence description, boolean always) {
7651        TaskRecord task;
7652        ArrayList<PendingThumbnailsRecord> receivers = null;
7653
7654        //System.out.println("Send pending thumbnail: " + r);
7655
7656        synchronized(this) {
7657            if (r == null) {
7658                r = ActivityRecord.isInStackLocked(token);
7659                if (r == null) {
7660                    return;
7661                }
7662            }
7663            if (thumbnail == null && r.thumbHolder != null) {
7664                thumbnail = r.thumbHolder.lastThumbnail;
7665                description = r.thumbHolder.lastDescription;
7666            }
7667            if (thumbnail == null && !always) {
7668                // If there is no thumbnail, and this entry is not actually
7669                // going away, then abort for now and pick up the next
7670                // thumbnail we get.
7671                return;
7672            }
7673            task = r.task;
7674
7675            int N = mPendingThumbnails.size();
7676            int i=0;
7677            while (i<N) {
7678                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7679                //System.out.println("Looking in " + pr.pendingRecords);
7680                if (pr.pendingRecords.remove(r)) {
7681                    if (receivers == null) {
7682                        receivers = new ArrayList<PendingThumbnailsRecord>();
7683                    }
7684                    receivers.add(pr);
7685                    if (pr.pendingRecords.size() == 0) {
7686                        pr.finished = true;
7687                        mPendingThumbnails.remove(i);
7688                        N--;
7689                        continue;
7690                    }
7691                }
7692                i++;
7693            }
7694        }
7695
7696        if (receivers != null) {
7697            final int N = receivers.size();
7698            for (int i=0; i<N; i++) {
7699                try {
7700                    PendingThumbnailsRecord pr = receivers.get(i);
7701                    pr.receiver.newThumbnail(
7702                        task != null ? task.taskId : -1, thumbnail, description);
7703                    if (pr.finished) {
7704                        pr.receiver.finished();
7705                    }
7706                } catch (Exception e) {
7707                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7708                }
7709            }
7710        }
7711    }
7712
7713    // =========================================================
7714    // CONTENT PROVIDERS
7715    // =========================================================
7716
7717    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7718        List<ProviderInfo> providers = null;
7719        try {
7720            providers = AppGlobals.getPackageManager().
7721                queryContentProviders(app.processName, app.uid,
7722                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7723        } catch (RemoteException ex) {
7724        }
7725        if (DEBUG_MU)
7726            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7727        int userId = app.userId;
7728        if (providers != null) {
7729            int N = providers.size();
7730            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7731            for (int i=0; i<N; i++) {
7732                ProviderInfo cpi =
7733                    (ProviderInfo)providers.get(i);
7734                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7735                        cpi.name, cpi.flags);
7736                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7737                    // This is a singleton provider, but a user besides the
7738                    // default user is asking to initialize a process it runs
7739                    // in...  well, no, it doesn't actually run in this process,
7740                    // it runs in the process of the default user.  Get rid of it.
7741                    providers.remove(i);
7742                    N--;
7743                    i--;
7744                    continue;
7745                }
7746
7747                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7748                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7749                if (cpr == null) {
7750                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7751                    mProviderMap.putProviderByClass(comp, cpr);
7752                }
7753                if (DEBUG_MU)
7754                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7755                app.pubProviders.put(cpi.name, cpr);
7756                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7757                    // Don't add this if it is a platform component that is marked
7758                    // to run in multiple processes, because this is actually
7759                    // part of the framework so doesn't make sense to track as a
7760                    // separate apk in the process.
7761                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7762                }
7763                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7764            }
7765        }
7766        return providers;
7767    }
7768
7769    /**
7770     * Check if {@link ProcessRecord} has a possible chance at accessing the
7771     * given {@link ProviderInfo}. Final permission checking is always done
7772     * in {@link ContentProvider}.
7773     */
7774    private final String checkContentProviderPermissionLocked(
7775            ProviderInfo cpi, ProcessRecord r) {
7776        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7777        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7778        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7779                cpi.applicationInfo.uid, cpi.exported)
7780                == PackageManager.PERMISSION_GRANTED) {
7781            return null;
7782        }
7783        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7784                cpi.applicationInfo.uid, cpi.exported)
7785                == PackageManager.PERMISSION_GRANTED) {
7786            return null;
7787        }
7788
7789        PathPermission[] pps = cpi.pathPermissions;
7790        if (pps != null) {
7791            int i = pps.length;
7792            while (i > 0) {
7793                i--;
7794                PathPermission pp = pps[i];
7795                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7796                        cpi.applicationInfo.uid, cpi.exported)
7797                        == PackageManager.PERMISSION_GRANTED) {
7798                    return null;
7799                }
7800                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7801                        cpi.applicationInfo.uid, cpi.exported)
7802                        == PackageManager.PERMISSION_GRANTED) {
7803                    return null;
7804                }
7805            }
7806        }
7807
7808        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7809        if (perms != null) {
7810            for (GrantUri uri : perms.keySet()) {
7811                if (uri.uri.getAuthority().equals(cpi.authority)) {
7812                    return null;
7813                }
7814            }
7815        }
7816
7817        String msg;
7818        if (!cpi.exported) {
7819            msg = "Permission Denial: opening provider " + cpi.name
7820                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7821                    + ", uid=" + callingUid + ") that is not exported from uid "
7822                    + cpi.applicationInfo.uid;
7823        } else {
7824            msg = "Permission Denial: opening provider " + cpi.name
7825                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7826                    + ", uid=" + callingUid + ") requires "
7827                    + cpi.readPermission + " or " + cpi.writePermission;
7828        }
7829        Slog.w(TAG, msg);
7830        return msg;
7831    }
7832
7833    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7834            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7835        if (r != null) {
7836            for (int i=0; i<r.conProviders.size(); i++) {
7837                ContentProviderConnection conn = r.conProviders.get(i);
7838                if (conn.provider == cpr) {
7839                    if (DEBUG_PROVIDER) Slog.v(TAG,
7840                            "Adding provider requested by "
7841                            + r.processName + " from process "
7842                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7843                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7844                    if (stable) {
7845                        conn.stableCount++;
7846                        conn.numStableIncs++;
7847                    } else {
7848                        conn.unstableCount++;
7849                        conn.numUnstableIncs++;
7850                    }
7851                    return conn;
7852                }
7853            }
7854            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7855            if (stable) {
7856                conn.stableCount = 1;
7857                conn.numStableIncs = 1;
7858            } else {
7859                conn.unstableCount = 1;
7860                conn.numUnstableIncs = 1;
7861            }
7862            cpr.connections.add(conn);
7863            r.conProviders.add(conn);
7864            return conn;
7865        }
7866        cpr.addExternalProcessHandleLocked(externalProcessToken);
7867        return null;
7868    }
7869
7870    boolean decProviderCountLocked(ContentProviderConnection conn,
7871            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7872        if (conn != null) {
7873            cpr = conn.provider;
7874            if (DEBUG_PROVIDER) Slog.v(TAG,
7875                    "Removing provider requested by "
7876                    + conn.client.processName + " from process "
7877                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7878                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7879            if (stable) {
7880                conn.stableCount--;
7881            } else {
7882                conn.unstableCount--;
7883            }
7884            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7885                cpr.connections.remove(conn);
7886                conn.client.conProviders.remove(conn);
7887                return true;
7888            }
7889            return false;
7890        }
7891        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7892        return false;
7893    }
7894
7895    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7896            String name, IBinder token, boolean stable, int userId) {
7897        ContentProviderRecord cpr;
7898        ContentProviderConnection conn = null;
7899        ProviderInfo cpi = null;
7900
7901        synchronized(this) {
7902            ProcessRecord r = null;
7903            if (caller != null) {
7904                r = getRecordForAppLocked(caller);
7905                if (r == null) {
7906                    throw new SecurityException(
7907                            "Unable to find app for caller " + caller
7908                          + " (pid=" + Binder.getCallingPid()
7909                          + ") when getting content provider " + name);
7910                }
7911            }
7912
7913            // First check if this content provider has been published...
7914            cpr = mProviderMap.getProviderByName(name, userId);
7915            boolean providerRunning = cpr != null;
7916            if (providerRunning) {
7917                cpi = cpr.info;
7918                String msg;
7919                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7920                    throw new SecurityException(msg);
7921                }
7922
7923                if (r != null && cpr.canRunHere(r)) {
7924                    // This provider has been published or is in the process
7925                    // of being published...  but it is also allowed to run
7926                    // in the caller's process, so don't make a connection
7927                    // and just let the caller instantiate its own instance.
7928                    ContentProviderHolder holder = cpr.newHolder(null);
7929                    // don't give caller the provider object, it needs
7930                    // to make its own.
7931                    holder.provider = null;
7932                    return holder;
7933                }
7934
7935                final long origId = Binder.clearCallingIdentity();
7936
7937                // In this case the provider instance already exists, so we can
7938                // return it right away.
7939                conn = incProviderCountLocked(r, cpr, token, stable);
7940                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7941                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7942                        // If this is a perceptible app accessing the provider,
7943                        // make sure to count it as being accessed and thus
7944                        // back up on the LRU list.  This is good because
7945                        // content providers are often expensive to start.
7946                        updateLruProcessLocked(cpr.proc, false, null);
7947                    }
7948                }
7949
7950                if (cpr.proc != null) {
7951                    if (false) {
7952                        if (cpr.name.flattenToShortString().equals(
7953                                "com.android.providers.calendar/.CalendarProvider2")) {
7954                            Slog.v(TAG, "****************** KILLING "
7955                                + cpr.name.flattenToShortString());
7956                            Process.killProcess(cpr.proc.pid);
7957                        }
7958                    }
7959                    boolean success = updateOomAdjLocked(cpr.proc);
7960                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7961                    // NOTE: there is still a race here where a signal could be
7962                    // pending on the process even though we managed to update its
7963                    // adj level.  Not sure what to do about this, but at least
7964                    // the race is now smaller.
7965                    if (!success) {
7966                        // Uh oh...  it looks like the provider's process
7967                        // has been killed on us.  We need to wait for a new
7968                        // process to be started, and make sure its death
7969                        // doesn't kill our process.
7970                        Slog.i(TAG,
7971                                "Existing provider " + cpr.name.flattenToShortString()
7972                                + " is crashing; detaching " + r);
7973                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7974                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7975                        if (!lastRef) {
7976                            // This wasn't the last ref our process had on
7977                            // the provider...  we have now been killed, bail.
7978                            return null;
7979                        }
7980                        providerRunning = false;
7981                        conn = null;
7982                    }
7983                }
7984
7985                Binder.restoreCallingIdentity(origId);
7986            }
7987
7988            boolean singleton;
7989            if (!providerRunning) {
7990                try {
7991                    cpi = AppGlobals.getPackageManager().
7992                        resolveContentProvider(name,
7993                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7994                } catch (RemoteException ex) {
7995                }
7996                if (cpi == null) {
7997                    return null;
7998                }
7999                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8000                        cpi.name, cpi.flags);
8001                if (singleton) {
8002                    userId = 0;
8003                }
8004                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8005
8006                String msg;
8007                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
8008                    throw new SecurityException(msg);
8009                }
8010
8011                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8012                        && !cpi.processName.equals("system")) {
8013                    // If this content provider does not run in the system
8014                    // process, and the system is not yet ready to run other
8015                    // processes, then fail fast instead of hanging.
8016                    throw new IllegalArgumentException(
8017                            "Attempt to launch content provider before system ready");
8018                }
8019
8020                // Make sure that the user who owns this provider is started.  If not,
8021                // we don't want to allow it to run.
8022                if (mStartedUsers.get(userId) == null) {
8023                    Slog.w(TAG, "Unable to launch app "
8024                            + cpi.applicationInfo.packageName + "/"
8025                            + cpi.applicationInfo.uid + " for provider "
8026                            + name + ": user " + userId + " is stopped");
8027                    return null;
8028                }
8029
8030                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8031                cpr = mProviderMap.getProviderByClass(comp, userId);
8032                final boolean firstClass = cpr == null;
8033                if (firstClass) {
8034                    try {
8035                        ApplicationInfo ai =
8036                            AppGlobals.getPackageManager().
8037                                getApplicationInfo(
8038                                        cpi.applicationInfo.packageName,
8039                                        STOCK_PM_FLAGS, userId);
8040                        if (ai == null) {
8041                            Slog.w(TAG, "No package info for content provider "
8042                                    + cpi.name);
8043                            return null;
8044                        }
8045                        ai = getAppInfoForUser(ai, userId);
8046                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8047                    } catch (RemoteException ex) {
8048                        // pm is in same process, this will never happen.
8049                    }
8050                }
8051
8052                if (r != null && cpr.canRunHere(r)) {
8053                    // If this is a multiprocess provider, then just return its
8054                    // info and allow the caller to instantiate it.  Only do
8055                    // this if the provider is the same user as the caller's
8056                    // process, or can run as root (so can be in any process).
8057                    return cpr.newHolder(null);
8058                }
8059
8060                if (DEBUG_PROVIDER) {
8061                    RuntimeException e = new RuntimeException("here");
8062                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8063                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8064                }
8065
8066                // This is single process, and our app is now connecting to it.
8067                // See if we are already in the process of launching this
8068                // provider.
8069                final int N = mLaunchingProviders.size();
8070                int i;
8071                for (i=0; i<N; i++) {
8072                    if (mLaunchingProviders.get(i) == cpr) {
8073                        break;
8074                    }
8075                }
8076
8077                // If the provider is not already being launched, then get it
8078                // started.
8079                if (i >= N) {
8080                    final long origId = Binder.clearCallingIdentity();
8081
8082                    try {
8083                        // Content provider is now in use, its package can't be stopped.
8084                        try {
8085                            AppGlobals.getPackageManager().setPackageStoppedState(
8086                                    cpr.appInfo.packageName, false, userId);
8087                        } catch (RemoteException e) {
8088                        } catch (IllegalArgumentException e) {
8089                            Slog.w(TAG, "Failed trying to unstop package "
8090                                    + cpr.appInfo.packageName + ": " + e);
8091                        }
8092
8093                        // Use existing process if already started
8094                        ProcessRecord proc = getProcessRecordLocked(
8095                                cpi.processName, cpr.appInfo.uid, false);
8096                        if (proc != null && proc.thread != null) {
8097                            if (DEBUG_PROVIDER) {
8098                                Slog.d(TAG, "Installing in existing process " + proc);
8099                            }
8100                            proc.pubProviders.put(cpi.name, cpr);
8101                            try {
8102                                proc.thread.scheduleInstallProvider(cpi);
8103                            } catch (RemoteException e) {
8104                            }
8105                        } else {
8106                            proc = startProcessLocked(cpi.processName,
8107                                    cpr.appInfo, false, 0, "content provider",
8108                                    new ComponentName(cpi.applicationInfo.packageName,
8109                                            cpi.name), false, false, false);
8110                            if (proc == null) {
8111                                Slog.w(TAG, "Unable to launch app "
8112                                        + cpi.applicationInfo.packageName + "/"
8113                                        + cpi.applicationInfo.uid + " for provider "
8114                                        + name + ": process is bad");
8115                                return null;
8116                            }
8117                        }
8118                        cpr.launchingApp = proc;
8119                        mLaunchingProviders.add(cpr);
8120                    } finally {
8121                        Binder.restoreCallingIdentity(origId);
8122                    }
8123                }
8124
8125                // Make sure the provider is published (the same provider class
8126                // may be published under multiple names).
8127                if (firstClass) {
8128                    mProviderMap.putProviderByClass(comp, cpr);
8129                }
8130
8131                mProviderMap.putProviderByName(name, cpr);
8132                conn = incProviderCountLocked(r, cpr, token, stable);
8133                if (conn != null) {
8134                    conn.waiting = true;
8135                }
8136            }
8137        }
8138
8139        // Wait for the provider to be published...
8140        synchronized (cpr) {
8141            while (cpr.provider == null) {
8142                if (cpr.launchingApp == null) {
8143                    Slog.w(TAG, "Unable to launch app "
8144                            + cpi.applicationInfo.packageName + "/"
8145                            + cpi.applicationInfo.uid + " for provider "
8146                            + name + ": launching app became null");
8147                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8148                            UserHandle.getUserId(cpi.applicationInfo.uid),
8149                            cpi.applicationInfo.packageName,
8150                            cpi.applicationInfo.uid, name);
8151                    return null;
8152                }
8153                try {
8154                    if (DEBUG_MU) {
8155                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8156                                + cpr.launchingApp);
8157                    }
8158                    if (conn != null) {
8159                        conn.waiting = true;
8160                    }
8161                    cpr.wait();
8162                } catch (InterruptedException ex) {
8163                } finally {
8164                    if (conn != null) {
8165                        conn.waiting = false;
8166                    }
8167                }
8168            }
8169        }
8170        return cpr != null ? cpr.newHolder(conn) : null;
8171    }
8172
8173    public final ContentProviderHolder getContentProvider(
8174            IApplicationThread caller, String name, int userId, boolean stable) {
8175        enforceNotIsolatedCaller("getContentProvider");
8176        if (caller == null) {
8177            String msg = "null IApplicationThread when getting content provider "
8178                    + name;
8179            Slog.w(TAG, msg);
8180            throw new SecurityException(msg);
8181        }
8182
8183        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8184                false, true, "getContentProvider", null);
8185        return getContentProviderImpl(caller, name, null, stable, userId);
8186    }
8187
8188    public ContentProviderHolder getContentProviderExternal(
8189            String name, int userId, IBinder token) {
8190        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8191            "Do not have permission in call getContentProviderExternal()");
8192        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8193                false, true, "getContentProvider", null);
8194        return getContentProviderExternalUnchecked(name, token, userId);
8195    }
8196
8197    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8198            IBinder token, int userId) {
8199        return getContentProviderImpl(null, name, token, true, userId);
8200    }
8201
8202    /**
8203     * Drop a content provider from a ProcessRecord's bookkeeping
8204     */
8205    public void removeContentProvider(IBinder connection, boolean stable) {
8206        enforceNotIsolatedCaller("removeContentProvider");
8207        long ident = Binder.clearCallingIdentity();
8208        try {
8209            synchronized (this) {
8210                ContentProviderConnection conn;
8211                try {
8212                    conn = (ContentProviderConnection)connection;
8213                } catch (ClassCastException e) {
8214                    String msg ="removeContentProvider: " + connection
8215                            + " not a ContentProviderConnection";
8216                    Slog.w(TAG, msg);
8217                    throw new IllegalArgumentException(msg);
8218                }
8219                if (conn == null) {
8220                    throw new NullPointerException("connection is null");
8221                }
8222                if (decProviderCountLocked(conn, null, null, stable)) {
8223                    updateOomAdjLocked();
8224                }
8225            }
8226        } finally {
8227            Binder.restoreCallingIdentity(ident);
8228        }
8229    }
8230
8231    public void removeContentProviderExternal(String name, IBinder token) {
8232        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8233            "Do not have permission in call removeContentProviderExternal()");
8234        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8235    }
8236
8237    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8238        synchronized (this) {
8239            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8240            if(cpr == null) {
8241                //remove from mProvidersByClass
8242                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8243                return;
8244            }
8245
8246            //update content provider record entry info
8247            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8248            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8249            if (localCpr.hasExternalProcessHandles()) {
8250                if (localCpr.removeExternalProcessHandleLocked(token)) {
8251                    updateOomAdjLocked();
8252                } else {
8253                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8254                            + " with no external reference for token: "
8255                            + token + ".");
8256                }
8257            } else {
8258                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8259                        + " with no external references.");
8260            }
8261        }
8262    }
8263
8264    public final void publishContentProviders(IApplicationThread caller,
8265            List<ContentProviderHolder> providers) {
8266        if (providers == null) {
8267            return;
8268        }
8269
8270        enforceNotIsolatedCaller("publishContentProviders");
8271        synchronized (this) {
8272            final ProcessRecord r = getRecordForAppLocked(caller);
8273            if (DEBUG_MU)
8274                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8275            if (r == null) {
8276                throw new SecurityException(
8277                        "Unable to find app for caller " + caller
8278                      + " (pid=" + Binder.getCallingPid()
8279                      + ") when publishing content providers");
8280            }
8281
8282            final long origId = Binder.clearCallingIdentity();
8283
8284            final int N = providers.size();
8285            for (int i=0; i<N; i++) {
8286                ContentProviderHolder src = providers.get(i);
8287                if (src == null || src.info == null || src.provider == null) {
8288                    continue;
8289                }
8290                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8291                if (DEBUG_MU)
8292                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8293                if (dst != null) {
8294                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8295                    mProviderMap.putProviderByClass(comp, dst);
8296                    String names[] = dst.info.authority.split(";");
8297                    for (int j = 0; j < names.length; j++) {
8298                        mProviderMap.putProviderByName(names[j], dst);
8299                    }
8300
8301                    int NL = mLaunchingProviders.size();
8302                    int j;
8303                    for (j=0; j<NL; j++) {
8304                        if (mLaunchingProviders.get(j) == dst) {
8305                            mLaunchingProviders.remove(j);
8306                            j--;
8307                            NL--;
8308                        }
8309                    }
8310                    synchronized (dst) {
8311                        dst.provider = src.provider;
8312                        dst.proc = r;
8313                        dst.notifyAll();
8314                    }
8315                    updateOomAdjLocked(r);
8316                }
8317            }
8318
8319            Binder.restoreCallingIdentity(origId);
8320        }
8321    }
8322
8323    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8324        ContentProviderConnection conn;
8325        try {
8326            conn = (ContentProviderConnection)connection;
8327        } catch (ClassCastException e) {
8328            String msg ="refContentProvider: " + connection
8329                    + " not a ContentProviderConnection";
8330            Slog.w(TAG, msg);
8331            throw new IllegalArgumentException(msg);
8332        }
8333        if (conn == null) {
8334            throw new NullPointerException("connection is null");
8335        }
8336
8337        synchronized (this) {
8338            if (stable > 0) {
8339                conn.numStableIncs += stable;
8340            }
8341            stable = conn.stableCount + stable;
8342            if (stable < 0) {
8343                throw new IllegalStateException("stableCount < 0: " + stable);
8344            }
8345
8346            if (unstable > 0) {
8347                conn.numUnstableIncs += unstable;
8348            }
8349            unstable = conn.unstableCount + unstable;
8350            if (unstable < 0) {
8351                throw new IllegalStateException("unstableCount < 0: " + unstable);
8352            }
8353
8354            if ((stable+unstable) <= 0) {
8355                throw new IllegalStateException("ref counts can't go to zero here: stable="
8356                        + stable + " unstable=" + unstable);
8357            }
8358            conn.stableCount = stable;
8359            conn.unstableCount = unstable;
8360            return !conn.dead;
8361        }
8362    }
8363
8364    public void unstableProviderDied(IBinder connection) {
8365        ContentProviderConnection conn;
8366        try {
8367            conn = (ContentProviderConnection)connection;
8368        } catch (ClassCastException e) {
8369            String msg ="refContentProvider: " + connection
8370                    + " not a ContentProviderConnection";
8371            Slog.w(TAG, msg);
8372            throw new IllegalArgumentException(msg);
8373        }
8374        if (conn == null) {
8375            throw new NullPointerException("connection is null");
8376        }
8377
8378        // Safely retrieve the content provider associated with the connection.
8379        IContentProvider provider;
8380        synchronized (this) {
8381            provider = conn.provider.provider;
8382        }
8383
8384        if (provider == null) {
8385            // Um, yeah, we're way ahead of you.
8386            return;
8387        }
8388
8389        // Make sure the caller is being honest with us.
8390        if (provider.asBinder().pingBinder()) {
8391            // Er, no, still looks good to us.
8392            synchronized (this) {
8393                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8394                        + " says " + conn + " died, but we don't agree");
8395                return;
8396            }
8397        }
8398
8399        // Well look at that!  It's dead!
8400        synchronized (this) {
8401            if (conn.provider.provider != provider) {
8402                // But something changed...  good enough.
8403                return;
8404            }
8405
8406            ProcessRecord proc = conn.provider.proc;
8407            if (proc == null || proc.thread == null) {
8408                // Seems like the process is already cleaned up.
8409                return;
8410            }
8411
8412            // As far as we're concerned, this is just like receiving a
8413            // death notification...  just a bit prematurely.
8414            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8415                    + ") early provider death");
8416            final long ident = Binder.clearCallingIdentity();
8417            try {
8418                appDiedLocked(proc, proc.pid, proc.thread);
8419            } finally {
8420                Binder.restoreCallingIdentity(ident);
8421            }
8422        }
8423    }
8424
8425    @Override
8426    public void appNotRespondingViaProvider(IBinder connection) {
8427        enforceCallingPermission(
8428                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8429
8430        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8431        if (conn == null) {
8432            Slog.w(TAG, "ContentProviderConnection is null");
8433            return;
8434        }
8435
8436        final ProcessRecord host = conn.provider.proc;
8437        if (host == null) {
8438            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8439            return;
8440        }
8441
8442        final long token = Binder.clearCallingIdentity();
8443        try {
8444            appNotResponding(host, null, null, false, "ContentProvider not responding");
8445        } finally {
8446            Binder.restoreCallingIdentity(token);
8447        }
8448    }
8449
8450    public final void installSystemProviders() {
8451        List<ProviderInfo> providers;
8452        synchronized (this) {
8453            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8454            providers = generateApplicationProvidersLocked(app);
8455            if (providers != null) {
8456                for (int i=providers.size()-1; i>=0; i--) {
8457                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8458                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8459                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8460                                + ": not system .apk");
8461                        providers.remove(i);
8462                    }
8463                }
8464            }
8465        }
8466        if (providers != null) {
8467            mSystemThread.installSystemProviders(providers);
8468        }
8469
8470        mCoreSettingsObserver = new CoreSettingsObserver(this);
8471
8472        mUsageStatsService.monitorPackages();
8473    }
8474
8475    /**
8476     * Allows app to retrieve the MIME type of a URI without having permission
8477     * to access its content provider.
8478     *
8479     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8480     *
8481     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8482     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8483     */
8484    public String getProviderMimeType(Uri uri, int userId) {
8485        enforceNotIsolatedCaller("getProviderMimeType");
8486        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8487                userId, false, true, "getProviderMimeType", null);
8488        final String name = uri.getAuthority();
8489        final long ident = Binder.clearCallingIdentity();
8490        ContentProviderHolder holder = null;
8491
8492        try {
8493            holder = getContentProviderExternalUnchecked(name, null, userId);
8494            if (holder != null) {
8495                return holder.provider.getType(uri);
8496            }
8497        } catch (RemoteException e) {
8498            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8499            return null;
8500        } finally {
8501            if (holder != null) {
8502                removeContentProviderExternalUnchecked(name, null, userId);
8503            }
8504            Binder.restoreCallingIdentity(ident);
8505        }
8506
8507        return null;
8508    }
8509
8510    // =========================================================
8511    // GLOBAL MANAGEMENT
8512    // =========================================================
8513
8514    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8515            boolean isolated) {
8516        String proc = customProcess != null ? customProcess : info.processName;
8517        BatteryStatsImpl.Uid.Proc ps = null;
8518        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8519        int uid = info.uid;
8520        if (isolated) {
8521            int userId = UserHandle.getUserId(uid);
8522            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8523            while (true) {
8524                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8525                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8526                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8527                }
8528                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8529                mNextIsolatedProcessUid++;
8530                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8531                    // No process for this uid, use it.
8532                    break;
8533                }
8534                stepsLeft--;
8535                if (stepsLeft <= 0) {
8536                    return null;
8537                }
8538            }
8539        }
8540        return new ProcessRecord(stats, info, proc, uid);
8541    }
8542
8543    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8544        ProcessRecord app;
8545        if (!isolated) {
8546            app = getProcessRecordLocked(info.processName, info.uid, true);
8547        } else {
8548            app = null;
8549        }
8550
8551        if (app == null) {
8552            app = newProcessRecordLocked(info, null, isolated);
8553            mProcessNames.put(info.processName, app.uid, app);
8554            if (isolated) {
8555                mIsolatedProcesses.put(app.uid, app);
8556            }
8557            updateLruProcessLocked(app, false, null);
8558            updateOomAdjLocked();
8559        }
8560
8561        // This package really, really can not be stopped.
8562        try {
8563            AppGlobals.getPackageManager().setPackageStoppedState(
8564                    info.packageName, false, UserHandle.getUserId(app.uid));
8565        } catch (RemoteException e) {
8566        } catch (IllegalArgumentException e) {
8567            Slog.w(TAG, "Failed trying to unstop package "
8568                    + info.packageName + ": " + e);
8569        }
8570
8571        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8572                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8573            app.persistent = true;
8574            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8575        }
8576        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8577            mPersistentStartingProcesses.add(app);
8578            startProcessLocked(app, "added application", app.processName);
8579        }
8580
8581        return app;
8582    }
8583
8584    public void unhandledBack() {
8585        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8586                "unhandledBack()");
8587
8588        synchronized(this) {
8589            final long origId = Binder.clearCallingIdentity();
8590            try {
8591                getFocusedStack().unhandledBackLocked();
8592            } finally {
8593                Binder.restoreCallingIdentity(origId);
8594            }
8595        }
8596    }
8597
8598    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8599        enforceNotIsolatedCaller("openContentUri");
8600        final int userId = UserHandle.getCallingUserId();
8601        String name = uri.getAuthority();
8602        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8603        ParcelFileDescriptor pfd = null;
8604        if (cph != null) {
8605            // We record the binder invoker's uid in thread-local storage before
8606            // going to the content provider to open the file.  Later, in the code
8607            // that handles all permissions checks, we look for this uid and use
8608            // that rather than the Activity Manager's own uid.  The effect is that
8609            // we do the check against the caller's permissions even though it looks
8610            // to the content provider like the Activity Manager itself is making
8611            // the request.
8612            sCallerIdentity.set(new Identity(
8613                    Binder.getCallingPid(), Binder.getCallingUid()));
8614            try {
8615                pfd = cph.provider.openFile(null, uri, "r", null);
8616            } catch (FileNotFoundException e) {
8617                // do nothing; pfd will be returned null
8618            } finally {
8619                // Ensure that whatever happens, we clean up the identity state
8620                sCallerIdentity.remove();
8621            }
8622
8623            // We've got the fd now, so we're done with the provider.
8624            removeContentProviderExternalUnchecked(name, null, userId);
8625        } else {
8626            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8627        }
8628        return pfd;
8629    }
8630
8631    // Actually is sleeping or shutting down or whatever else in the future
8632    // is an inactive state.
8633    public boolean isSleepingOrShuttingDown() {
8634        return mSleeping || mShuttingDown;
8635    }
8636
8637    public boolean isSleeping() {
8638        return mSleeping;
8639    }
8640
8641    void goingToSleep() {
8642        synchronized(this) {
8643            mWentToSleep = true;
8644            updateEventDispatchingLocked();
8645            goToSleepIfNeededLocked();
8646        }
8647    }
8648
8649    void finishRunningVoiceLocked() {
8650        if (mRunningVoice) {
8651            mRunningVoice = false;
8652            goToSleepIfNeededLocked();
8653        }
8654    }
8655
8656    void goToSleepIfNeededLocked() {
8657        if (mWentToSleep && !mRunningVoice) {
8658            if (!mSleeping) {
8659                mSleeping = true;
8660                mStackSupervisor.goingToSleepLocked();
8661
8662                // Initialize the wake times of all processes.
8663                checkExcessivePowerUsageLocked(false);
8664                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8665                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8666                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8667            }
8668        }
8669    }
8670
8671    @Override
8672    public boolean shutdown(int timeout) {
8673        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8674                != PackageManager.PERMISSION_GRANTED) {
8675            throw new SecurityException("Requires permission "
8676                    + android.Manifest.permission.SHUTDOWN);
8677        }
8678
8679        boolean timedout = false;
8680
8681        synchronized(this) {
8682            mShuttingDown = true;
8683            updateEventDispatchingLocked();
8684            timedout = mStackSupervisor.shutdownLocked(timeout);
8685        }
8686
8687        mAppOpsService.shutdown();
8688        mUsageStatsService.shutdown();
8689        mBatteryStatsService.shutdown();
8690        synchronized (this) {
8691            mProcessStats.shutdownLocked();
8692        }
8693
8694        return timedout;
8695    }
8696
8697    public final void activitySlept(IBinder token) {
8698        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8699
8700        final long origId = Binder.clearCallingIdentity();
8701
8702        synchronized (this) {
8703            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8704            if (r != null) {
8705                mStackSupervisor.activitySleptLocked(r);
8706            }
8707        }
8708
8709        Binder.restoreCallingIdentity(origId);
8710    }
8711
8712    void logLockScreen(String msg) {
8713        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8714                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8715                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8716                mStackSupervisor.mDismissKeyguardOnNextActivity);
8717    }
8718
8719    private void comeOutOfSleepIfNeededLocked() {
8720        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8721            if (mSleeping) {
8722                mSleeping = false;
8723                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8724            }
8725        }
8726    }
8727
8728    void wakingUp() {
8729        synchronized(this) {
8730            mWentToSleep = false;
8731            updateEventDispatchingLocked();
8732            comeOutOfSleepIfNeededLocked();
8733        }
8734    }
8735
8736    void startRunningVoiceLocked() {
8737        if (!mRunningVoice) {
8738            mRunningVoice = true;
8739            comeOutOfSleepIfNeededLocked();
8740        }
8741    }
8742
8743    private void updateEventDispatchingLocked() {
8744        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8745    }
8746
8747    public void setLockScreenShown(boolean shown) {
8748        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8749                != PackageManager.PERMISSION_GRANTED) {
8750            throw new SecurityException("Requires permission "
8751                    + android.Manifest.permission.DEVICE_POWER);
8752        }
8753
8754        synchronized(this) {
8755            long ident = Binder.clearCallingIdentity();
8756            try {
8757                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8758                mLockScreenShown = shown;
8759                comeOutOfSleepIfNeededLocked();
8760            } finally {
8761                Binder.restoreCallingIdentity(ident);
8762            }
8763        }
8764    }
8765
8766    public void stopAppSwitches() {
8767        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8768                != PackageManager.PERMISSION_GRANTED) {
8769            throw new SecurityException("Requires permission "
8770                    + android.Manifest.permission.STOP_APP_SWITCHES);
8771        }
8772
8773        synchronized(this) {
8774            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8775                    + APP_SWITCH_DELAY_TIME;
8776            mDidAppSwitch = false;
8777            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8778            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8779            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8780        }
8781    }
8782
8783    public void resumeAppSwitches() {
8784        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8785                != PackageManager.PERMISSION_GRANTED) {
8786            throw new SecurityException("Requires permission "
8787                    + android.Manifest.permission.STOP_APP_SWITCHES);
8788        }
8789
8790        synchronized(this) {
8791            // Note that we don't execute any pending app switches... we will
8792            // let those wait until either the timeout, or the next start
8793            // activity request.
8794            mAppSwitchesAllowedTime = 0;
8795        }
8796    }
8797
8798    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8799            String name) {
8800        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8801            return true;
8802        }
8803
8804        final int perm = checkComponentPermission(
8805                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8806                callingUid, -1, true);
8807        if (perm == PackageManager.PERMISSION_GRANTED) {
8808            return true;
8809        }
8810
8811        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8812        return false;
8813    }
8814
8815    public void setDebugApp(String packageName, boolean waitForDebugger,
8816            boolean persistent) {
8817        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8818                "setDebugApp()");
8819
8820        long ident = Binder.clearCallingIdentity();
8821        try {
8822            // Note that this is not really thread safe if there are multiple
8823            // callers into it at the same time, but that's not a situation we
8824            // care about.
8825            if (persistent) {
8826                final ContentResolver resolver = mContext.getContentResolver();
8827                Settings.Global.putString(
8828                    resolver, Settings.Global.DEBUG_APP,
8829                    packageName);
8830                Settings.Global.putInt(
8831                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8832                    waitForDebugger ? 1 : 0);
8833            }
8834
8835            synchronized (this) {
8836                if (!persistent) {
8837                    mOrigDebugApp = mDebugApp;
8838                    mOrigWaitForDebugger = mWaitForDebugger;
8839                }
8840                mDebugApp = packageName;
8841                mWaitForDebugger = waitForDebugger;
8842                mDebugTransient = !persistent;
8843                if (packageName != null) {
8844                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8845                            false, UserHandle.USER_ALL, "set debug app");
8846                }
8847            }
8848        } finally {
8849            Binder.restoreCallingIdentity(ident);
8850        }
8851    }
8852
8853    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8854        synchronized (this) {
8855            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8856            if (!isDebuggable) {
8857                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8858                    throw new SecurityException("Process not debuggable: " + app.packageName);
8859                }
8860            }
8861
8862            mOpenGlTraceApp = processName;
8863        }
8864    }
8865
8866    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8867            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8868        synchronized (this) {
8869            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8870            if (!isDebuggable) {
8871                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8872                    throw new SecurityException("Process not debuggable: " + app.packageName);
8873                }
8874            }
8875            mProfileApp = processName;
8876            mProfileFile = profileFile;
8877            if (mProfileFd != null) {
8878                try {
8879                    mProfileFd.close();
8880                } catch (IOException e) {
8881                }
8882                mProfileFd = null;
8883            }
8884            mProfileFd = profileFd;
8885            mProfileType = 0;
8886            mAutoStopProfiler = autoStopProfiler;
8887        }
8888    }
8889
8890    @Override
8891    public void setAlwaysFinish(boolean enabled) {
8892        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8893                "setAlwaysFinish()");
8894
8895        Settings.Global.putInt(
8896                mContext.getContentResolver(),
8897                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8898
8899        synchronized (this) {
8900            mAlwaysFinishActivities = enabled;
8901        }
8902    }
8903
8904    @Override
8905    public void setActivityController(IActivityController controller) {
8906        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8907                "setActivityController()");
8908        synchronized (this) {
8909            mController = controller;
8910            Watchdog.getInstance().setActivityController(controller);
8911        }
8912    }
8913
8914    @Override
8915    public void setUserIsMonkey(boolean userIsMonkey) {
8916        synchronized (this) {
8917            synchronized (mPidsSelfLocked) {
8918                final int callingPid = Binder.getCallingPid();
8919                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8920                if (precessRecord == null) {
8921                    throw new SecurityException("Unknown process: " + callingPid);
8922                }
8923                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8924                    throw new SecurityException("Only an instrumentation process "
8925                            + "with a UiAutomation can call setUserIsMonkey");
8926                }
8927            }
8928            mUserIsMonkey = userIsMonkey;
8929        }
8930    }
8931
8932    @Override
8933    public boolean isUserAMonkey() {
8934        synchronized (this) {
8935            // If there is a controller also implies the user is a monkey.
8936            return (mUserIsMonkey || mController != null);
8937        }
8938    }
8939
8940    public void requestBugReport() {
8941        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8942        SystemProperties.set("ctl.start", "bugreport");
8943    }
8944
8945    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8946        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8947    }
8948
8949    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8950        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8951            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8952        }
8953        return KEY_DISPATCHING_TIMEOUT;
8954    }
8955
8956    @Override
8957    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8958        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8959                != PackageManager.PERMISSION_GRANTED) {
8960            throw new SecurityException("Requires permission "
8961                    + android.Manifest.permission.FILTER_EVENTS);
8962        }
8963        ProcessRecord proc;
8964        long timeout;
8965        synchronized (this) {
8966            synchronized (mPidsSelfLocked) {
8967                proc = mPidsSelfLocked.get(pid);
8968            }
8969            timeout = getInputDispatchingTimeoutLocked(proc);
8970        }
8971
8972        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8973            return -1;
8974        }
8975
8976        return timeout;
8977    }
8978
8979    /**
8980     * Handle input dispatching timeouts.
8981     * Returns whether input dispatching should be aborted or not.
8982     */
8983    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8984            final ActivityRecord activity, final ActivityRecord parent,
8985            final boolean aboveSystem, String reason) {
8986        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8987                != PackageManager.PERMISSION_GRANTED) {
8988            throw new SecurityException("Requires permission "
8989                    + android.Manifest.permission.FILTER_EVENTS);
8990        }
8991
8992        final String annotation;
8993        if (reason == null) {
8994            annotation = "Input dispatching timed out";
8995        } else {
8996            annotation = "Input dispatching timed out (" + reason + ")";
8997        }
8998
8999        if (proc != null) {
9000            synchronized (this) {
9001                if (proc.debugging) {
9002                    return false;
9003                }
9004
9005                if (mDidDexOpt) {
9006                    // Give more time since we were dexopting.
9007                    mDidDexOpt = false;
9008                    return false;
9009                }
9010
9011                if (proc.instrumentationClass != null) {
9012                    Bundle info = new Bundle();
9013                    info.putString("shortMsg", "keyDispatchingTimedOut");
9014                    info.putString("longMsg", annotation);
9015                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9016                    return true;
9017                }
9018            }
9019            mHandler.post(new Runnable() {
9020                @Override
9021                public void run() {
9022                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9023                }
9024            });
9025        }
9026
9027        return true;
9028    }
9029
9030    public Bundle getAssistContextExtras(int requestType) {
9031        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9032                "getAssistContextExtras()");
9033        PendingAssistExtras pae;
9034        Bundle extras = new Bundle();
9035        synchronized (this) {
9036            ActivityRecord activity = getFocusedStack().mResumedActivity;
9037            if (activity == null) {
9038                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9039                return null;
9040            }
9041            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9042            if (activity.app == null || activity.app.thread == null) {
9043                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9044                return extras;
9045            }
9046            if (activity.app.pid == Binder.getCallingPid()) {
9047                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9048                return extras;
9049            }
9050            pae = new PendingAssistExtras(activity);
9051            try {
9052                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9053                        requestType);
9054                mPendingAssistExtras.add(pae);
9055                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9056            } catch (RemoteException e) {
9057                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9058                return extras;
9059            }
9060        }
9061        synchronized (pae) {
9062            while (!pae.haveResult) {
9063                try {
9064                    pae.wait();
9065                } catch (InterruptedException e) {
9066                }
9067            }
9068            if (pae.result != null) {
9069                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9070            }
9071        }
9072        synchronized (this) {
9073            mPendingAssistExtras.remove(pae);
9074            mHandler.removeCallbacks(pae);
9075        }
9076        return extras;
9077    }
9078
9079    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9080        PendingAssistExtras pae = (PendingAssistExtras)token;
9081        synchronized (pae) {
9082            pae.result = extras;
9083            pae.haveResult = true;
9084            pae.notifyAll();
9085        }
9086    }
9087
9088    public void registerProcessObserver(IProcessObserver observer) {
9089        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9090                "registerProcessObserver()");
9091        synchronized (this) {
9092            mProcessObservers.register(observer);
9093        }
9094    }
9095
9096    @Override
9097    public void unregisterProcessObserver(IProcessObserver observer) {
9098        synchronized (this) {
9099            mProcessObservers.unregister(observer);
9100        }
9101    }
9102
9103    @Override
9104    public boolean convertFromTranslucent(IBinder token) {
9105        final long origId = Binder.clearCallingIdentity();
9106        try {
9107            synchronized (this) {
9108                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9109                if (r == null) {
9110                    return false;
9111                }
9112                if (r.changeWindowTranslucency(true)) {
9113                    mWindowManager.setAppFullscreen(token, true);
9114                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9115                    return true;
9116                }
9117                return false;
9118            }
9119        } finally {
9120            Binder.restoreCallingIdentity(origId);
9121        }
9122    }
9123
9124    @Override
9125    public boolean convertToTranslucent(IBinder token) {
9126        final long origId = Binder.clearCallingIdentity();
9127        try {
9128            synchronized (this) {
9129                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9130                if (r == null) {
9131                    return false;
9132                }
9133                if (r.changeWindowTranslucency(false)) {
9134                    r.task.stack.convertToTranslucent(r);
9135                    mWindowManager.setAppFullscreen(token, false);
9136                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9137                    return true;
9138                }
9139                return false;
9140            }
9141        } finally {
9142            Binder.restoreCallingIdentity(origId);
9143        }
9144    }
9145
9146    @Override
9147    public void setImmersive(IBinder token, boolean immersive) {
9148        synchronized(this) {
9149            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9150            if (r == null) {
9151                throw new IllegalArgumentException();
9152            }
9153            r.immersive = immersive;
9154
9155            // update associated state if we're frontmost
9156            if (r == mFocusedActivity) {
9157                if (DEBUG_IMMERSIVE) {
9158                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9159                }
9160                applyUpdateLockStateLocked(r);
9161            }
9162        }
9163    }
9164
9165    @Override
9166    public boolean isImmersive(IBinder token) {
9167        synchronized (this) {
9168            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9169            if (r == null) {
9170                throw new IllegalArgumentException();
9171            }
9172            return r.immersive;
9173        }
9174    }
9175
9176    public boolean isTopActivityImmersive() {
9177        enforceNotIsolatedCaller("startActivity");
9178        synchronized (this) {
9179            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9180            return (r != null) ? r.immersive : false;
9181        }
9182    }
9183
9184    public final void enterSafeMode() {
9185        synchronized(this) {
9186            // It only makes sense to do this before the system is ready
9187            // and started launching other packages.
9188            if (!mSystemReady) {
9189                try {
9190                    AppGlobals.getPackageManager().enterSafeMode();
9191                } catch (RemoteException e) {
9192                }
9193            }
9194
9195            mSafeMode = true;
9196        }
9197    }
9198
9199    public final void showSafeModeOverlay() {
9200        View v = LayoutInflater.from(mContext).inflate(
9201                com.android.internal.R.layout.safe_mode, null);
9202        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9203        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9204        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9205        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9206        lp.gravity = Gravity.BOTTOM | Gravity.START;
9207        lp.format = v.getBackground().getOpacity();
9208        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9209                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9210        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9211        ((WindowManager)mContext.getSystemService(
9212                Context.WINDOW_SERVICE)).addView(v, lp);
9213    }
9214
9215    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9216        if (!(sender instanceof PendingIntentRecord)) {
9217            return;
9218        }
9219        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9220        synchronized (stats) {
9221            if (mBatteryStatsService.isOnBattery()) {
9222                mBatteryStatsService.enforceCallingPermission();
9223                PendingIntentRecord rec = (PendingIntentRecord)sender;
9224                int MY_UID = Binder.getCallingUid();
9225                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9226                BatteryStatsImpl.Uid.Pkg pkg =
9227                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9228                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9229                pkg.incWakeupsLocked();
9230            }
9231        }
9232    }
9233
9234    public boolean killPids(int[] pids, String pReason, boolean secure) {
9235        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9236            throw new SecurityException("killPids only available to the system");
9237        }
9238        String reason = (pReason == null) ? "Unknown" : pReason;
9239        // XXX Note: don't acquire main activity lock here, because the window
9240        // manager calls in with its locks held.
9241
9242        boolean killed = false;
9243        synchronized (mPidsSelfLocked) {
9244            int[] types = new int[pids.length];
9245            int worstType = 0;
9246            for (int i=0; i<pids.length; i++) {
9247                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9248                if (proc != null) {
9249                    int type = proc.setAdj;
9250                    types[i] = type;
9251                    if (type > worstType) {
9252                        worstType = type;
9253                    }
9254                }
9255            }
9256
9257            // If the worst oom_adj is somewhere in the cached proc LRU range,
9258            // then constrain it so we will kill all cached procs.
9259            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9260                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9261                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9262            }
9263
9264            // If this is not a secure call, don't let it kill processes that
9265            // are important.
9266            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9267                worstType = ProcessList.SERVICE_ADJ;
9268            }
9269
9270            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9271            for (int i=0; i<pids.length; i++) {
9272                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9273                if (proc == null) {
9274                    continue;
9275                }
9276                int adj = proc.setAdj;
9277                if (adj >= worstType && !proc.killedByAm) {
9278                    killUnneededProcessLocked(proc, reason);
9279                    killed = true;
9280                }
9281            }
9282        }
9283        return killed;
9284    }
9285
9286    @Override
9287    public void killUid(int uid, String reason) {
9288        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9289            throw new SecurityException("killUid only available to the system");
9290        }
9291        synchronized (this) {
9292            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9293                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9294                    reason != null ? reason : "kill uid");
9295        }
9296    }
9297
9298    @Override
9299    public boolean killProcessesBelowForeground(String reason) {
9300        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9301            throw new SecurityException("killProcessesBelowForeground() only available to system");
9302        }
9303
9304        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9305    }
9306
9307    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9308        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9309            throw new SecurityException("killProcessesBelowAdj() only available to system");
9310        }
9311
9312        boolean killed = false;
9313        synchronized (mPidsSelfLocked) {
9314            final int size = mPidsSelfLocked.size();
9315            for (int i = 0; i < size; i++) {
9316                final int pid = mPidsSelfLocked.keyAt(i);
9317                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9318                if (proc == null) continue;
9319
9320                final int adj = proc.setAdj;
9321                if (adj > belowAdj && !proc.killedByAm) {
9322                    killUnneededProcessLocked(proc, reason);
9323                    killed = true;
9324                }
9325            }
9326        }
9327        return killed;
9328    }
9329
9330    @Override
9331    public void hang(final IBinder who, boolean allowRestart) {
9332        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9333                != PackageManager.PERMISSION_GRANTED) {
9334            throw new SecurityException("Requires permission "
9335                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9336        }
9337
9338        final IBinder.DeathRecipient death = new DeathRecipient() {
9339            @Override
9340            public void binderDied() {
9341                synchronized (this) {
9342                    notifyAll();
9343                }
9344            }
9345        };
9346
9347        try {
9348            who.linkToDeath(death, 0);
9349        } catch (RemoteException e) {
9350            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9351            return;
9352        }
9353
9354        synchronized (this) {
9355            Watchdog.getInstance().setAllowRestart(allowRestart);
9356            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9357            synchronized (death) {
9358                while (who.isBinderAlive()) {
9359                    try {
9360                        death.wait();
9361                    } catch (InterruptedException e) {
9362                    }
9363                }
9364            }
9365            Watchdog.getInstance().setAllowRestart(true);
9366        }
9367    }
9368
9369    @Override
9370    public void restart() {
9371        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9372                != PackageManager.PERMISSION_GRANTED) {
9373            throw new SecurityException("Requires permission "
9374                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9375        }
9376
9377        Log.i(TAG, "Sending shutdown broadcast...");
9378
9379        BroadcastReceiver br = new BroadcastReceiver() {
9380            @Override public void onReceive(Context context, Intent intent) {
9381                // Now the broadcast is done, finish up the low-level shutdown.
9382                Log.i(TAG, "Shutting down activity manager...");
9383                shutdown(10000);
9384                Log.i(TAG, "Shutdown complete, restarting!");
9385                Process.killProcess(Process.myPid());
9386                System.exit(10);
9387            }
9388        };
9389
9390        // First send the high-level shut down broadcast.
9391        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9392        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9393        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9394        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9395        mContext.sendOrderedBroadcastAsUser(intent,
9396                UserHandle.ALL, null, br, mHandler, 0, null, null);
9397        */
9398        br.onReceive(mContext, intent);
9399    }
9400
9401    private long getLowRamTimeSinceIdle(long now) {
9402        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9403    }
9404
9405    @Override
9406    public void performIdleMaintenance() {
9407        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9408                != PackageManager.PERMISSION_GRANTED) {
9409            throw new SecurityException("Requires permission "
9410                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9411        }
9412
9413        synchronized (this) {
9414            final long now = SystemClock.uptimeMillis();
9415            final long timeSinceLastIdle = now - mLastIdleTime;
9416            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9417            mLastIdleTime = now;
9418            mLowRamTimeSinceLastIdle = 0;
9419            if (mLowRamStartTime != 0) {
9420                mLowRamStartTime = now;
9421            }
9422
9423            StringBuilder sb = new StringBuilder(128);
9424            sb.append("Idle maintenance over ");
9425            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9426            sb.append(" low RAM for ");
9427            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9428            Slog.i(TAG, sb.toString());
9429
9430            // If at least 1/3 of our time since the last idle period has been spent
9431            // with RAM low, then we want to kill processes.
9432            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9433
9434            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9435                ProcessRecord proc = mLruProcesses.get(i);
9436                if (proc.notCachedSinceIdle) {
9437                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9438                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9439                        if (doKilling && proc.initialIdlePss != 0
9440                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9441                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9442                                    + " from " + proc.initialIdlePss + ")");
9443                        }
9444                    }
9445                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9446                    proc.notCachedSinceIdle = true;
9447                    proc.initialIdlePss = 0;
9448                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9449                            isSleeping(), now);
9450                }
9451            }
9452
9453            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9454            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9455        }
9456    }
9457
9458    private void retrieveSettings() {
9459        final ContentResolver resolver = mContext.getContentResolver();
9460        String debugApp = Settings.Global.getString(
9461            resolver, Settings.Global.DEBUG_APP);
9462        boolean waitForDebugger = Settings.Global.getInt(
9463            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9464        boolean alwaysFinishActivities = Settings.Global.getInt(
9465            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9466        boolean forceRtl = Settings.Global.getInt(
9467                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9468        // Transfer any global setting for forcing RTL layout, into a System Property
9469        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9470
9471        Configuration configuration = new Configuration();
9472        Settings.System.getConfiguration(resolver, configuration);
9473        if (forceRtl) {
9474            // This will take care of setting the correct layout direction flags
9475            configuration.setLayoutDirection(configuration.locale);
9476        }
9477
9478        synchronized (this) {
9479            mDebugApp = mOrigDebugApp = debugApp;
9480            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9481            mAlwaysFinishActivities = alwaysFinishActivities;
9482            // This happens before any activities are started, so we can
9483            // change mConfiguration in-place.
9484            updateConfigurationLocked(configuration, null, false, true);
9485            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9486        }
9487    }
9488
9489    public boolean testIsSystemReady() {
9490        // no need to synchronize(this) just to read & return the value
9491        return mSystemReady;
9492    }
9493
9494    private static File getCalledPreBootReceiversFile() {
9495        File dataDir = Environment.getDataDirectory();
9496        File systemDir = new File(dataDir, "system");
9497        File fname = new File(systemDir, "called_pre_boots.dat");
9498        return fname;
9499    }
9500
9501    static final int LAST_DONE_VERSION = 10000;
9502
9503    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9504        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9505        File file = getCalledPreBootReceiversFile();
9506        FileInputStream fis = null;
9507        try {
9508            fis = new FileInputStream(file);
9509            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9510            int fvers = dis.readInt();
9511            if (fvers == LAST_DONE_VERSION) {
9512                String vers = dis.readUTF();
9513                String codename = dis.readUTF();
9514                String build = dis.readUTF();
9515                if (android.os.Build.VERSION.RELEASE.equals(vers)
9516                        && android.os.Build.VERSION.CODENAME.equals(codename)
9517                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9518                    int num = dis.readInt();
9519                    while (num > 0) {
9520                        num--;
9521                        String pkg = dis.readUTF();
9522                        String cls = dis.readUTF();
9523                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9524                    }
9525                }
9526            }
9527        } catch (FileNotFoundException e) {
9528        } catch (IOException e) {
9529            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9530        } finally {
9531            if (fis != null) {
9532                try {
9533                    fis.close();
9534                } catch (IOException e) {
9535                }
9536            }
9537        }
9538        return lastDoneReceivers;
9539    }
9540
9541    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9542        File file = getCalledPreBootReceiversFile();
9543        FileOutputStream fos = null;
9544        DataOutputStream dos = null;
9545        try {
9546            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9547            fos = new FileOutputStream(file);
9548            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9549            dos.writeInt(LAST_DONE_VERSION);
9550            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9551            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9552            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9553            dos.writeInt(list.size());
9554            for (int i=0; i<list.size(); i++) {
9555                dos.writeUTF(list.get(i).getPackageName());
9556                dos.writeUTF(list.get(i).getClassName());
9557            }
9558        } catch (IOException e) {
9559            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9560            file.delete();
9561        } finally {
9562            FileUtils.sync(fos);
9563            if (dos != null) {
9564                try {
9565                    dos.close();
9566                } catch (IOException e) {
9567                    // TODO Auto-generated catch block
9568                    e.printStackTrace();
9569                }
9570            }
9571        }
9572    }
9573
9574    public void systemReady(final Runnable goingCallback) {
9575        synchronized(this) {
9576            if (mSystemReady) {
9577                if (goingCallback != null) goingCallback.run();
9578                return;
9579            }
9580
9581            // Check to see if there are any update receivers to run.
9582            if (!mDidUpdate) {
9583                if (mWaitingUpdate) {
9584                    return;
9585                }
9586                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9587                List<ResolveInfo> ris = null;
9588                try {
9589                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9590                            intent, null, 0, 0);
9591                } catch (RemoteException e) {
9592                }
9593                if (ris != null) {
9594                    for (int i=ris.size()-1; i>=0; i--) {
9595                        if ((ris.get(i).activityInfo.applicationInfo.flags
9596                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9597                            ris.remove(i);
9598                        }
9599                    }
9600                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9601
9602                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9603
9604                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9605                    for (int i=0; i<ris.size(); i++) {
9606                        ActivityInfo ai = ris.get(i).activityInfo;
9607                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9608                        if (lastDoneReceivers.contains(comp)) {
9609                            // We already did the pre boot receiver for this app with the current
9610                            // platform version, so don't do it again...
9611                            ris.remove(i);
9612                            i--;
9613                            // ...however, do keep it as one that has been done, so we don't
9614                            // forget about it when rewriting the file of last done receivers.
9615                            doneReceivers.add(comp);
9616                        }
9617                    }
9618
9619                    final int[] users = getUsersLocked();
9620                    for (int i=0; i<ris.size(); i++) {
9621                        ActivityInfo ai = ris.get(i).activityInfo;
9622                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9623                        doneReceivers.add(comp);
9624                        intent.setComponent(comp);
9625                        for (int j=0; j<users.length; j++) {
9626                            IIntentReceiver finisher = null;
9627                            if (i == ris.size()-1 && j == users.length-1) {
9628                                finisher = new IIntentReceiver.Stub() {
9629                                    public void performReceive(Intent intent, int resultCode,
9630                                            String data, Bundle extras, boolean ordered,
9631                                            boolean sticky, int sendingUser) {
9632                                        // The raw IIntentReceiver interface is called
9633                                        // with the AM lock held, so redispatch to
9634                                        // execute our code without the lock.
9635                                        mHandler.post(new Runnable() {
9636                                            public void run() {
9637                                                synchronized (ActivityManagerService.this) {
9638                                                    mDidUpdate = true;
9639                                                }
9640                                                writeLastDonePreBootReceivers(doneReceivers);
9641                                                showBootMessage(mContext.getText(
9642                                                        R.string.android_upgrading_complete),
9643                                                        false);
9644                                                systemReady(goingCallback);
9645                                            }
9646                                        });
9647                                    }
9648                                };
9649                            }
9650                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9651                                    + " for user " + users[j]);
9652                            broadcastIntentLocked(null, null, intent, null, finisher,
9653                                    0, null, null, null, AppOpsManager.OP_NONE,
9654                                    true, false, MY_PID, Process.SYSTEM_UID,
9655                                    users[j]);
9656                            if (finisher != null) {
9657                                mWaitingUpdate = true;
9658                            }
9659                        }
9660                    }
9661                }
9662                if (mWaitingUpdate) {
9663                    return;
9664                }
9665                mDidUpdate = true;
9666            }
9667
9668            mAppOpsService.systemReady();
9669            mSystemReady = true;
9670        }
9671
9672        ArrayList<ProcessRecord> procsToKill = null;
9673        synchronized(mPidsSelfLocked) {
9674            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9675                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9676                if (!isAllowedWhileBooting(proc.info)){
9677                    if (procsToKill == null) {
9678                        procsToKill = new ArrayList<ProcessRecord>();
9679                    }
9680                    procsToKill.add(proc);
9681                }
9682            }
9683        }
9684
9685        synchronized(this) {
9686            if (procsToKill != null) {
9687                for (int i=procsToKill.size()-1; i>=0; i--) {
9688                    ProcessRecord proc = procsToKill.get(i);
9689                    Slog.i(TAG, "Removing system update proc: " + proc);
9690                    removeProcessLocked(proc, true, false, "system update done");
9691                }
9692            }
9693
9694            // Now that we have cleaned up any update processes, we
9695            // are ready to start launching real processes and know that
9696            // we won't trample on them any more.
9697            mProcessesReady = true;
9698        }
9699
9700        Slog.i(TAG, "System now ready");
9701        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9702            SystemClock.uptimeMillis());
9703
9704        synchronized(this) {
9705            // Make sure we have no pre-ready processes sitting around.
9706
9707            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9708                ResolveInfo ri = mContext.getPackageManager()
9709                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9710                                STOCK_PM_FLAGS);
9711                CharSequence errorMsg = null;
9712                if (ri != null) {
9713                    ActivityInfo ai = ri.activityInfo;
9714                    ApplicationInfo app = ai.applicationInfo;
9715                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9716                        mTopAction = Intent.ACTION_FACTORY_TEST;
9717                        mTopData = null;
9718                        mTopComponent = new ComponentName(app.packageName,
9719                                ai.name);
9720                    } else {
9721                        errorMsg = mContext.getResources().getText(
9722                                com.android.internal.R.string.factorytest_not_system);
9723                    }
9724                } else {
9725                    errorMsg = mContext.getResources().getText(
9726                            com.android.internal.R.string.factorytest_no_action);
9727                }
9728                if (errorMsg != null) {
9729                    mTopAction = null;
9730                    mTopData = null;
9731                    mTopComponent = null;
9732                    Message msg = Message.obtain();
9733                    msg.what = SHOW_FACTORY_ERROR_MSG;
9734                    msg.getData().putCharSequence("msg", errorMsg);
9735                    mHandler.sendMessage(msg);
9736                }
9737            }
9738        }
9739
9740        retrieveSettings();
9741
9742        synchronized (this) {
9743            readGrantedUriPermissionsLocked();
9744        }
9745
9746        if (goingCallback != null) goingCallback.run();
9747
9748        mSystemServiceManager.startUser(mCurrentUserId);
9749
9750        synchronized (this) {
9751            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9752                try {
9753                    List apps = AppGlobals.getPackageManager().
9754                        getPersistentApplications(STOCK_PM_FLAGS);
9755                    if (apps != null) {
9756                        int N = apps.size();
9757                        int i;
9758                        for (i=0; i<N; i++) {
9759                            ApplicationInfo info
9760                                = (ApplicationInfo)apps.get(i);
9761                            if (info != null &&
9762                                    !info.packageName.equals("android")) {
9763                                addAppLocked(info, false);
9764                            }
9765                        }
9766                    }
9767                } catch (RemoteException ex) {
9768                    // pm is in same process, this will never happen.
9769                }
9770            }
9771
9772            // Start up initial activity.
9773            mBooting = true;
9774
9775            try {
9776                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9777                    Message msg = Message.obtain();
9778                    msg.what = SHOW_UID_ERROR_MSG;
9779                    mHandler.sendMessage(msg);
9780                }
9781            } catch (RemoteException e) {
9782            }
9783
9784            long ident = Binder.clearCallingIdentity();
9785            try {
9786                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9787                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9788                        | Intent.FLAG_RECEIVER_FOREGROUND);
9789                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9790                broadcastIntentLocked(null, null, intent,
9791                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9792                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9793                intent = new Intent(Intent.ACTION_USER_STARTING);
9794                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9795                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9796                broadcastIntentLocked(null, null, intent,
9797                        null, new IIntentReceiver.Stub() {
9798                            @Override
9799                            public void performReceive(Intent intent, int resultCode, String data,
9800                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9801                                    throws RemoteException {
9802                            }
9803                        }, 0, null, null,
9804                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9805                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9806            } catch (Throwable t) {
9807                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9808            } finally {
9809                Binder.restoreCallingIdentity(ident);
9810            }
9811            mStackSupervisor.resumeTopActivitiesLocked();
9812            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9813        }
9814    }
9815
9816    private boolean makeAppCrashingLocked(ProcessRecord app,
9817            String shortMsg, String longMsg, String stackTrace) {
9818        app.crashing = true;
9819        app.crashingReport = generateProcessError(app,
9820                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9821        startAppProblemLocked(app);
9822        app.stopFreezingAllLocked();
9823        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9824    }
9825
9826    private void makeAppNotRespondingLocked(ProcessRecord app,
9827            String activity, String shortMsg, String longMsg) {
9828        app.notResponding = true;
9829        app.notRespondingReport = generateProcessError(app,
9830                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9831                activity, shortMsg, longMsg, null);
9832        startAppProblemLocked(app);
9833        app.stopFreezingAllLocked();
9834    }
9835
9836    /**
9837     * Generate a process error record, suitable for attachment to a ProcessRecord.
9838     *
9839     * @param app The ProcessRecord in which the error occurred.
9840     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9841     *                      ActivityManager.AppErrorStateInfo
9842     * @param activity The activity associated with the crash, if known.
9843     * @param shortMsg Short message describing the crash.
9844     * @param longMsg Long message describing the crash.
9845     * @param stackTrace Full crash stack trace, may be null.
9846     *
9847     * @return Returns a fully-formed AppErrorStateInfo record.
9848     */
9849    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9850            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9851        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9852
9853        report.condition = condition;
9854        report.processName = app.processName;
9855        report.pid = app.pid;
9856        report.uid = app.info.uid;
9857        report.tag = activity;
9858        report.shortMsg = shortMsg;
9859        report.longMsg = longMsg;
9860        report.stackTrace = stackTrace;
9861
9862        return report;
9863    }
9864
9865    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9866        synchronized (this) {
9867            app.crashing = false;
9868            app.crashingReport = null;
9869            app.notResponding = false;
9870            app.notRespondingReport = null;
9871            if (app.anrDialog == fromDialog) {
9872                app.anrDialog = null;
9873            }
9874            if (app.waitDialog == fromDialog) {
9875                app.waitDialog = null;
9876            }
9877            if (app.pid > 0 && app.pid != MY_PID) {
9878                handleAppCrashLocked(app, null, null, null);
9879                killUnneededProcessLocked(app, "user request after error");
9880            }
9881        }
9882    }
9883
9884    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9885            String stackTrace) {
9886        long now = SystemClock.uptimeMillis();
9887
9888        Long crashTime;
9889        if (!app.isolated) {
9890            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9891        } else {
9892            crashTime = null;
9893        }
9894        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9895            // This process loses!
9896            Slog.w(TAG, "Process " + app.info.processName
9897                    + " has crashed too many times: killing!");
9898            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9899                    app.userId, app.info.processName, app.uid);
9900            mStackSupervisor.handleAppCrashLocked(app);
9901            if (!app.persistent) {
9902                // We don't want to start this process again until the user
9903                // explicitly does so...  but for persistent process, we really
9904                // need to keep it running.  If a persistent process is actually
9905                // repeatedly crashing, then badness for everyone.
9906                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9907                        app.info.processName);
9908                if (!app.isolated) {
9909                    // XXX We don't have a way to mark isolated processes
9910                    // as bad, since they don't have a peristent identity.
9911                    mBadProcesses.put(app.info.processName, app.uid,
9912                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9913                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9914                }
9915                app.bad = true;
9916                app.removed = true;
9917                // Don't let services in this process be restarted and potentially
9918                // annoy the user repeatedly.  Unless it is persistent, since those
9919                // processes run critical code.
9920                removeProcessLocked(app, false, false, "crash");
9921                mStackSupervisor.resumeTopActivitiesLocked();
9922                return false;
9923            }
9924            mStackSupervisor.resumeTopActivitiesLocked();
9925        } else {
9926            mStackSupervisor.finishTopRunningActivityLocked(app);
9927        }
9928
9929        // Bump up the crash count of any services currently running in the proc.
9930        for (int i=app.services.size()-1; i>=0; i--) {
9931            // Any services running in the application need to be placed
9932            // back in the pending list.
9933            ServiceRecord sr = app.services.valueAt(i);
9934            sr.crashCount++;
9935        }
9936
9937        // If the crashing process is what we consider to be the "home process" and it has been
9938        // replaced by a third-party app, clear the package preferred activities from packages
9939        // with a home activity running in the process to prevent a repeatedly crashing app
9940        // from blocking the user to manually clear the list.
9941        final ArrayList<ActivityRecord> activities = app.activities;
9942        if (app == mHomeProcess && activities.size() > 0
9943                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9944            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9945                final ActivityRecord r = activities.get(activityNdx);
9946                if (r.isHomeActivity()) {
9947                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9948                    try {
9949                        ActivityThread.getPackageManager()
9950                                .clearPackagePreferredActivities(r.packageName);
9951                    } catch (RemoteException c) {
9952                        // pm is in same process, this will never happen.
9953                    }
9954                }
9955            }
9956        }
9957
9958        if (!app.isolated) {
9959            // XXX Can't keep track of crash times for isolated processes,
9960            // because they don't have a perisistent identity.
9961            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9962        }
9963
9964        return true;
9965    }
9966
9967    void startAppProblemLocked(ProcessRecord app) {
9968        if (app.userId == mCurrentUserId) {
9969            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9970                    mContext, app.info.packageName, app.info.flags);
9971        } else {
9972            // If this app is not running under the current user, then we
9973            // can't give it a report button because that would require
9974            // launching the report UI under a different user.
9975            app.errorReportReceiver = null;
9976        }
9977        skipCurrentReceiverLocked(app);
9978    }
9979
9980    void skipCurrentReceiverLocked(ProcessRecord app) {
9981        for (BroadcastQueue queue : mBroadcastQueues) {
9982            queue.skipCurrentReceiverLocked(app);
9983        }
9984    }
9985
9986    /**
9987     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9988     * The application process will exit immediately after this call returns.
9989     * @param app object of the crashing app, null for the system server
9990     * @param crashInfo describing the exception
9991     */
9992    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9993        ProcessRecord r = findAppProcess(app, "Crash");
9994        final String processName = app == null ? "system_server"
9995                : (r == null ? "unknown" : r.processName);
9996
9997        handleApplicationCrashInner("crash", r, processName, crashInfo);
9998    }
9999
10000    /* Native crash reporting uses this inner version because it needs to be somewhat
10001     * decoupled from the AM-managed cleanup lifecycle
10002     */
10003    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10004            ApplicationErrorReport.CrashInfo crashInfo) {
10005        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10006                UserHandle.getUserId(Binder.getCallingUid()), processName,
10007                r == null ? -1 : r.info.flags,
10008                crashInfo.exceptionClassName,
10009                crashInfo.exceptionMessage,
10010                crashInfo.throwFileName,
10011                crashInfo.throwLineNumber);
10012
10013        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10014
10015        crashApplication(r, crashInfo);
10016    }
10017
10018    public void handleApplicationStrictModeViolation(
10019            IBinder app,
10020            int violationMask,
10021            StrictMode.ViolationInfo info) {
10022        ProcessRecord r = findAppProcess(app, "StrictMode");
10023        if (r == null) {
10024            return;
10025        }
10026
10027        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10028            Integer stackFingerprint = info.hashCode();
10029            boolean logIt = true;
10030            synchronized (mAlreadyLoggedViolatedStacks) {
10031                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10032                    logIt = false;
10033                    // TODO: sub-sample into EventLog for these, with
10034                    // the info.durationMillis?  Then we'd get
10035                    // the relative pain numbers, without logging all
10036                    // the stack traces repeatedly.  We'd want to do
10037                    // likewise in the client code, which also does
10038                    // dup suppression, before the Binder call.
10039                } else {
10040                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10041                        mAlreadyLoggedViolatedStacks.clear();
10042                    }
10043                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10044                }
10045            }
10046            if (logIt) {
10047                logStrictModeViolationToDropBox(r, info);
10048            }
10049        }
10050
10051        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10052            AppErrorResult result = new AppErrorResult();
10053            synchronized (this) {
10054                final long origId = Binder.clearCallingIdentity();
10055
10056                Message msg = Message.obtain();
10057                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10058                HashMap<String, Object> data = new HashMap<String, Object>();
10059                data.put("result", result);
10060                data.put("app", r);
10061                data.put("violationMask", violationMask);
10062                data.put("info", info);
10063                msg.obj = data;
10064                mHandler.sendMessage(msg);
10065
10066                Binder.restoreCallingIdentity(origId);
10067            }
10068            int res = result.get();
10069            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10070        }
10071    }
10072
10073    // Depending on the policy in effect, there could be a bunch of
10074    // these in quick succession so we try to batch these together to
10075    // minimize disk writes, number of dropbox entries, and maximize
10076    // compression, by having more fewer, larger records.
10077    private void logStrictModeViolationToDropBox(
10078            ProcessRecord process,
10079            StrictMode.ViolationInfo info) {
10080        if (info == null) {
10081            return;
10082        }
10083        final boolean isSystemApp = process == null ||
10084                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10085                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10086        final String processName = process == null ? "unknown" : process.processName;
10087        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10088        final DropBoxManager dbox = (DropBoxManager)
10089                mContext.getSystemService(Context.DROPBOX_SERVICE);
10090
10091        // Exit early if the dropbox isn't configured to accept this report type.
10092        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10093
10094        boolean bufferWasEmpty;
10095        boolean needsFlush;
10096        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10097        synchronized (sb) {
10098            bufferWasEmpty = sb.length() == 0;
10099            appendDropBoxProcessHeaders(process, processName, sb);
10100            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10101            sb.append("System-App: ").append(isSystemApp).append("\n");
10102            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10103            if (info.violationNumThisLoop != 0) {
10104                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10105            }
10106            if (info.numAnimationsRunning != 0) {
10107                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10108            }
10109            if (info.broadcastIntentAction != null) {
10110                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10111            }
10112            if (info.durationMillis != -1) {
10113                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10114            }
10115            if (info.numInstances != -1) {
10116                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10117            }
10118            if (info.tags != null) {
10119                for (String tag : info.tags) {
10120                    sb.append("Span-Tag: ").append(tag).append("\n");
10121                }
10122            }
10123            sb.append("\n");
10124            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10125                sb.append(info.crashInfo.stackTrace);
10126            }
10127            sb.append("\n");
10128
10129            // Only buffer up to ~64k.  Various logging bits truncate
10130            // things at 128k.
10131            needsFlush = (sb.length() > 64 * 1024);
10132        }
10133
10134        // Flush immediately if the buffer's grown too large, or this
10135        // is a non-system app.  Non-system apps are isolated with a
10136        // different tag & policy and not batched.
10137        //
10138        // Batching is useful during internal testing with
10139        // StrictMode settings turned up high.  Without batching,
10140        // thousands of separate files could be created on boot.
10141        if (!isSystemApp || needsFlush) {
10142            new Thread("Error dump: " + dropboxTag) {
10143                @Override
10144                public void run() {
10145                    String report;
10146                    synchronized (sb) {
10147                        report = sb.toString();
10148                        sb.delete(0, sb.length());
10149                        sb.trimToSize();
10150                    }
10151                    if (report.length() != 0) {
10152                        dbox.addText(dropboxTag, report);
10153                    }
10154                }
10155            }.start();
10156            return;
10157        }
10158
10159        // System app batching:
10160        if (!bufferWasEmpty) {
10161            // An existing dropbox-writing thread is outstanding, so
10162            // we don't need to start it up.  The existing thread will
10163            // catch the buffer appends we just did.
10164            return;
10165        }
10166
10167        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10168        // (After this point, we shouldn't access AMS internal data structures.)
10169        new Thread("Error dump: " + dropboxTag) {
10170            @Override
10171            public void run() {
10172                // 5 second sleep to let stacks arrive and be batched together
10173                try {
10174                    Thread.sleep(5000);  // 5 seconds
10175                } catch (InterruptedException e) {}
10176
10177                String errorReport;
10178                synchronized (mStrictModeBuffer) {
10179                    errorReport = mStrictModeBuffer.toString();
10180                    if (errorReport.length() == 0) {
10181                        return;
10182                    }
10183                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10184                    mStrictModeBuffer.trimToSize();
10185                }
10186                dbox.addText(dropboxTag, errorReport);
10187            }
10188        }.start();
10189    }
10190
10191    /**
10192     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10193     * @param app object of the crashing app, null for the system server
10194     * @param tag reported by the caller
10195     * @param crashInfo describing the context of the error
10196     * @return true if the process should exit immediately (WTF is fatal)
10197     */
10198    public boolean handleApplicationWtf(IBinder app, String tag,
10199            ApplicationErrorReport.CrashInfo crashInfo) {
10200        ProcessRecord r = findAppProcess(app, "WTF");
10201        final String processName = app == null ? "system_server"
10202                : (r == null ? "unknown" : r.processName);
10203
10204        EventLog.writeEvent(EventLogTags.AM_WTF,
10205                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10206                processName,
10207                r == null ? -1 : r.info.flags,
10208                tag, crashInfo.exceptionMessage);
10209
10210        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10211
10212        if (r != null && r.pid != Process.myPid() &&
10213                Settings.Global.getInt(mContext.getContentResolver(),
10214                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10215            crashApplication(r, crashInfo);
10216            return true;
10217        } else {
10218            return false;
10219        }
10220    }
10221
10222    /**
10223     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10224     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10225     */
10226    private ProcessRecord findAppProcess(IBinder app, String reason) {
10227        if (app == null) {
10228            return null;
10229        }
10230
10231        synchronized (this) {
10232            final int NP = mProcessNames.getMap().size();
10233            for (int ip=0; ip<NP; ip++) {
10234                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10235                final int NA = apps.size();
10236                for (int ia=0; ia<NA; ia++) {
10237                    ProcessRecord p = apps.valueAt(ia);
10238                    if (p.thread != null && p.thread.asBinder() == app) {
10239                        return p;
10240                    }
10241                }
10242            }
10243
10244            Slog.w(TAG, "Can't find mystery application for " + reason
10245                    + " from pid=" + Binder.getCallingPid()
10246                    + " uid=" + Binder.getCallingUid() + ": " + app);
10247            return null;
10248        }
10249    }
10250
10251    /**
10252     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10253     * to append various headers to the dropbox log text.
10254     */
10255    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10256            StringBuilder sb) {
10257        // Watchdog thread ends up invoking this function (with
10258        // a null ProcessRecord) to add the stack file to dropbox.
10259        // Do not acquire a lock on this (am) in such cases, as it
10260        // could cause a potential deadlock, if and when watchdog
10261        // is invoked due to unavailability of lock on am and it
10262        // would prevent watchdog from killing system_server.
10263        if (process == null) {
10264            sb.append("Process: ").append(processName).append("\n");
10265            return;
10266        }
10267        // Note: ProcessRecord 'process' is guarded by the service
10268        // instance.  (notably process.pkgList, which could otherwise change
10269        // concurrently during execution of this method)
10270        synchronized (this) {
10271            sb.append("Process: ").append(processName).append("\n");
10272            int flags = process.info.flags;
10273            IPackageManager pm = AppGlobals.getPackageManager();
10274            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10275            for (int ip=0; ip<process.pkgList.size(); ip++) {
10276                String pkg = process.pkgList.keyAt(ip);
10277                sb.append("Package: ").append(pkg);
10278                try {
10279                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10280                    if (pi != null) {
10281                        sb.append(" v").append(pi.versionCode);
10282                        if (pi.versionName != null) {
10283                            sb.append(" (").append(pi.versionName).append(")");
10284                        }
10285                    }
10286                } catch (RemoteException e) {
10287                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10288                }
10289                sb.append("\n");
10290            }
10291        }
10292    }
10293
10294    private static String processClass(ProcessRecord process) {
10295        if (process == null || process.pid == MY_PID) {
10296            return "system_server";
10297        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10298            return "system_app";
10299        } else {
10300            return "data_app";
10301        }
10302    }
10303
10304    /**
10305     * Write a description of an error (crash, WTF, ANR) to the drop box.
10306     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10307     * @param process which caused the error, null means the system server
10308     * @param activity which triggered the error, null if unknown
10309     * @param parent activity related to the error, null if unknown
10310     * @param subject line related to the error, null if absent
10311     * @param report in long form describing the error, null if absent
10312     * @param logFile to include in the report, null if none
10313     * @param crashInfo giving an application stack trace, null if absent
10314     */
10315    public void addErrorToDropBox(String eventType,
10316            ProcessRecord process, String processName, ActivityRecord activity,
10317            ActivityRecord parent, String subject,
10318            final String report, final File logFile,
10319            final ApplicationErrorReport.CrashInfo crashInfo) {
10320        // NOTE -- this must never acquire the ActivityManagerService lock,
10321        // otherwise the watchdog may be prevented from resetting the system.
10322
10323        final String dropboxTag = processClass(process) + "_" + eventType;
10324        final DropBoxManager dbox = (DropBoxManager)
10325                mContext.getSystemService(Context.DROPBOX_SERVICE);
10326
10327        // Exit early if the dropbox isn't configured to accept this report type.
10328        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10329
10330        final StringBuilder sb = new StringBuilder(1024);
10331        appendDropBoxProcessHeaders(process, processName, sb);
10332        if (activity != null) {
10333            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10334        }
10335        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10336            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10337        }
10338        if (parent != null && parent != activity) {
10339            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10340        }
10341        if (subject != null) {
10342            sb.append("Subject: ").append(subject).append("\n");
10343        }
10344        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10345        if (Debug.isDebuggerConnected()) {
10346            sb.append("Debugger: Connected\n");
10347        }
10348        sb.append("\n");
10349
10350        // Do the rest in a worker thread to avoid blocking the caller on I/O
10351        // (After this point, we shouldn't access AMS internal data structures.)
10352        Thread worker = new Thread("Error dump: " + dropboxTag) {
10353            @Override
10354            public void run() {
10355                if (report != null) {
10356                    sb.append(report);
10357                }
10358                if (logFile != null) {
10359                    try {
10360                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10361                                    "\n\n[[TRUNCATED]]"));
10362                    } catch (IOException e) {
10363                        Slog.e(TAG, "Error reading " + logFile, e);
10364                    }
10365                }
10366                if (crashInfo != null && crashInfo.stackTrace != null) {
10367                    sb.append(crashInfo.stackTrace);
10368                }
10369
10370                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10371                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10372                if (lines > 0) {
10373                    sb.append("\n");
10374
10375                    // Merge several logcat streams, and take the last N lines
10376                    InputStreamReader input = null;
10377                    try {
10378                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10379                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10380                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10381
10382                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10383                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10384                        input = new InputStreamReader(logcat.getInputStream());
10385
10386                        int num;
10387                        char[] buf = new char[8192];
10388                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10389                    } catch (IOException e) {
10390                        Slog.e(TAG, "Error running logcat", e);
10391                    } finally {
10392                        if (input != null) try { input.close(); } catch (IOException e) {}
10393                    }
10394                }
10395
10396                dbox.addText(dropboxTag, sb.toString());
10397            }
10398        };
10399
10400        if (process == null) {
10401            // If process is null, we are being called from some internal code
10402            // and may be about to die -- run this synchronously.
10403            worker.run();
10404        } else {
10405            worker.start();
10406        }
10407    }
10408
10409    /**
10410     * Bring up the "unexpected error" dialog box for a crashing app.
10411     * Deal with edge cases (intercepts from instrumented applications,
10412     * ActivityController, error intent receivers, that sort of thing).
10413     * @param r the application crashing
10414     * @param crashInfo describing the failure
10415     */
10416    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10417        long timeMillis = System.currentTimeMillis();
10418        String shortMsg = crashInfo.exceptionClassName;
10419        String longMsg = crashInfo.exceptionMessage;
10420        String stackTrace = crashInfo.stackTrace;
10421        if (shortMsg != null && longMsg != null) {
10422            longMsg = shortMsg + ": " + longMsg;
10423        } else if (shortMsg != null) {
10424            longMsg = shortMsg;
10425        }
10426
10427        AppErrorResult result = new AppErrorResult();
10428        synchronized (this) {
10429            if (mController != null) {
10430                try {
10431                    String name = r != null ? r.processName : null;
10432                    int pid = r != null ? r.pid : Binder.getCallingPid();
10433                    if (!mController.appCrashed(name, pid,
10434                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10435                        Slog.w(TAG, "Force-killing crashed app " + name
10436                                + " at watcher's request");
10437                        Process.killProcess(pid);
10438                        return;
10439                    }
10440                } catch (RemoteException e) {
10441                    mController = null;
10442                    Watchdog.getInstance().setActivityController(null);
10443                }
10444            }
10445
10446            final long origId = Binder.clearCallingIdentity();
10447
10448            // If this process is running instrumentation, finish it.
10449            if (r != null && r.instrumentationClass != null) {
10450                Slog.w(TAG, "Error in app " + r.processName
10451                      + " running instrumentation " + r.instrumentationClass + ":");
10452                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10453                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10454                Bundle info = new Bundle();
10455                info.putString("shortMsg", shortMsg);
10456                info.putString("longMsg", longMsg);
10457                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10458                Binder.restoreCallingIdentity(origId);
10459                return;
10460            }
10461
10462            // If we can't identify the process or it's already exceeded its crash quota,
10463            // quit right away without showing a crash dialog.
10464            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10465                Binder.restoreCallingIdentity(origId);
10466                return;
10467            }
10468
10469            Message msg = Message.obtain();
10470            msg.what = SHOW_ERROR_MSG;
10471            HashMap data = new HashMap();
10472            data.put("result", result);
10473            data.put("app", r);
10474            msg.obj = data;
10475            mHandler.sendMessage(msg);
10476
10477            Binder.restoreCallingIdentity(origId);
10478        }
10479
10480        int res = result.get();
10481
10482        Intent appErrorIntent = null;
10483        synchronized (this) {
10484            if (r != null && !r.isolated) {
10485                // XXX Can't keep track of crash time for isolated processes,
10486                // since they don't have a persistent identity.
10487                mProcessCrashTimes.put(r.info.processName, r.uid,
10488                        SystemClock.uptimeMillis());
10489            }
10490            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10491                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10492            }
10493        }
10494
10495        if (appErrorIntent != null) {
10496            try {
10497                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10498            } catch (ActivityNotFoundException e) {
10499                Slog.w(TAG, "bug report receiver dissappeared", e);
10500            }
10501        }
10502    }
10503
10504    Intent createAppErrorIntentLocked(ProcessRecord r,
10505            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10506        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10507        if (report == null) {
10508            return null;
10509        }
10510        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10511        result.setComponent(r.errorReportReceiver);
10512        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10513        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10514        return result;
10515    }
10516
10517    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10518            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10519        if (r.errorReportReceiver == null) {
10520            return null;
10521        }
10522
10523        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10524            return null;
10525        }
10526
10527        ApplicationErrorReport report = new ApplicationErrorReport();
10528        report.packageName = r.info.packageName;
10529        report.installerPackageName = r.errorReportReceiver.getPackageName();
10530        report.processName = r.processName;
10531        report.time = timeMillis;
10532        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10533
10534        if (r.crashing || r.forceCrashReport) {
10535            report.type = ApplicationErrorReport.TYPE_CRASH;
10536            report.crashInfo = crashInfo;
10537        } else if (r.notResponding) {
10538            report.type = ApplicationErrorReport.TYPE_ANR;
10539            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10540
10541            report.anrInfo.activity = r.notRespondingReport.tag;
10542            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10543            report.anrInfo.info = r.notRespondingReport.longMsg;
10544        }
10545
10546        return report;
10547    }
10548
10549    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10550        enforceNotIsolatedCaller("getProcessesInErrorState");
10551        // assume our apps are happy - lazy create the list
10552        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10553
10554        final boolean allUsers = ActivityManager.checkUidPermission(
10555                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10556                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10557        int userId = UserHandle.getUserId(Binder.getCallingUid());
10558
10559        synchronized (this) {
10560
10561            // iterate across all processes
10562            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10563                ProcessRecord app = mLruProcesses.get(i);
10564                if (!allUsers && app.userId != userId) {
10565                    continue;
10566                }
10567                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10568                    // This one's in trouble, so we'll generate a report for it
10569                    // crashes are higher priority (in case there's a crash *and* an anr)
10570                    ActivityManager.ProcessErrorStateInfo report = null;
10571                    if (app.crashing) {
10572                        report = app.crashingReport;
10573                    } else if (app.notResponding) {
10574                        report = app.notRespondingReport;
10575                    }
10576
10577                    if (report != null) {
10578                        if (errList == null) {
10579                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10580                        }
10581                        errList.add(report);
10582                    } else {
10583                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10584                                " crashing = " + app.crashing +
10585                                " notResponding = " + app.notResponding);
10586                    }
10587                }
10588            }
10589        }
10590
10591        return errList;
10592    }
10593
10594    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10595        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10596            if (currApp != null) {
10597                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10598            }
10599            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10600        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10601            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10602        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10603            if (currApp != null) {
10604                currApp.lru = 0;
10605            }
10606            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10607        } else if (adj >= ProcessList.SERVICE_ADJ) {
10608            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10609        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10610            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10611        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10612            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10613        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10614            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10615        } else {
10616            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10617        }
10618    }
10619
10620    private void fillInProcMemInfo(ProcessRecord app,
10621            ActivityManager.RunningAppProcessInfo outInfo) {
10622        outInfo.pid = app.pid;
10623        outInfo.uid = app.info.uid;
10624        if (mHeavyWeightProcess == app) {
10625            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10626        }
10627        if (app.persistent) {
10628            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10629        }
10630        if (app.activities.size() > 0) {
10631            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10632        }
10633        outInfo.lastTrimLevel = app.trimMemoryLevel;
10634        int adj = app.curAdj;
10635        outInfo.importance = oomAdjToImportance(adj, outInfo);
10636        outInfo.importanceReasonCode = app.adjTypeCode;
10637        outInfo.processState = app.curProcState;
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 processes 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        app.foregroundActivities = foregroundActivities;
15312
15313        return app.curRawAdj;
15314    }
15315
15316    /**
15317     * Schedule PSS collection of a process.
15318     */
15319    void requestPssLocked(ProcessRecord proc, int procState) {
15320        if (mPendingPssProcesses.contains(proc)) {
15321            return;
15322        }
15323        if (mPendingPssProcesses.size() == 0) {
15324            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15325        }
15326        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15327        proc.pssProcState = procState;
15328        mPendingPssProcesses.add(proc);
15329    }
15330
15331    /**
15332     * Schedule PSS collection of all processes.
15333     */
15334    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15335        if (!always) {
15336            if (now < (mLastFullPssTime +
15337                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15338                return;
15339            }
15340        }
15341        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15342        mLastFullPssTime = now;
15343        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15344        mPendingPssProcesses.clear();
15345        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15346            ProcessRecord app = mLruProcesses.get(i);
15347            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15348                app.pssProcState = app.setProcState;
15349                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15350                        isSleeping(), now);
15351                mPendingPssProcesses.add(app);
15352            }
15353        }
15354        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15355    }
15356
15357    /**
15358     * Ask a given process to GC right now.
15359     */
15360    final void performAppGcLocked(ProcessRecord app) {
15361        try {
15362            app.lastRequestedGc = SystemClock.uptimeMillis();
15363            if (app.thread != null) {
15364                if (app.reportLowMemory) {
15365                    app.reportLowMemory = false;
15366                    app.thread.scheduleLowMemory();
15367                } else {
15368                    app.thread.processInBackground();
15369                }
15370            }
15371        } catch (Exception e) {
15372            // whatever.
15373        }
15374    }
15375
15376    /**
15377     * Returns true if things are idle enough to perform GCs.
15378     */
15379    private final boolean canGcNowLocked() {
15380        boolean processingBroadcasts = false;
15381        for (BroadcastQueue q : mBroadcastQueues) {
15382            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15383                processingBroadcasts = true;
15384            }
15385        }
15386        return !processingBroadcasts
15387                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15388    }
15389
15390    /**
15391     * Perform GCs on all processes that are waiting for it, but only
15392     * if things are idle.
15393     */
15394    final void performAppGcsLocked() {
15395        final int N = mProcessesToGc.size();
15396        if (N <= 0) {
15397            return;
15398        }
15399        if (canGcNowLocked()) {
15400            while (mProcessesToGc.size() > 0) {
15401                ProcessRecord proc = mProcessesToGc.remove(0);
15402                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15403                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15404                            <= SystemClock.uptimeMillis()) {
15405                        // To avoid spamming the system, we will GC processes one
15406                        // at a time, waiting a few seconds between each.
15407                        performAppGcLocked(proc);
15408                        scheduleAppGcsLocked();
15409                        return;
15410                    } else {
15411                        // It hasn't been long enough since we last GCed this
15412                        // process...  put it in the list to wait for its time.
15413                        addProcessToGcListLocked(proc);
15414                        break;
15415                    }
15416                }
15417            }
15418
15419            scheduleAppGcsLocked();
15420        }
15421    }
15422
15423    /**
15424     * If all looks good, perform GCs on all processes waiting for them.
15425     */
15426    final void performAppGcsIfAppropriateLocked() {
15427        if (canGcNowLocked()) {
15428            performAppGcsLocked();
15429            return;
15430        }
15431        // Still not idle, wait some more.
15432        scheduleAppGcsLocked();
15433    }
15434
15435    /**
15436     * Schedule the execution of all pending app GCs.
15437     */
15438    final void scheduleAppGcsLocked() {
15439        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15440
15441        if (mProcessesToGc.size() > 0) {
15442            // Schedule a GC for the time to the next process.
15443            ProcessRecord proc = mProcessesToGc.get(0);
15444            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15445
15446            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15447            long now = SystemClock.uptimeMillis();
15448            if (when < (now+GC_TIMEOUT)) {
15449                when = now + GC_TIMEOUT;
15450            }
15451            mHandler.sendMessageAtTime(msg, when);
15452        }
15453    }
15454
15455    /**
15456     * Add a process to the array of processes waiting to be GCed.  Keeps the
15457     * list in sorted order by the last GC time.  The process can't already be
15458     * on the list.
15459     */
15460    final void addProcessToGcListLocked(ProcessRecord proc) {
15461        boolean added = false;
15462        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15463            if (mProcessesToGc.get(i).lastRequestedGc <
15464                    proc.lastRequestedGc) {
15465                added = true;
15466                mProcessesToGc.add(i+1, proc);
15467                break;
15468            }
15469        }
15470        if (!added) {
15471            mProcessesToGc.add(0, proc);
15472        }
15473    }
15474
15475    /**
15476     * Set up to ask a process to GC itself.  This will either do it
15477     * immediately, or put it on the list of processes to gc the next
15478     * time things are idle.
15479     */
15480    final void scheduleAppGcLocked(ProcessRecord app) {
15481        long now = SystemClock.uptimeMillis();
15482        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15483            return;
15484        }
15485        if (!mProcessesToGc.contains(app)) {
15486            addProcessToGcListLocked(app);
15487            scheduleAppGcsLocked();
15488        }
15489    }
15490
15491    final void checkExcessivePowerUsageLocked(boolean doKills) {
15492        updateCpuStatsNow();
15493
15494        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15495        boolean doWakeKills = doKills;
15496        boolean doCpuKills = doKills;
15497        if (mLastPowerCheckRealtime == 0) {
15498            doWakeKills = false;
15499        }
15500        if (mLastPowerCheckUptime == 0) {
15501            doCpuKills = false;
15502        }
15503        if (stats.isScreenOn()) {
15504            doWakeKills = false;
15505        }
15506        final long curRealtime = SystemClock.elapsedRealtime();
15507        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15508        final long curUptime = SystemClock.uptimeMillis();
15509        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15510        mLastPowerCheckRealtime = curRealtime;
15511        mLastPowerCheckUptime = curUptime;
15512        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15513            doWakeKills = false;
15514        }
15515        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15516            doCpuKills = false;
15517        }
15518        int i = mLruProcesses.size();
15519        while (i > 0) {
15520            i--;
15521            ProcessRecord app = mLruProcesses.get(i);
15522            if (!app.keeping) {
15523                long wtime;
15524                synchronized (stats) {
15525                    wtime = stats.getProcessWakeTime(app.info.uid,
15526                            app.pid, curRealtime);
15527                }
15528                long wtimeUsed = wtime - app.lastWakeTime;
15529                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15530                if (DEBUG_POWER) {
15531                    StringBuilder sb = new StringBuilder(128);
15532                    sb.append("Wake for ");
15533                    app.toShortString(sb);
15534                    sb.append(": over ");
15535                    TimeUtils.formatDuration(realtimeSince, sb);
15536                    sb.append(" used ");
15537                    TimeUtils.formatDuration(wtimeUsed, sb);
15538                    sb.append(" (");
15539                    sb.append((wtimeUsed*100)/realtimeSince);
15540                    sb.append("%)");
15541                    Slog.i(TAG, sb.toString());
15542                    sb.setLength(0);
15543                    sb.append("CPU for ");
15544                    app.toShortString(sb);
15545                    sb.append(": over ");
15546                    TimeUtils.formatDuration(uptimeSince, sb);
15547                    sb.append(" used ");
15548                    TimeUtils.formatDuration(cputimeUsed, sb);
15549                    sb.append(" (");
15550                    sb.append((cputimeUsed*100)/uptimeSince);
15551                    sb.append("%)");
15552                    Slog.i(TAG, sb.toString());
15553                }
15554                // If a process has held a wake lock for more
15555                // than 50% of the time during this period,
15556                // that sounds bad.  Kill!
15557                if (doWakeKills && realtimeSince > 0
15558                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15559                    synchronized (stats) {
15560                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15561                                realtimeSince, wtimeUsed);
15562                    }
15563                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15564                            + " during " + realtimeSince);
15565                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15566                } else if (doCpuKills && uptimeSince > 0
15567                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15568                    synchronized (stats) {
15569                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15570                                uptimeSince, cputimeUsed);
15571                    }
15572                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15573                            + " during " + uptimeSince);
15574                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15575                } else {
15576                    app.lastWakeTime = wtime;
15577                    app.lastCpuTime = app.curCpuTime;
15578                }
15579            }
15580        }
15581    }
15582
15583    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15584            ProcessRecord TOP_APP, boolean doingAll, long now) {
15585        boolean success = true;
15586
15587        if (app.curRawAdj != app.setRawAdj) {
15588            if (wasKeeping && !app.keeping) {
15589                // This app is no longer something we want to keep.  Note
15590                // its current wake lock time to later know to kill it if
15591                // it is not behaving well.
15592                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15593                synchronized (stats) {
15594                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15595                            app.pid, SystemClock.elapsedRealtime());
15596                }
15597                app.lastCpuTime = app.curCpuTime;
15598            }
15599
15600            app.setRawAdj = app.curRawAdj;
15601        }
15602
15603        int changes = 0;
15604
15605        if (app.curAdj != app.setAdj) {
15606            ProcessList.setOomAdj(app.pid, app.curAdj);
15607            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15608                TAG, "Set " + app.pid + " " + app.processName +
15609                " adj " + app.curAdj + ": " + app.adjType);
15610            app.setAdj = app.curAdj;
15611        }
15612
15613        if (app.setSchedGroup != app.curSchedGroup) {
15614            app.setSchedGroup = app.curSchedGroup;
15615            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15616                    "Setting process group of " + app.processName
15617                    + " to " + app.curSchedGroup);
15618            if (app.waitingToKill != null &&
15619                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15620                killUnneededProcessLocked(app, app.waitingToKill);
15621                success = false;
15622            } else {
15623                if (true) {
15624                    long oldId = Binder.clearCallingIdentity();
15625                    try {
15626                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15627                    } catch (Exception e) {
15628                        Slog.w(TAG, "Failed setting process group of " + app.pid
15629                                + " to " + app.curSchedGroup);
15630                        e.printStackTrace();
15631                    } finally {
15632                        Binder.restoreCallingIdentity(oldId);
15633                    }
15634                } else {
15635                    if (app.thread != null) {
15636                        try {
15637                            app.thread.setSchedulingGroup(app.curSchedGroup);
15638                        } catch (RemoteException e) {
15639                        }
15640                    }
15641                }
15642                Process.setSwappiness(app.pid,
15643                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15644            }
15645        }
15646        if (app.repForegroundActivities != app.foregroundActivities) {
15647            app.repForegroundActivities = app.foregroundActivities;
15648            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15649        }
15650        if (app.repProcState != app.curProcState) {
15651            app.repProcState = app.curProcState;
15652            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15653            if (app.thread != null) {
15654                try {
15655                    if (false) {
15656                        //RuntimeException h = new RuntimeException("here");
15657                        Slog.i(TAG, "Sending new process state " + app.repProcState
15658                                + " to " + app /*, h*/);
15659                    }
15660                    app.thread.setProcessState(app.repProcState);
15661                } catch (RemoteException e) {
15662                }
15663            }
15664        }
15665        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15666                app.setProcState)) {
15667            app.lastStateTime = now;
15668            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15669                    isSleeping(), now);
15670            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15671                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15672                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15673                    + (app.nextPssTime-now) + ": " + app);
15674        } else {
15675            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15676                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15677                requestPssLocked(app, app.setProcState);
15678                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15679                        isSleeping(), now);
15680            } else if (false && DEBUG_PSS) {
15681                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15682            }
15683        }
15684        if (app.setProcState != app.curProcState) {
15685            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15686                    "Proc state change of " + app.processName
15687                    + " to " + app.curProcState);
15688            app.setProcState = app.curProcState;
15689            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15690                app.notCachedSinceIdle = false;
15691            }
15692            if (!doingAll) {
15693                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15694            } else {
15695                app.procStateChanged = true;
15696            }
15697        }
15698
15699        if (changes != 0) {
15700            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15701            int i = mPendingProcessChanges.size()-1;
15702            ProcessChangeItem item = null;
15703            while (i >= 0) {
15704                item = mPendingProcessChanges.get(i);
15705                if (item.pid == app.pid) {
15706                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15707                    break;
15708                }
15709                i--;
15710            }
15711            if (i < 0) {
15712                // No existing item in pending changes; need a new one.
15713                final int NA = mAvailProcessChanges.size();
15714                if (NA > 0) {
15715                    item = mAvailProcessChanges.remove(NA-1);
15716                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15717                } else {
15718                    item = new ProcessChangeItem();
15719                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15720                }
15721                item.changes = 0;
15722                item.pid = app.pid;
15723                item.uid = app.info.uid;
15724                if (mPendingProcessChanges.size() == 0) {
15725                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15726                            "*** Enqueueing dispatch processes changed!");
15727                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15728                }
15729                mPendingProcessChanges.add(item);
15730            }
15731            item.changes |= changes;
15732            item.processState = app.repProcState;
15733            item.foregroundActivities = app.repForegroundActivities;
15734            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15735                    + Integer.toHexString(System.identityHashCode(item))
15736                    + " " + app.toShortString() + ": changes=" + item.changes
15737                    + " procState=" + item.processState
15738                    + " foreground=" + item.foregroundActivities
15739                    + " type=" + app.adjType + " source=" + app.adjSource
15740                    + " target=" + app.adjTarget);
15741        }
15742
15743        return success;
15744    }
15745
15746    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15747        if (proc.thread != null && proc.baseProcessTracker != null) {
15748            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15749        }
15750    }
15751
15752    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15753            ProcessRecord TOP_APP, boolean doingAll, long now) {
15754        if (app.thread == null) {
15755            return false;
15756        }
15757
15758        final boolean wasKeeping = app.keeping;
15759
15760        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15761
15762        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15763    }
15764
15765    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15766            boolean oomAdj) {
15767        if (isForeground != proc.foregroundServices) {
15768            proc.foregroundServices = isForeground;
15769            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15770                    proc.info.uid);
15771            if (isForeground) {
15772                if (curProcs == null) {
15773                    curProcs = new ArrayList<ProcessRecord>();
15774                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15775                }
15776                if (!curProcs.contains(proc)) {
15777                    curProcs.add(proc);
15778                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15779                            proc.info.packageName, proc.info.uid);
15780                }
15781            } else {
15782                if (curProcs != null) {
15783                    if (curProcs.remove(proc)) {
15784                        mBatteryStatsService.noteEvent(
15785                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15786                                proc.info.packageName, proc.info.uid);
15787                        if (curProcs.size() <= 0) {
15788                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15789                        }
15790                    }
15791                }
15792            }
15793            if (oomAdj) {
15794                updateOomAdjLocked();
15795            }
15796        }
15797    }
15798
15799    private final ActivityRecord resumedAppLocked() {
15800        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15801        String pkg;
15802        int uid;
15803        if (act != null && !act.sleeping) {
15804            pkg = act.packageName;
15805            uid = act.info.applicationInfo.uid;
15806        } else {
15807            pkg = null;
15808            uid = -1;
15809        }
15810        // Has the UID or resumed package name changed?
15811        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15812                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15813            if (mCurResumedPackage != null) {
15814                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15815                        mCurResumedPackage, mCurResumedUid);
15816            }
15817            mCurResumedPackage = pkg;
15818            mCurResumedUid = uid;
15819            if (mCurResumedPackage != null) {
15820                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15821                        mCurResumedPackage, mCurResumedUid);
15822            }
15823        }
15824        return act;
15825    }
15826
15827    final boolean updateOomAdjLocked(ProcessRecord app) {
15828        final ActivityRecord TOP_ACT = resumedAppLocked();
15829        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15830        final boolean wasCached = app.cached;
15831
15832        mAdjSeq++;
15833
15834        // This is the desired cached adjusment we want to tell it to use.
15835        // If our app is currently cached, we know it, and that is it.  Otherwise,
15836        // we don't know it yet, and it needs to now be cached we will then
15837        // need to do a complete oom adj.
15838        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15839                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15840        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15841                SystemClock.uptimeMillis());
15842        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15843            // Changed to/from cached state, so apps after it in the LRU
15844            // list may also be changed.
15845            updateOomAdjLocked();
15846        }
15847        return success;
15848    }
15849
15850    final void updateOomAdjLocked() {
15851        final ActivityRecord TOP_ACT = resumedAppLocked();
15852        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15853        final long now = SystemClock.uptimeMillis();
15854        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15855        final int N = mLruProcesses.size();
15856
15857        if (false) {
15858            RuntimeException e = new RuntimeException();
15859            e.fillInStackTrace();
15860            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15861        }
15862
15863        mAdjSeq++;
15864        mNewNumServiceProcs = 0;
15865        mNewNumAServiceProcs = 0;
15866
15867        final int emptyProcessLimit;
15868        final int cachedProcessLimit;
15869        if (mProcessLimit <= 0) {
15870            emptyProcessLimit = cachedProcessLimit = 0;
15871        } else if (mProcessLimit == 1) {
15872            emptyProcessLimit = 1;
15873            cachedProcessLimit = 0;
15874        } else {
15875            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15876            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15877        }
15878
15879        // Let's determine how many processes we have running vs.
15880        // how many slots we have for background processes; we may want
15881        // to put multiple processes in a slot of there are enough of
15882        // them.
15883        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15884                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15885        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15886        if (numEmptyProcs > cachedProcessLimit) {
15887            // If there are more empty processes than our limit on cached
15888            // processes, then use the cached process limit for the factor.
15889            // This ensures that the really old empty processes get pushed
15890            // down to the bottom, so if we are running low on memory we will
15891            // have a better chance at keeping around more cached processes
15892            // instead of a gazillion empty processes.
15893            numEmptyProcs = cachedProcessLimit;
15894        }
15895        int emptyFactor = numEmptyProcs/numSlots;
15896        if (emptyFactor < 1) emptyFactor = 1;
15897        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15898        if (cachedFactor < 1) cachedFactor = 1;
15899        int stepCached = 0;
15900        int stepEmpty = 0;
15901        int numCached = 0;
15902        int numEmpty = 0;
15903        int numTrimming = 0;
15904
15905        mNumNonCachedProcs = 0;
15906        mNumCachedHiddenProcs = 0;
15907
15908        // First update the OOM adjustment for each of the
15909        // application processes based on their current state.
15910        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15911        int nextCachedAdj = curCachedAdj+1;
15912        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15913        int nextEmptyAdj = curEmptyAdj+2;
15914        for (int i=N-1; i>=0; i--) {
15915            ProcessRecord app = mLruProcesses.get(i);
15916            if (!app.killedByAm && app.thread != null) {
15917                app.procStateChanged = false;
15918                final boolean wasKeeping = app.keeping;
15919                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15920
15921                // If we haven't yet assigned the final cached adj
15922                // to the process, do that now.
15923                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15924                    switch (app.curProcState) {
15925                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15926                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15927                            // This process is a cached process holding activities...
15928                            // assign it the next cached value for that type, and then
15929                            // step that cached level.
15930                            app.curRawAdj = curCachedAdj;
15931                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15932                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15933                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15934                                    + ")");
15935                            if (curCachedAdj != nextCachedAdj) {
15936                                stepCached++;
15937                                if (stepCached >= cachedFactor) {
15938                                    stepCached = 0;
15939                                    curCachedAdj = nextCachedAdj;
15940                                    nextCachedAdj += 2;
15941                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15942                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15943                                    }
15944                                }
15945                            }
15946                            break;
15947                        default:
15948                            // For everything else, assign next empty cached process
15949                            // level and bump that up.  Note that this means that
15950                            // long-running services that have dropped down to the
15951                            // cached level will be treated as empty (since their process
15952                            // state is still as a service), which is what we want.
15953                            app.curRawAdj = curEmptyAdj;
15954                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15955                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15956                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15957                                    + ")");
15958                            if (curEmptyAdj != nextEmptyAdj) {
15959                                stepEmpty++;
15960                                if (stepEmpty >= emptyFactor) {
15961                                    stepEmpty = 0;
15962                                    curEmptyAdj = nextEmptyAdj;
15963                                    nextEmptyAdj += 2;
15964                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15965                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15966                                    }
15967                                }
15968                            }
15969                            break;
15970                    }
15971                }
15972
15973                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15974
15975                // Count the number of process types.
15976                switch (app.curProcState) {
15977                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15978                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15979                        mNumCachedHiddenProcs++;
15980                        numCached++;
15981                        if (numCached > cachedProcessLimit) {
15982                            killUnneededProcessLocked(app, "cached #" + numCached);
15983                        }
15984                        break;
15985                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15986                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15987                                && app.lastActivityTime < oldTime) {
15988                            killUnneededProcessLocked(app, "empty for "
15989                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15990                                    / 1000) + "s");
15991                        } else {
15992                            numEmpty++;
15993                            if (numEmpty > emptyProcessLimit) {
15994                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15995                            }
15996                        }
15997                        break;
15998                    default:
15999                        mNumNonCachedProcs++;
16000                        break;
16001                }
16002
16003                if (app.isolated && app.services.size() <= 0) {
16004                    // If this is an isolated process, and there are no
16005                    // services running in it, then the process is no longer
16006                    // needed.  We agressively kill these because we can by
16007                    // definition not re-use the same process again, and it is
16008                    // good to avoid having whatever code was running in them
16009                    // left sitting around after no longer needed.
16010                    killUnneededProcessLocked(app, "isolated not needed");
16011                }
16012
16013                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16014                        && !app.killedByAm) {
16015                    numTrimming++;
16016                }
16017            }
16018        }
16019
16020        mNumServiceProcs = mNewNumServiceProcs;
16021
16022        // Now determine the memory trimming level of background processes.
16023        // Unfortunately we need to start at the back of the list to do this
16024        // properly.  We only do this if the number of background apps we
16025        // are managing to keep around is less than half the maximum we desire;
16026        // if we are keeping a good number around, we'll let them use whatever
16027        // memory they want.
16028        final int numCachedAndEmpty = numCached + numEmpty;
16029        int memFactor;
16030        if (numCached <= ProcessList.TRIM_CACHED_APPS
16031                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16032            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16033                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16034            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16035                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16036            } else {
16037                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16038            }
16039        } else {
16040            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16041        }
16042        // We always allow the memory level to go up (better).  We only allow it to go
16043        // down if we are in a state where that is allowed, *and* the total number of processes
16044        // has gone down since last time.
16045        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16046                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16047                + " last=" + mLastNumProcesses);
16048        if (memFactor > mLastMemoryLevel) {
16049            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16050                memFactor = mLastMemoryLevel;
16051                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16052            }
16053        }
16054        mLastMemoryLevel = memFactor;
16055        mLastNumProcesses = mLruProcesses.size();
16056        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16057        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16058        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16059            if (mLowRamStartTime == 0) {
16060                mLowRamStartTime = now;
16061            }
16062            int step = 0;
16063            int fgTrimLevel;
16064            switch (memFactor) {
16065                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16066                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16067                    break;
16068                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16069                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16070                    break;
16071                default:
16072                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16073                    break;
16074            }
16075            int factor = numTrimming/3;
16076            int minFactor = 2;
16077            if (mHomeProcess != null) minFactor++;
16078            if (mPreviousProcess != null) minFactor++;
16079            if (factor < minFactor) factor = minFactor;
16080            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16081            for (int i=N-1; i>=0; i--) {
16082                ProcessRecord app = mLruProcesses.get(i);
16083                if (allChanged || app.procStateChanged) {
16084                    setProcessTrackerState(app, trackerMemFactor, now);
16085                    app.procStateChanged = false;
16086                }
16087                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16088                        && !app.killedByAm) {
16089                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16090                        try {
16091                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16092                                    "Trimming memory of " + app.processName
16093                                    + " to " + curLevel);
16094                            app.thread.scheduleTrimMemory(curLevel);
16095                        } catch (RemoteException e) {
16096                        }
16097                        if (false) {
16098                            // For now we won't do this; our memory trimming seems
16099                            // to be good enough at this point that destroying
16100                            // activities causes more harm than good.
16101                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16102                                    && app != mHomeProcess && app != mPreviousProcess) {
16103                                // Need to do this on its own message because the stack may not
16104                                // be in a consistent state at this point.
16105                                // For these apps we will also finish their activities
16106                                // to help them free memory.
16107                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16108                            }
16109                        }
16110                    }
16111                    app.trimMemoryLevel = curLevel;
16112                    step++;
16113                    if (step >= factor) {
16114                        step = 0;
16115                        switch (curLevel) {
16116                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16117                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16118                                break;
16119                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16120                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16121                                break;
16122                        }
16123                    }
16124                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16125                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16126                            && app.thread != null) {
16127                        try {
16128                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16129                                    "Trimming memory of heavy-weight " + app.processName
16130                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16131                            app.thread.scheduleTrimMemory(
16132                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16133                        } catch (RemoteException e) {
16134                        }
16135                    }
16136                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16137                } else {
16138                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16139                            || app.systemNoUi) && app.pendingUiClean) {
16140                        // If this application is now in the background and it
16141                        // had done UI, then give it the special trim level to
16142                        // have it free UI resources.
16143                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16144                        if (app.trimMemoryLevel < level && app.thread != null) {
16145                            try {
16146                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16147                                        "Trimming memory of bg-ui " + app.processName
16148                                        + " to " + level);
16149                                app.thread.scheduleTrimMemory(level);
16150                            } catch (RemoteException e) {
16151                            }
16152                        }
16153                        app.pendingUiClean = false;
16154                    }
16155                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16156                        try {
16157                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16158                                    "Trimming memory of fg " + app.processName
16159                                    + " to " + fgTrimLevel);
16160                            app.thread.scheduleTrimMemory(fgTrimLevel);
16161                        } catch (RemoteException e) {
16162                        }
16163                    }
16164                    app.trimMemoryLevel = fgTrimLevel;
16165                }
16166            }
16167        } else {
16168            if (mLowRamStartTime != 0) {
16169                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16170                mLowRamStartTime = 0;
16171            }
16172            for (int i=N-1; i>=0; i--) {
16173                ProcessRecord app = mLruProcesses.get(i);
16174                if (allChanged || app.procStateChanged) {
16175                    setProcessTrackerState(app, trackerMemFactor, now);
16176                    app.procStateChanged = false;
16177                }
16178                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16179                        || app.systemNoUi) && app.pendingUiClean) {
16180                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16181                            && app.thread != null) {
16182                        try {
16183                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16184                                    "Trimming memory of ui hidden " + app.processName
16185                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16186                            app.thread.scheduleTrimMemory(
16187                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16188                        } catch (RemoteException e) {
16189                        }
16190                    }
16191                    app.pendingUiClean = false;
16192                }
16193                app.trimMemoryLevel = 0;
16194            }
16195        }
16196
16197        if (mAlwaysFinishActivities) {
16198            // Need to do this on its own message because the stack may not
16199            // be in a consistent state at this point.
16200            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16201        }
16202
16203        if (allChanged) {
16204            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16205        }
16206
16207        if (mProcessStats.shouldWriteNowLocked(now)) {
16208            mHandler.post(new Runnable() {
16209                @Override public void run() {
16210                    synchronized (ActivityManagerService.this) {
16211                        mProcessStats.writeStateAsyncLocked();
16212                    }
16213                }
16214            });
16215        }
16216
16217        if (DEBUG_OOM_ADJ) {
16218            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16219        }
16220    }
16221
16222    final void trimApplications() {
16223        synchronized (this) {
16224            int i;
16225
16226            // First remove any unused application processes whose package
16227            // has been removed.
16228            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16229                final ProcessRecord app = mRemovedProcesses.get(i);
16230                if (app.activities.size() == 0
16231                        && app.curReceiver == null && app.services.size() == 0) {
16232                    Slog.i(
16233                        TAG, "Exiting empty application process "
16234                        + app.processName + " ("
16235                        + (app.thread != null ? app.thread.asBinder() : null)
16236                        + ")\n");
16237                    if (app.pid > 0 && app.pid != MY_PID) {
16238                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16239                                app.processName, app.setAdj, "empty");
16240                        app.killedByAm = true;
16241                        Process.killProcessQuiet(app.pid);
16242                    } else {
16243                        try {
16244                            app.thread.scheduleExit();
16245                        } catch (Exception e) {
16246                            // Ignore exceptions.
16247                        }
16248                    }
16249                    cleanUpApplicationRecordLocked(app, false, true, -1);
16250                    mRemovedProcesses.remove(i);
16251
16252                    if (app.persistent) {
16253                        if (app.persistent) {
16254                            addAppLocked(app.info, false);
16255                        }
16256                    }
16257                }
16258            }
16259
16260            // Now update the oom adj for all processes.
16261            updateOomAdjLocked();
16262        }
16263    }
16264
16265    /** This method sends the specified signal to each of the persistent apps */
16266    public void signalPersistentProcesses(int sig) throws RemoteException {
16267        if (sig != Process.SIGNAL_USR1) {
16268            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16269        }
16270
16271        synchronized (this) {
16272            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16273                    != PackageManager.PERMISSION_GRANTED) {
16274                throw new SecurityException("Requires permission "
16275                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16276            }
16277
16278            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16279                ProcessRecord r = mLruProcesses.get(i);
16280                if (r.thread != null && r.persistent) {
16281                    Process.sendSignal(r.pid, sig);
16282                }
16283            }
16284        }
16285    }
16286
16287    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16288        if (proc == null || proc == mProfileProc) {
16289            proc = mProfileProc;
16290            path = mProfileFile;
16291            profileType = mProfileType;
16292            clearProfilerLocked();
16293        }
16294        if (proc == null) {
16295            return;
16296        }
16297        try {
16298            proc.thread.profilerControl(false, path, null, profileType);
16299        } catch (RemoteException e) {
16300            throw new IllegalStateException("Process disappeared");
16301        }
16302    }
16303
16304    private void clearProfilerLocked() {
16305        if (mProfileFd != null) {
16306            try {
16307                mProfileFd.close();
16308            } catch (IOException e) {
16309            }
16310        }
16311        mProfileApp = null;
16312        mProfileProc = null;
16313        mProfileFile = null;
16314        mProfileType = 0;
16315        mAutoStopProfiler = false;
16316    }
16317
16318    public boolean profileControl(String process, int userId, boolean start,
16319            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16320
16321        try {
16322            synchronized (this) {
16323                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16324                // its own permission.
16325                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16326                        != PackageManager.PERMISSION_GRANTED) {
16327                    throw new SecurityException("Requires permission "
16328                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16329                }
16330
16331                if (start && fd == null) {
16332                    throw new IllegalArgumentException("null fd");
16333                }
16334
16335                ProcessRecord proc = null;
16336                if (process != null) {
16337                    proc = findProcessLocked(process, userId, "profileControl");
16338                }
16339
16340                if (start && (proc == null || proc.thread == null)) {
16341                    throw new IllegalArgumentException("Unknown process: " + process);
16342                }
16343
16344                if (start) {
16345                    stopProfilerLocked(null, null, 0);
16346                    setProfileApp(proc.info, proc.processName, path, fd, false);
16347                    mProfileProc = proc;
16348                    mProfileType = profileType;
16349                    try {
16350                        fd = fd.dup();
16351                    } catch (IOException e) {
16352                        fd = null;
16353                    }
16354                    proc.thread.profilerControl(start, path, fd, profileType);
16355                    fd = null;
16356                    mProfileFd = null;
16357                } else {
16358                    stopProfilerLocked(proc, path, profileType);
16359                    if (fd != null) {
16360                        try {
16361                            fd.close();
16362                        } catch (IOException e) {
16363                        }
16364                    }
16365                }
16366
16367                return true;
16368            }
16369        } catch (RemoteException e) {
16370            throw new IllegalStateException("Process disappeared");
16371        } finally {
16372            if (fd != null) {
16373                try {
16374                    fd.close();
16375                } catch (IOException e) {
16376                }
16377            }
16378        }
16379    }
16380
16381    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16382        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16383                userId, true, true, callName, null);
16384        ProcessRecord proc = null;
16385        try {
16386            int pid = Integer.parseInt(process);
16387            synchronized (mPidsSelfLocked) {
16388                proc = mPidsSelfLocked.get(pid);
16389            }
16390        } catch (NumberFormatException e) {
16391        }
16392
16393        if (proc == null) {
16394            ArrayMap<String, SparseArray<ProcessRecord>> all
16395                    = mProcessNames.getMap();
16396            SparseArray<ProcessRecord> procs = all.get(process);
16397            if (procs != null && procs.size() > 0) {
16398                proc = procs.valueAt(0);
16399                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16400                    for (int i=1; i<procs.size(); i++) {
16401                        ProcessRecord thisProc = procs.valueAt(i);
16402                        if (thisProc.userId == userId) {
16403                            proc = thisProc;
16404                            break;
16405                        }
16406                    }
16407                }
16408            }
16409        }
16410
16411        return proc;
16412    }
16413
16414    public boolean dumpHeap(String process, int userId, boolean managed,
16415            String path, ParcelFileDescriptor fd) throws RemoteException {
16416
16417        try {
16418            synchronized (this) {
16419                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16420                // its own permission (same as profileControl).
16421                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16422                        != PackageManager.PERMISSION_GRANTED) {
16423                    throw new SecurityException("Requires permission "
16424                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16425                }
16426
16427                if (fd == null) {
16428                    throw new IllegalArgumentException("null fd");
16429                }
16430
16431                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16432                if (proc == null || proc.thread == null) {
16433                    throw new IllegalArgumentException("Unknown process: " + process);
16434                }
16435
16436                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16437                if (!isDebuggable) {
16438                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16439                        throw new SecurityException("Process not debuggable: " + proc);
16440                    }
16441                }
16442
16443                proc.thread.dumpHeap(managed, path, fd);
16444                fd = null;
16445                return true;
16446            }
16447        } catch (RemoteException e) {
16448            throw new IllegalStateException("Process disappeared");
16449        } finally {
16450            if (fd != null) {
16451                try {
16452                    fd.close();
16453                } catch (IOException e) {
16454                }
16455            }
16456        }
16457    }
16458
16459    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16460    public void monitor() {
16461        synchronized (this) { }
16462    }
16463
16464    void onCoreSettingsChange(Bundle settings) {
16465        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16466            ProcessRecord processRecord = mLruProcesses.get(i);
16467            try {
16468                if (processRecord.thread != null) {
16469                    processRecord.thread.setCoreSettings(settings);
16470                }
16471            } catch (RemoteException re) {
16472                /* ignore */
16473            }
16474        }
16475    }
16476
16477    // Multi-user methods
16478
16479    /**
16480     * Start user, if its not already running, but don't bring it to foreground.
16481     */
16482    @Override
16483    public boolean startUserInBackground(final int userId) {
16484        return startUser(userId, /* foreground */ false);
16485    }
16486
16487    /**
16488     * Refreshes the list of users related to the current user when either a
16489     * user switch happens or when a new related user is started in the
16490     * background.
16491     */
16492    private void updateCurrentProfileIdsLocked() {
16493        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16494                mCurrentUserId, false /* enabledOnly */);
16495        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16496        for (int i = 0; i < currentProfileIds.length; i++) {
16497            currentProfileIds[i] = profiles.get(i).id;
16498        }
16499        mCurrentProfileIds = currentProfileIds;
16500    }
16501
16502    private Set getProfileIdsLocked(int userId) {
16503        Set userIds = new HashSet<Integer>();
16504        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16505                userId, false /* enabledOnly */);
16506        for (UserInfo user : profiles) {
16507            userIds.add(Integer.valueOf(user.id));
16508        }
16509        return userIds;
16510    }
16511
16512    @Override
16513    public boolean switchUser(final int userId) {
16514        return startUser(userId, /* foregound */ true);
16515    }
16516
16517    private boolean startUser(final int userId, boolean foreground) {
16518        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16519                != PackageManager.PERMISSION_GRANTED) {
16520            String msg = "Permission Denial: switchUser() from pid="
16521                    + Binder.getCallingPid()
16522                    + ", uid=" + Binder.getCallingUid()
16523                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16524            Slog.w(TAG, msg);
16525            throw new SecurityException(msg);
16526        }
16527
16528        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16529
16530        final long ident = Binder.clearCallingIdentity();
16531        try {
16532            synchronized (this) {
16533                final int oldUserId = mCurrentUserId;
16534                if (oldUserId == userId) {
16535                    return true;
16536                }
16537
16538                mStackSupervisor.setLockTaskModeLocked(null);
16539
16540                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16541                if (userInfo == null) {
16542                    Slog.w(TAG, "No user info for user #" + userId);
16543                    return false;
16544                }
16545
16546                if (foreground) {
16547                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16548                            R.anim.screen_user_enter);
16549                }
16550
16551                boolean needStart = false;
16552
16553                // If the user we are switching to is not currently started, then
16554                // we need to start it now.
16555                if (mStartedUsers.get(userId) == null) {
16556                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16557                    updateStartedUserArrayLocked();
16558                    needStart = true;
16559                }
16560
16561                final Integer userIdInt = Integer.valueOf(userId);
16562                mUserLru.remove(userIdInt);
16563                mUserLru.add(userIdInt);
16564
16565                if (foreground) {
16566                    mCurrentUserId = userId;
16567                    updateCurrentProfileIdsLocked();
16568                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16569                    // Once the internal notion of the active user has switched, we lock the device
16570                    // with the option to show the user switcher on the keyguard.
16571                    mWindowManager.lockNow(null);
16572                } else {
16573                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16574                    updateCurrentProfileIdsLocked();
16575                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16576                    mUserLru.remove(currentUserIdInt);
16577                    mUserLru.add(currentUserIdInt);
16578                }
16579
16580                final UserStartedState uss = mStartedUsers.get(userId);
16581
16582                // Make sure user is in the started state.  If it is currently
16583                // stopping, we need to knock that off.
16584                if (uss.mState == UserStartedState.STATE_STOPPING) {
16585                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16586                    // so we can just fairly silently bring the user back from
16587                    // the almost-dead.
16588                    uss.mState = UserStartedState.STATE_RUNNING;
16589                    updateStartedUserArrayLocked();
16590                    needStart = true;
16591                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16592                    // This means ACTION_SHUTDOWN has been sent, so we will
16593                    // need to treat this as a new boot of the user.
16594                    uss.mState = UserStartedState.STATE_BOOTING;
16595                    updateStartedUserArrayLocked();
16596                    needStart = true;
16597                }
16598
16599                if (uss.mState == UserStartedState.STATE_BOOTING) {
16600                    // Booting up a new user, need to tell system services about it.
16601                    // Note that this is on the same handler as scheduling of broadcasts,
16602                    // which is important because it needs to go first.
16603                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16604                }
16605
16606                if (foreground) {
16607                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16608                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16609                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16610                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16611                            oldUserId, userId, uss));
16612                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16613                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16614                }
16615
16616                if (needStart) {
16617                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16618                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16619                            | Intent.FLAG_RECEIVER_FOREGROUND);
16620                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16621                    broadcastIntentLocked(null, null, intent,
16622                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16623                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16624                }
16625
16626                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16627                    if (userId != 0) {
16628                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16629                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16630                        broadcastIntentLocked(null, null, intent, null,
16631                                new IIntentReceiver.Stub() {
16632                                    public void performReceive(Intent intent, int resultCode,
16633                                            String data, Bundle extras, boolean ordered,
16634                                            boolean sticky, int sendingUser) {
16635                                        userInitialized(uss, userId);
16636                                    }
16637                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16638                                true, false, MY_PID, Process.SYSTEM_UID,
16639                                userId);
16640                        uss.initializing = true;
16641                    } else {
16642                        getUserManagerLocked().makeInitialized(userInfo.id);
16643                    }
16644                }
16645
16646                if (foreground) {
16647                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16648                    if (homeInFront) {
16649                        startHomeActivityLocked(userId);
16650                    } else {
16651                        mStackSupervisor.resumeTopActivitiesLocked();
16652                    }
16653                    EventLogTags.writeAmSwitchUser(userId);
16654                    getUserManagerLocked().userForeground(userId);
16655                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16656                }
16657
16658                if (needStart) {
16659                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16660                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16661                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16662                    broadcastIntentLocked(null, null, intent,
16663                            null, new IIntentReceiver.Stub() {
16664                                @Override
16665                                public void performReceive(Intent intent, int resultCode, String data,
16666                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16667                                        throws RemoteException {
16668                                }
16669                            }, 0, null, null,
16670                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16671                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16672                }
16673            }
16674        } finally {
16675            Binder.restoreCallingIdentity(ident);
16676        }
16677
16678        return true;
16679    }
16680
16681    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16682        long ident = Binder.clearCallingIdentity();
16683        try {
16684            Intent intent;
16685            if (oldUserId >= 0) {
16686                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16687                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16688                        | Intent.FLAG_RECEIVER_FOREGROUND);
16689                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16690                broadcastIntentLocked(null, null, intent,
16691                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16692                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16693            }
16694            if (newUserId >= 0) {
16695                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16696                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16697                        | Intent.FLAG_RECEIVER_FOREGROUND);
16698                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16699                broadcastIntentLocked(null, null, intent,
16700                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16701                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16702                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16703                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16704                        | Intent.FLAG_RECEIVER_FOREGROUND);
16705                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16706                broadcastIntentLocked(null, null, intent,
16707                        null, null, 0, null, null,
16708                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16709                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16710            }
16711        } finally {
16712            Binder.restoreCallingIdentity(ident);
16713        }
16714    }
16715
16716    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16717            final int newUserId) {
16718        final int N = mUserSwitchObservers.beginBroadcast();
16719        if (N > 0) {
16720            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16721                int mCount = 0;
16722                @Override
16723                public void sendResult(Bundle data) throws RemoteException {
16724                    synchronized (ActivityManagerService.this) {
16725                        if (mCurUserSwitchCallback == this) {
16726                            mCount++;
16727                            if (mCount == N) {
16728                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16729                            }
16730                        }
16731                    }
16732                }
16733            };
16734            synchronized (this) {
16735                uss.switching = true;
16736                mCurUserSwitchCallback = callback;
16737            }
16738            for (int i=0; i<N; i++) {
16739                try {
16740                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16741                            newUserId, callback);
16742                } catch (RemoteException e) {
16743                }
16744            }
16745        } else {
16746            synchronized (this) {
16747                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16748            }
16749        }
16750        mUserSwitchObservers.finishBroadcast();
16751    }
16752
16753    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16754        synchronized (this) {
16755            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16756            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16757        }
16758    }
16759
16760    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16761        mCurUserSwitchCallback = null;
16762        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16763        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16764                oldUserId, newUserId, uss));
16765    }
16766
16767    void userInitialized(UserStartedState uss, int newUserId) {
16768        completeSwitchAndInitalize(uss, newUserId, true, false);
16769    }
16770
16771    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16772        completeSwitchAndInitalize(uss, newUserId, false, true);
16773    }
16774
16775    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16776            boolean clearInitializing, boolean clearSwitching) {
16777        boolean unfrozen = false;
16778        synchronized (this) {
16779            if (clearInitializing) {
16780                uss.initializing = false;
16781                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16782            }
16783            if (clearSwitching) {
16784                uss.switching = false;
16785            }
16786            if (!uss.switching && !uss.initializing) {
16787                mWindowManager.stopFreezingScreen();
16788                unfrozen = true;
16789            }
16790        }
16791        if (unfrozen) {
16792            final int N = mUserSwitchObservers.beginBroadcast();
16793            for (int i=0; i<N; i++) {
16794                try {
16795                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16796                } catch (RemoteException e) {
16797                }
16798            }
16799            mUserSwitchObservers.finishBroadcast();
16800        }
16801    }
16802
16803    void scheduleStartProfilesLocked() {
16804        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16805            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16806                    DateUtils.SECOND_IN_MILLIS);
16807        }
16808    }
16809
16810    void startProfilesLocked() {
16811        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16812        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16813                mCurrentUserId, false /* enabledOnly */);
16814        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16815        for (UserInfo user : profiles) {
16816            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16817                    && user.id != mCurrentUserId) {
16818                toStart.add(user);
16819            }
16820        }
16821        final int n = toStart.size();
16822        int i = 0;
16823        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16824            startUserInBackground(toStart.get(i).id);
16825        }
16826        if (i < n) {
16827            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16828        }
16829    }
16830
16831    void finishUserSwitch(UserStartedState uss) {
16832        synchronized (this) {
16833            if (uss.mState == UserStartedState.STATE_BOOTING
16834                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16835                uss.mState = UserStartedState.STATE_RUNNING;
16836                final int userId = uss.mHandle.getIdentifier();
16837                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16838                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16839                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16840                broadcastIntentLocked(null, null, intent,
16841                        null, null, 0, null, null,
16842                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16843                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16844            }
16845
16846            startProfilesLocked();
16847
16848            int num = mUserLru.size();
16849            int i = 0;
16850            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16851                Integer oldUserId = mUserLru.get(i);
16852                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16853                if (oldUss == null) {
16854                    // Shouldn't happen, but be sane if it does.
16855                    mUserLru.remove(i);
16856                    num--;
16857                    continue;
16858                }
16859                if (oldUss.mState == UserStartedState.STATE_STOPPING
16860                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16861                    // This user is already stopping, doesn't count.
16862                    num--;
16863                    i++;
16864                    continue;
16865                }
16866                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16867                    // Owner and current can't be stopped, but count as running.
16868                    i++;
16869                    continue;
16870                }
16871                // This is a user to be stopped.
16872                stopUserLocked(oldUserId, null);
16873                num--;
16874                i++;
16875            }
16876        }
16877    }
16878
16879    @Override
16880    public int stopUser(final int userId, final IStopUserCallback callback) {
16881        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16882                != PackageManager.PERMISSION_GRANTED) {
16883            String msg = "Permission Denial: switchUser() from pid="
16884                    + Binder.getCallingPid()
16885                    + ", uid=" + Binder.getCallingUid()
16886                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16887            Slog.w(TAG, msg);
16888            throw new SecurityException(msg);
16889        }
16890        if (userId <= 0) {
16891            throw new IllegalArgumentException("Can't stop primary user " + userId);
16892        }
16893        synchronized (this) {
16894            return stopUserLocked(userId, callback);
16895        }
16896    }
16897
16898    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16899        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16900        if (mCurrentUserId == userId) {
16901            return ActivityManager.USER_OP_IS_CURRENT;
16902        }
16903
16904        final UserStartedState uss = mStartedUsers.get(userId);
16905        if (uss == null) {
16906            // User is not started, nothing to do...  but we do need to
16907            // callback if requested.
16908            if (callback != null) {
16909                mHandler.post(new Runnable() {
16910                    @Override
16911                    public void run() {
16912                        try {
16913                            callback.userStopped(userId);
16914                        } catch (RemoteException e) {
16915                        }
16916                    }
16917                });
16918            }
16919            return ActivityManager.USER_OP_SUCCESS;
16920        }
16921
16922        if (callback != null) {
16923            uss.mStopCallbacks.add(callback);
16924        }
16925
16926        if (uss.mState != UserStartedState.STATE_STOPPING
16927                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16928            uss.mState = UserStartedState.STATE_STOPPING;
16929            updateStartedUserArrayLocked();
16930
16931            long ident = Binder.clearCallingIdentity();
16932            try {
16933                // We are going to broadcast ACTION_USER_STOPPING and then
16934                // once that is done send a final ACTION_SHUTDOWN and then
16935                // stop the user.
16936                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16937                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16938                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16939                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16940                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16941                // This is the result receiver for the final shutdown broadcast.
16942                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16943                    @Override
16944                    public void performReceive(Intent intent, int resultCode, String data,
16945                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16946                        finishUserStop(uss);
16947                    }
16948                };
16949                // This is the result receiver for the initial stopping broadcast.
16950                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16951                    @Override
16952                    public void performReceive(Intent intent, int resultCode, String data,
16953                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16954                        // On to the next.
16955                        synchronized (ActivityManagerService.this) {
16956                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16957                                // Whoops, we are being started back up.  Abort, abort!
16958                                return;
16959                            }
16960                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16961                        }
16962                        mSystemServiceManager.stopUser(userId);
16963                        broadcastIntentLocked(null, null, shutdownIntent,
16964                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16965                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16966                    }
16967                };
16968                // Kick things off.
16969                broadcastIntentLocked(null, null, stoppingIntent,
16970                        null, stoppingReceiver, 0, null, null,
16971                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16972                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16973            } finally {
16974                Binder.restoreCallingIdentity(ident);
16975            }
16976        }
16977
16978        return ActivityManager.USER_OP_SUCCESS;
16979    }
16980
16981    void finishUserStop(UserStartedState uss) {
16982        final int userId = uss.mHandle.getIdentifier();
16983        boolean stopped;
16984        ArrayList<IStopUserCallback> callbacks;
16985        synchronized (this) {
16986            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16987            if (mStartedUsers.get(userId) != uss) {
16988                stopped = false;
16989            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16990                stopped = false;
16991            } else {
16992                stopped = true;
16993                // User can no longer run.
16994                mStartedUsers.remove(userId);
16995                mUserLru.remove(Integer.valueOf(userId));
16996                updateStartedUserArrayLocked();
16997
16998                // Clean up all state and processes associated with the user.
16999                // Kill all the processes for the user.
17000                forceStopUserLocked(userId, "finish user");
17001            }
17002        }
17003
17004        for (int i=0; i<callbacks.size(); i++) {
17005            try {
17006                if (stopped) callbacks.get(i).userStopped(userId);
17007                else callbacks.get(i).userStopAborted(userId);
17008            } catch (RemoteException e) {
17009            }
17010        }
17011
17012        if (stopped) {
17013            mSystemServiceManager.cleanupUser(userId);
17014            synchronized (this) {
17015                mStackSupervisor.removeUserLocked(userId);
17016            }
17017        }
17018    }
17019
17020    @Override
17021    public UserInfo getCurrentUser() {
17022        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17023                != PackageManager.PERMISSION_GRANTED) && (
17024                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17025                != PackageManager.PERMISSION_GRANTED)) {
17026            String msg = "Permission Denial: getCurrentUser() from pid="
17027                    + Binder.getCallingPid()
17028                    + ", uid=" + Binder.getCallingUid()
17029                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17030            Slog.w(TAG, msg);
17031            throw new SecurityException(msg);
17032        }
17033        synchronized (this) {
17034            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17035        }
17036    }
17037
17038    int getCurrentUserIdLocked() {
17039        return mCurrentUserId;
17040    }
17041
17042    @Override
17043    public boolean isUserRunning(int userId, boolean orStopped) {
17044        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17045                != PackageManager.PERMISSION_GRANTED) {
17046            String msg = "Permission Denial: isUserRunning() from pid="
17047                    + Binder.getCallingPid()
17048                    + ", uid=" + Binder.getCallingUid()
17049                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17050            Slog.w(TAG, msg);
17051            throw new SecurityException(msg);
17052        }
17053        synchronized (this) {
17054            return isUserRunningLocked(userId, orStopped);
17055        }
17056    }
17057
17058    boolean isUserRunningLocked(int userId, boolean orStopped) {
17059        UserStartedState state = mStartedUsers.get(userId);
17060        if (state == null) {
17061            return false;
17062        }
17063        if (orStopped) {
17064            return true;
17065        }
17066        return state.mState != UserStartedState.STATE_STOPPING
17067                && state.mState != UserStartedState.STATE_SHUTDOWN;
17068    }
17069
17070    @Override
17071    public int[] getRunningUserIds() {
17072        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17073                != PackageManager.PERMISSION_GRANTED) {
17074            String msg = "Permission Denial: isUserRunning() from pid="
17075                    + Binder.getCallingPid()
17076                    + ", uid=" + Binder.getCallingUid()
17077                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17078            Slog.w(TAG, msg);
17079            throw new SecurityException(msg);
17080        }
17081        synchronized (this) {
17082            return mStartedUserArray;
17083        }
17084    }
17085
17086    private void updateStartedUserArrayLocked() {
17087        int num = 0;
17088        for (int i=0; i<mStartedUsers.size();  i++) {
17089            UserStartedState uss = mStartedUsers.valueAt(i);
17090            // This list does not include stopping users.
17091            if (uss.mState != UserStartedState.STATE_STOPPING
17092                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17093                num++;
17094            }
17095        }
17096        mStartedUserArray = new int[num];
17097        num = 0;
17098        for (int i=0; i<mStartedUsers.size();  i++) {
17099            UserStartedState uss = mStartedUsers.valueAt(i);
17100            if (uss.mState != UserStartedState.STATE_STOPPING
17101                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17102                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17103                num++;
17104            }
17105        }
17106    }
17107
17108    @Override
17109    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17110        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17111                != PackageManager.PERMISSION_GRANTED) {
17112            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17113                    + Binder.getCallingPid()
17114                    + ", uid=" + Binder.getCallingUid()
17115                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17116            Slog.w(TAG, msg);
17117            throw new SecurityException(msg);
17118        }
17119
17120        mUserSwitchObservers.register(observer);
17121    }
17122
17123    @Override
17124    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17125        mUserSwitchObservers.unregister(observer);
17126    }
17127
17128    private boolean userExists(int userId) {
17129        if (userId == 0) {
17130            return true;
17131        }
17132        UserManagerService ums = getUserManagerLocked();
17133        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17134    }
17135
17136    int[] getUsersLocked() {
17137        UserManagerService ums = getUserManagerLocked();
17138        return ums != null ? ums.getUserIds() : new int[] { 0 };
17139    }
17140
17141    UserManagerService getUserManagerLocked() {
17142        if (mUserManager == null) {
17143            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17144            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17145        }
17146        return mUserManager;
17147    }
17148
17149    private int applyUserId(int uid, int userId) {
17150        return UserHandle.getUid(userId, uid);
17151    }
17152
17153    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17154        if (info == null) return null;
17155        ApplicationInfo newInfo = new ApplicationInfo(info);
17156        newInfo.uid = applyUserId(info.uid, userId);
17157        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17158                + info.packageName;
17159        return newInfo;
17160    }
17161
17162    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17163        if (aInfo == null
17164                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17165            return aInfo;
17166        }
17167
17168        ActivityInfo info = new ActivityInfo(aInfo);
17169        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17170        return info;
17171    }
17172
17173    private final class LocalService extends ActivityManagerInternal {
17174        @Override
17175        public void goingToSleep() {
17176            ActivityManagerService.this.goingToSleep();
17177        }
17178
17179        @Override
17180        public void wakingUp() {
17181            ActivityManagerService.this.wakingUp();
17182        }
17183    }
17184}
17185