ActivityManagerService.java revision 82326a98a4507deee89a90654dd0953c459811af
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.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    boolean mStartRunning = false;
803    ComponentName mTopComponent;
804    String mTopAction;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    String mDebugApp = null;
949    boolean mWaitForDebugger = false;
950    boolean mDebugTransient = false;
951    String mOrigDebugApp = null;
952    boolean mOrigWaitForDebugger = false;
953    boolean mAlwaysFinishActivities = false;
954    IActivityController mController = null;
955    String mProfileApp = null;
956    ProcessRecord mProfileProc = null;
957    String mProfileFile;
958    ParcelFileDescriptor mProfileFd;
959    int mProfileType = 0;
960    boolean mAutoStopProfiler = false;
961    String mOpenGlTraceApp = null;
962
963    static class ProcessChangeItem {
964        static final int CHANGE_ACTIVITIES = 1<<0;
965        static final int CHANGE_IMPORTANCE= 1<<1;
966        int changes;
967        int uid;
968        int pid;
969        int importance;
970        boolean foregroundActivities;
971    }
972
973    final RemoteCallbackList<IProcessObserver> mProcessObservers
974            = new RemoteCallbackList<IProcessObserver>();
975    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
976
977    final ArrayList<ProcessChangeItem> mPendingProcessChanges
978            = new ArrayList<ProcessChangeItem>();
979    final ArrayList<ProcessChangeItem> mAvailProcessChanges
980            = new ArrayList<ProcessChangeItem>();
981
982    /**
983     * Runtime CPU use collection thread.  This object's lock is used to
984     * protect all related state.
985     */
986    final Thread mProcessCpuThread;
987
988    /**
989     * Used to collect process stats when showing not responding dialog.
990     * Protected by mProcessCpuThread.
991     */
992    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
993            MONITOR_THREAD_CPU_USAGE);
994    final AtomicLong mLastCpuTime = new AtomicLong(0);
995    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
996
997    long mLastWriteTime = 0;
998
999    /**
1000     * Used to retain an update lock when the foreground activity is in
1001     * immersive mode.
1002     */
1003    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1004
1005    /**
1006     * Set to true after the system has finished booting.
1007     */
1008    boolean mBooted = false;
1009
1010    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1011    int mProcessLimitOverride = -1;
1012
1013    WindowManagerService mWindowManager;
1014
1015    final ActivityThread mSystemThread;
1016
1017    int mCurrentUserId = 0;
1018    int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
1019    private UserManagerService mUserManager;
1020
1021    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1022        final ProcessRecord mApp;
1023        final int mPid;
1024        final IApplicationThread mAppThread;
1025
1026        AppDeathRecipient(ProcessRecord app, int pid,
1027                IApplicationThread thread) {
1028            if (localLOGV) Slog.v(
1029                TAG, "New death recipient " + this
1030                + " for thread " + thread.asBinder());
1031            mApp = app;
1032            mPid = pid;
1033            mAppThread = thread;
1034        }
1035
1036        @Override
1037        public void binderDied() {
1038            if (localLOGV) Slog.v(
1039                TAG, "Death received in " + this
1040                + " for thread " + mAppThread.asBinder());
1041            synchronized(ActivityManagerService.this) {
1042                appDiedLocked(mApp, mPid, mAppThread);
1043            }
1044        }
1045    }
1046
1047    static final int SHOW_ERROR_MSG = 1;
1048    static final int SHOW_NOT_RESPONDING_MSG = 2;
1049    static final int SHOW_FACTORY_ERROR_MSG = 3;
1050    static final int UPDATE_CONFIGURATION_MSG = 4;
1051    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1052    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1053    static final int SERVICE_TIMEOUT_MSG = 12;
1054    static final int UPDATE_TIME_ZONE = 13;
1055    static final int SHOW_UID_ERROR_MSG = 14;
1056    static final int IM_FEELING_LUCKY_MSG = 15;
1057    static final int PROC_START_TIMEOUT_MSG = 20;
1058    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1059    static final int KILL_APPLICATION_MSG = 22;
1060    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1061    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1062    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1063    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1064    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1065    static final int CLEAR_DNS_CACHE_MSG = 28;
1066    static final int UPDATE_HTTP_PROXY_MSG = 29;
1067    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1068    static final int DISPATCH_PROCESSES_CHANGED = 31;
1069    static final int DISPATCH_PROCESS_DIED = 32;
1070    static final int REPORT_MEM_USAGE_MSG = 33;
1071    static final int REPORT_USER_SWITCH_MSG = 34;
1072    static final int CONTINUE_USER_SWITCH_MSG = 35;
1073    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1074    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1075    static final int PERSIST_URI_GRANTS_MSG = 38;
1076    static final int REQUEST_ALL_PSS_MSG = 39;
1077    static final int START_RELATED_USERS_MSG = 40;
1078    static final int UPDATE_TIME = 41;
1079
1080    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1081    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1082    static final int FIRST_COMPAT_MODE_MSG = 300;
1083    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1084
1085    AlertDialog mUidAlert;
1086    CompatModeDialog mCompatModeDialog;
1087    long mLastMemUsageReportTime = 0;
1088
1089    /**
1090     * Flag whether the current user is a "monkey", i.e. whether
1091     * the UI is driven by a UI automation tool.
1092     */
1093    private boolean mUserIsMonkey;
1094
1095    final ServiceThread mHandlerThread;
1096    final MainHandler mHandler;
1097
1098    final class MainHandler extends Handler {
1099        public MainHandler(Looper looper) {
1100            super(looper, null, true);
1101        }
1102
1103        @Override
1104        public void handleMessage(Message msg) {
1105            switch (msg.what) {
1106            case SHOW_ERROR_MSG: {
1107                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1108                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1109                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1110                synchronized (ActivityManagerService.this) {
1111                    ProcessRecord proc = (ProcessRecord)data.get("app");
1112                    AppErrorResult res = (AppErrorResult) data.get("result");
1113                    if (proc != null && proc.crashDialog != null) {
1114                        Slog.e(TAG, "App already has crash dialog: " + proc);
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                        return;
1119                    }
1120                    if (!showBackground && UserHandle.getAppId(proc.uid)
1121                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1122                            && proc.pid != MY_PID) {
1123                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1124                        if (res != null) {
1125                            res.set(0);
1126                        }
1127                        return;
1128                    }
1129                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1130                        Dialog d = new AppErrorDialog(mContext,
1131                                ActivityManagerService.this, res, proc);
1132                        d.show();
1133                        proc.crashDialog = d;
1134                    } else {
1135                        // The device is asleep, so just pretend that the user
1136                        // saw a crash dialog and hit "force quit".
1137                        if (res != null) {
1138                            res.set(0);
1139                        }
1140                    }
1141                }
1142
1143                ensureBootCompleted();
1144            } break;
1145            case SHOW_NOT_RESPONDING_MSG: {
1146                synchronized (ActivityManagerService.this) {
1147                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1148                    ProcessRecord proc = (ProcessRecord)data.get("app");
1149                    if (proc != null && proc.anrDialog != null) {
1150                        Slog.e(TAG, "App already has anr dialog: " + proc);
1151                        return;
1152                    }
1153
1154                    Intent intent = new Intent("android.intent.action.ANR");
1155                    if (!mProcessesReady) {
1156                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1157                                | Intent.FLAG_RECEIVER_FOREGROUND);
1158                    }
1159                    broadcastIntentLocked(null, null, intent,
1160                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1161                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1162
1163                    if (mShowDialogs) {
1164                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1165                                mContext, proc, (ActivityRecord)data.get("activity"),
1166                                msg.arg1 != 0);
1167                        d.show();
1168                        proc.anrDialog = d;
1169                    } else {
1170                        // Just kill the app if there is no dialog to be shown.
1171                        killAppAtUsersRequest(proc, null);
1172                    }
1173                }
1174
1175                ensureBootCompleted();
1176            } break;
1177            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                synchronized (ActivityManagerService.this) {
1180                    ProcessRecord proc = (ProcessRecord) data.get("app");
1181                    if (proc == null) {
1182                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1183                        break;
1184                    }
1185                    if (proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1187                        return;
1188                    }
1189                    AppErrorResult res = (AppErrorResult) data.get("result");
1190                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1191                        Dialog d = new StrictModeViolationDialog(mContext,
1192                                ActivityManagerService.this, res, proc);
1193                        d.show();
1194                        proc.crashDialog = d;
1195                    } else {
1196                        // The device is asleep, so just pretend that the user
1197                        // saw a crash dialog and hit "force quit".
1198                        res.set(0);
1199                    }
1200                }
1201                ensureBootCompleted();
1202            } break;
1203            case SHOW_FACTORY_ERROR_MSG: {
1204                Dialog d = new FactoryErrorDialog(
1205                    mContext, msg.getData().getCharSequence("msg"));
1206                d.show();
1207                ensureBootCompleted();
1208            } break;
1209            case UPDATE_CONFIGURATION_MSG: {
1210                final ContentResolver resolver = mContext.getContentResolver();
1211                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1212            } break;
1213            case GC_BACKGROUND_PROCESSES_MSG: {
1214                synchronized (ActivityManagerService.this) {
1215                    performAppGcsIfAppropriateLocked();
1216                }
1217            } break;
1218            case WAIT_FOR_DEBUGGER_MSG: {
1219                synchronized (ActivityManagerService.this) {
1220                    ProcessRecord app = (ProcessRecord)msg.obj;
1221                    if (msg.arg1 != 0) {
1222                        if (!app.waitedForDebugger) {
1223                            Dialog d = new AppWaitingForDebuggerDialog(
1224                                    ActivityManagerService.this,
1225                                    mContext, app);
1226                            app.waitDialog = d;
1227                            app.waitedForDebugger = true;
1228                            d.show();
1229                        }
1230                    } else {
1231                        if (app.waitDialog != null) {
1232                            app.waitDialog.dismiss();
1233                            app.waitDialog = null;
1234                        }
1235                    }
1236                }
1237            } break;
1238            case SERVICE_TIMEOUT_MSG: {
1239                if (mDidDexOpt) {
1240                    mDidDexOpt = false;
1241                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1242                    nmsg.obj = msg.obj;
1243                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1244                    return;
1245                }
1246                mServices.serviceTimeout((ProcessRecord)msg.obj);
1247            } break;
1248            case UPDATE_TIME_ZONE: {
1249                synchronized (ActivityManagerService.this) {
1250                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1251                        ProcessRecord r = mLruProcesses.get(i);
1252                        if (r.thread != null) {
1253                            try {
1254                                r.thread.updateTimeZone();
1255                            } catch (RemoteException ex) {
1256                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1257                            }
1258                        }
1259                    }
1260                }
1261            } break;
1262            case CLEAR_DNS_CACHE_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1265                        ProcessRecord r = mLruProcesses.get(i);
1266                        if (r.thread != null) {
1267                            try {
1268                                r.thread.clearDnsCache();
1269                            } catch (RemoteException ex) {
1270                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1271                            }
1272                        }
1273                    }
1274                }
1275            } break;
1276            case UPDATE_HTTP_PROXY_MSG: {
1277                ProxyProperties proxy = (ProxyProperties)msg.obj;
1278                String host = "";
1279                String port = "";
1280                String exclList = "";
1281                String pacFileUrl = null;
1282                if (proxy != null) {
1283                    host = proxy.getHost();
1284                    port = Integer.toString(proxy.getPort());
1285                    exclList = proxy.getExclusionList();
1286                    pacFileUrl = proxy.getPacFileUrl();
1287                }
1288                synchronized (ActivityManagerService.this) {
1289                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1290                        ProcessRecord r = mLruProcesses.get(i);
1291                        if (r.thread != null) {
1292                            try {
1293                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1294                            } catch (RemoteException ex) {
1295                                Slog.w(TAG, "Failed to update http proxy for: " +
1296                                        r.info.processName);
1297                            }
1298                        }
1299                    }
1300                }
1301            } break;
1302            case SHOW_UID_ERROR_MSG: {
1303                String title = "System UIDs Inconsistent";
1304                String text = "UIDs on the system are inconsistent, you need to wipe your"
1305                        + " data partition or your device will be unstable.";
1306                Log.e(TAG, title + ": " + text);
1307                if (mShowDialogs) {
1308                    // XXX This is a temporary dialog, no need to localize.
1309                    AlertDialog d = new BaseErrorDialog(mContext);
1310                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1311                    d.setCancelable(false);
1312                    d.setTitle(title);
1313                    d.setMessage(text);
1314                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1315                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1316                    mUidAlert = d;
1317                    d.show();
1318                }
1319            } break;
1320            case IM_FEELING_LUCKY_MSG: {
1321                if (mUidAlert != null) {
1322                    mUidAlert.dismiss();
1323                    mUidAlert = null;
1324                }
1325            } break;
1326            case PROC_START_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1332                    return;
1333                }
1334                ProcessRecord app = (ProcessRecord)msg.obj;
1335                synchronized (ActivityManagerService.this) {
1336                    processStartTimedOutLocked(app);
1337                }
1338            } break;
1339            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1340                synchronized (ActivityManagerService.this) {
1341                    doPendingActivityLaunchesLocked(true);
1342                }
1343            } break;
1344            case KILL_APPLICATION_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    int appid = msg.arg1;
1347                    boolean restart = (msg.arg2 == 1);
1348                    Bundle bundle = (Bundle)msg.obj;
1349                    String pkg = bundle.getString("pkg");
1350                    String reason = bundle.getString("reason");
1351                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1352                            false, UserHandle.USER_ALL, reason);
1353                }
1354            } break;
1355            case FINALIZE_PENDING_INTENT_MSG: {
1356                ((PendingIntentRecord)msg.obj).completeFinalize();
1357            } break;
1358            case POST_HEAVY_NOTIFICATION_MSG: {
1359                INotificationManager inm = NotificationManager.getService();
1360                if (inm == null) {
1361                    return;
1362                }
1363
1364                ActivityRecord root = (ActivityRecord)msg.obj;
1365                ProcessRecord process = root.app;
1366                if (process == null) {
1367                    return;
1368                }
1369
1370                try {
1371                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1372                    String text = mContext.getString(R.string.heavy_weight_notification,
1373                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1374                    Notification notification = new Notification();
1375                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1376                    notification.when = 0;
1377                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1378                    notification.tickerText = text;
1379                    notification.defaults = 0; // please be quiet
1380                    notification.sound = null;
1381                    notification.vibrate = null;
1382                    notification.setLatestEventInfo(context, text,
1383                            mContext.getText(R.string.heavy_weight_notification_detail),
1384                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1385                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1386                                    new UserHandle(root.userId)));
1387
1388                    try {
1389                        int[] outId = new int[1];
1390                        inm.enqueueNotificationWithTag("android", "android", null,
1391                                R.string.heavy_weight_notification,
1392                                notification, outId, root.userId);
1393                    } catch (RuntimeException e) {
1394                        Slog.w(ActivityManagerService.TAG,
1395                                "Error showing notification for heavy-weight app", e);
1396                    } catch (RemoteException e) {
1397                    }
1398                } catch (NameNotFoundException e) {
1399                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1400                }
1401            } break;
1402            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1403                INotificationManager inm = NotificationManager.getService();
1404                if (inm == null) {
1405                    return;
1406                }
1407                try {
1408                    inm.cancelNotificationWithTag("android", null,
1409                            R.string.heavy_weight_notification,  msg.arg1);
1410                } catch (RuntimeException e) {
1411                    Slog.w(ActivityManagerService.TAG,
1412                            "Error canceling notification for service", e);
1413                } catch (RemoteException e) {
1414                }
1415            } break;
1416            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    checkExcessivePowerUsageLocked(true);
1419                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1420                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1421                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1422                }
1423            } break;
1424            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    ActivityRecord ar = (ActivityRecord)msg.obj;
1427                    if (mCompatModeDialog != null) {
1428                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1429                                ar.info.applicationInfo.packageName)) {
1430                            return;
1431                        }
1432                        mCompatModeDialog.dismiss();
1433                        mCompatModeDialog = null;
1434                    }
1435                    if (ar != null && false) {
1436                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1437                                ar.packageName)) {
1438                            int mode = mCompatModePackages.computeCompatModeLocked(
1439                                    ar.info.applicationInfo);
1440                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1441                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1442                                mCompatModeDialog = new CompatModeDialog(
1443                                        ActivityManagerService.this, mContext,
1444                                        ar.info.applicationInfo);
1445                                mCompatModeDialog.show();
1446                            }
1447                        }
1448                    }
1449                }
1450                break;
1451            }
1452            case DISPATCH_PROCESSES_CHANGED: {
1453                dispatchProcessesChanged();
1454                break;
1455            }
1456            case DISPATCH_PROCESS_DIED: {
1457                final int pid = msg.arg1;
1458                final int uid = msg.arg2;
1459                dispatchProcessDied(pid, uid);
1460                break;
1461            }
1462            case REPORT_MEM_USAGE_MSG: {
1463                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1464                Thread thread = new Thread() {
1465                    @Override public void run() {
1466                        final SparseArray<ProcessMemInfo> infoMap
1467                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1468                        for (int i=0, N=memInfos.size(); i<N; i++) {
1469                            ProcessMemInfo mi = memInfos.get(i);
1470                            infoMap.put(mi.pid, mi);
1471                        }
1472                        updateCpuStatsNow();
1473                        synchronized (mProcessCpuThread) {
1474                            final int N = mProcessCpuTracker.countStats();
1475                            for (int i=0; i<N; i++) {
1476                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1477                                if (st.vsize > 0) {
1478                                    long pss = Debug.getPss(st.pid, null);
1479                                    if (pss > 0) {
1480                                        if (infoMap.indexOfKey(st.pid) < 0) {
1481                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1482                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1483                                            mi.pss = pss;
1484                                            memInfos.add(mi);
1485                                        }
1486                                    }
1487                                }
1488                            }
1489                        }
1490
1491                        long totalPss = 0;
1492                        for (int i=0, N=memInfos.size(); i<N; i++) {
1493                            ProcessMemInfo mi = memInfos.get(i);
1494                            if (mi.pss == 0) {
1495                                mi.pss = Debug.getPss(mi.pid, null);
1496                            }
1497                            totalPss += mi.pss;
1498                        }
1499                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1500                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1501                                if (lhs.oomAdj != rhs.oomAdj) {
1502                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1503                                }
1504                                if (lhs.pss != rhs.pss) {
1505                                    return lhs.pss < rhs.pss ? 1 : -1;
1506                                }
1507                                return 0;
1508                            }
1509                        });
1510
1511                        StringBuilder tag = new StringBuilder(128);
1512                        StringBuilder stack = new StringBuilder(128);
1513                        tag.append("Low on memory -- ");
1514                        appendMemBucket(tag, totalPss, "total", false);
1515                        appendMemBucket(stack, totalPss, "total", true);
1516
1517                        StringBuilder logBuilder = new StringBuilder(1024);
1518                        logBuilder.append("Low on memory:\n");
1519
1520                        boolean firstLine = true;
1521                        int lastOomAdj = Integer.MIN_VALUE;
1522                        for (int i=0, N=memInfos.size(); i<N; i++) {
1523                            ProcessMemInfo mi = memInfos.get(i);
1524
1525                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1526                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1527                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1528                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1529                                if (lastOomAdj != mi.oomAdj) {
1530                                    lastOomAdj = mi.oomAdj;
1531                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1532                                        tag.append(" / ");
1533                                    }
1534                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1535                                        if (firstLine) {
1536                                            stack.append(":");
1537                                            firstLine = false;
1538                                        }
1539                                        stack.append("\n\t at ");
1540                                    } else {
1541                                        stack.append("$");
1542                                    }
1543                                } else {
1544                                    tag.append(" ");
1545                                    stack.append("$");
1546                                }
1547                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1548                                    appendMemBucket(tag, mi.pss, mi.name, false);
1549                                }
1550                                appendMemBucket(stack, mi.pss, mi.name, true);
1551                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1552                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1553                                    stack.append("(");
1554                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1555                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1556                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1557                                            stack.append(":");
1558                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1559                                        }
1560                                    }
1561                                    stack.append(")");
1562                                }
1563                            }
1564
1565                            logBuilder.append("  ");
1566                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1567                            logBuilder.append(' ');
1568                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1569                            logBuilder.append(' ');
1570                            ProcessList.appendRamKb(logBuilder, mi.pss);
1571                            logBuilder.append(" kB: ");
1572                            logBuilder.append(mi.name);
1573                            logBuilder.append(" (");
1574                            logBuilder.append(mi.pid);
1575                            logBuilder.append(") ");
1576                            logBuilder.append(mi.adjType);
1577                            logBuilder.append('\n');
1578                            if (mi.adjReason != null) {
1579                                logBuilder.append("                      ");
1580                                logBuilder.append(mi.adjReason);
1581                                logBuilder.append('\n');
1582                            }
1583                        }
1584
1585                        logBuilder.append("           ");
1586                        ProcessList.appendRamKb(logBuilder, totalPss);
1587                        logBuilder.append(" kB: TOTAL\n");
1588
1589                        long[] infos = new long[Debug.MEMINFO_COUNT];
1590                        Debug.getMemInfo(infos);
1591                        logBuilder.append("  MemInfo: ");
1592                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1595                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1596                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1597                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1598                            logBuilder.append("  ZRAM: ");
1599                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1600                            logBuilder.append(" kB RAM, ");
1601                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1602                            logBuilder.append(" kB swap total, ");
1603                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1604                            logBuilder.append(" kB swap free\n");
1605                        }
1606                        Slog.i(TAG, logBuilder.toString());
1607
1608                        StringBuilder dropBuilder = new StringBuilder(1024);
1609                        /*
1610                        StringWriter oomSw = new StringWriter();
1611                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1612                        StringWriter catSw = new StringWriter();
1613                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1614                        String[] emptyArgs = new String[] { };
1615                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1616                        oomPw.flush();
1617                        String oomString = oomSw.toString();
1618                        */
1619                        dropBuilder.append(stack);
1620                        dropBuilder.append('\n');
1621                        dropBuilder.append('\n');
1622                        dropBuilder.append(logBuilder);
1623                        dropBuilder.append('\n');
1624                        /*
1625                        dropBuilder.append(oomString);
1626                        dropBuilder.append('\n');
1627                        */
1628                        StringWriter catSw = new StringWriter();
1629                        synchronized (ActivityManagerService.this) {
1630                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1631                            String[] emptyArgs = new String[] { };
1632                            catPw.println();
1633                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1634                            catPw.println();
1635                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1636                                    false, false, null);
1637                            catPw.println();
1638                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1639                            catPw.flush();
1640                        }
1641                        dropBuilder.append(catSw.toString());
1642                        addErrorToDropBox("lowmem", null, "system_server", null,
1643                                null, tag.toString(), dropBuilder.toString(), null, null);
1644                        //Slog.i(TAG, "Sent to dropbox:");
1645                        //Slog.i(TAG, dropBuilder.toString());
1646                        synchronized (ActivityManagerService.this) {
1647                            long now = SystemClock.uptimeMillis();
1648                            if (mLastMemUsageReportTime < now) {
1649                                mLastMemUsageReportTime = now;
1650                            }
1651                        }
1652                    }
1653                };
1654                thread.start();
1655                break;
1656            }
1657            case REPORT_USER_SWITCH_MSG: {
1658                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1659                break;
1660            }
1661            case CONTINUE_USER_SWITCH_MSG: {
1662                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1663                break;
1664            }
1665            case USER_SWITCH_TIMEOUT_MSG: {
1666                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1667                break;
1668            }
1669            case IMMERSIVE_MODE_LOCK_MSG: {
1670                final boolean nextState = (msg.arg1 != 0);
1671                if (mUpdateLock.isHeld() != nextState) {
1672                    if (DEBUG_IMMERSIVE) {
1673                        final ActivityRecord r = (ActivityRecord) msg.obj;
1674                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1675                    }
1676                    if (nextState) {
1677                        mUpdateLock.acquire();
1678                    } else {
1679                        mUpdateLock.release();
1680                    }
1681                }
1682                break;
1683            }
1684            case PERSIST_URI_GRANTS_MSG: {
1685                writeGrantedUriPermissions();
1686                break;
1687            }
1688            case REQUEST_ALL_PSS_MSG: {
1689                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1690                break;
1691            }
1692            case START_RELATED_USERS_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    startRelatedUsersLocked();
1695                }
1696                break;
1697            }
1698            case UPDATE_TIME: {
1699                synchronized (ActivityManagerService.this) {
1700                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1701                        ProcessRecord r = mLruProcesses.get(i);
1702                        if (r.thread != null) {
1703                            try {
1704                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1705                            } catch (RemoteException ex) {
1706                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1707                            }
1708                        }
1709                    }
1710                }
1711                break;
1712            }
1713            }
1714        }
1715    };
1716
1717    static final int COLLECT_PSS_BG_MSG = 1;
1718
1719    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1720        @Override
1721        public void handleMessage(Message msg) {
1722            switch (msg.what) {
1723            case COLLECT_PSS_BG_MSG: {
1724                int i=0, num=0;
1725                long start = SystemClock.uptimeMillis();
1726                long[] tmp = new long[1];
1727                do {
1728                    ProcessRecord proc;
1729                    int procState;
1730                    int pid;
1731                    synchronized (ActivityManagerService.this) {
1732                        if (i >= mPendingPssProcesses.size()) {
1733                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1734                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1735                            mPendingPssProcesses.clear();
1736                            return;
1737                        }
1738                        proc = mPendingPssProcesses.get(i);
1739                        procState = proc.pssProcState;
1740                        if (proc.thread != null && procState == proc.setProcState) {
1741                            pid = proc.pid;
1742                        } else {
1743                            proc = null;
1744                            pid = 0;
1745                        }
1746                        i++;
1747                    }
1748                    if (proc != null) {
1749                        long pss = Debug.getPss(pid, tmp);
1750                        synchronized (ActivityManagerService.this) {
1751                            if (proc.thread != null && proc.setProcState == procState
1752                                    && proc.pid == pid) {
1753                                num++;
1754                                proc.lastPssTime = SystemClock.uptimeMillis();
1755                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1756                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1757                                        + ": " + pss + " lastPss=" + proc.lastPss
1758                                        + " state=" + ProcessList.makeProcStateString(procState));
1759                                if (proc.initialIdlePss == 0) {
1760                                    proc.initialIdlePss = pss;
1761                                }
1762                                proc.lastPss = pss;
1763                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1764                                    proc.lastCachedPss = pss;
1765                                }
1766                            }
1767                        }
1768                    }
1769                } while (true);
1770            }
1771            }
1772        }
1773    };
1774
1775    public void setSystemProcess() {
1776        try {
1777            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1778            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1779            ServiceManager.addService("meminfo", new MemBinder(this));
1780            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1781            ServiceManager.addService("dbinfo", new DbBinder(this));
1782            if (MONITOR_CPU_USAGE) {
1783                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1784            }
1785            ServiceManager.addService("permission", new PermissionController(this));
1786
1787            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1788                    "android", STOCK_PM_FLAGS);
1789            mSystemThread.installSystemApplicationInfo(info);
1790
1791            synchronized (this) {
1792                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1793                app.persistent = true;
1794                app.pid = MY_PID;
1795                app.maxAdj = ProcessList.SYSTEM_ADJ;
1796                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1797                mProcessNames.put(app.processName, app.uid, app);
1798                synchronized (mPidsSelfLocked) {
1799                    mPidsSelfLocked.put(app.pid, app);
1800                }
1801                updateLruProcessLocked(app, false, null);
1802                updateOomAdjLocked();
1803            }
1804        } catch (PackageManager.NameNotFoundException e) {
1805            throw new RuntimeException(
1806                    "Unable to find android system package", e);
1807        }
1808    }
1809
1810    public void setWindowManager(WindowManagerService wm) {
1811        mWindowManager = wm;
1812        mStackSupervisor.setWindowManager(wm);
1813    }
1814
1815    public void startObservingNativeCrashes() {
1816        final NativeCrashListener ncl = new NativeCrashListener(this);
1817        ncl.start();
1818    }
1819
1820    public IAppOpsService getAppOpsService() {
1821        return mAppOpsService;
1822    }
1823
1824    static class MemBinder extends Binder {
1825        ActivityManagerService mActivityManagerService;
1826        MemBinder(ActivityManagerService activityManagerService) {
1827            mActivityManagerService = activityManagerService;
1828        }
1829
1830        @Override
1831        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1832            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1833                    != PackageManager.PERMISSION_GRANTED) {
1834                pw.println("Permission Denial: can't dump meminfo from from pid="
1835                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1836                        + " without permission " + android.Manifest.permission.DUMP);
1837                return;
1838            }
1839
1840            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1841        }
1842    }
1843
1844    static class GraphicsBinder extends Binder {
1845        ActivityManagerService mActivityManagerService;
1846        GraphicsBinder(ActivityManagerService activityManagerService) {
1847            mActivityManagerService = activityManagerService;
1848        }
1849
1850        @Override
1851        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1852            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1853                    != PackageManager.PERMISSION_GRANTED) {
1854                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1855                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1856                        + " without permission " + android.Manifest.permission.DUMP);
1857                return;
1858            }
1859
1860            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1861        }
1862    }
1863
1864    static class DbBinder extends Binder {
1865        ActivityManagerService mActivityManagerService;
1866        DbBinder(ActivityManagerService activityManagerService) {
1867            mActivityManagerService = activityManagerService;
1868        }
1869
1870        @Override
1871        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1872            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1873                    != PackageManager.PERMISSION_GRANTED) {
1874                pw.println("Permission Denial: can't dump dbinfo from from pid="
1875                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1876                        + " without permission " + android.Manifest.permission.DUMP);
1877                return;
1878            }
1879
1880            mActivityManagerService.dumpDbInfo(fd, pw, args);
1881        }
1882    }
1883
1884    static class CpuBinder extends Binder {
1885        ActivityManagerService mActivityManagerService;
1886        CpuBinder(ActivityManagerService activityManagerService) {
1887            mActivityManagerService = activityManagerService;
1888        }
1889
1890        @Override
1891        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1892            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1893                    != PackageManager.PERMISSION_GRANTED) {
1894                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1895                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1896                        + " without permission " + android.Manifest.permission.DUMP);
1897                return;
1898            }
1899
1900            synchronized (mActivityManagerService.mProcessCpuThread) {
1901                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1902                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1903                        SystemClock.uptimeMillis()));
1904            }
1905        }
1906    }
1907
1908    public static final class Lifecycle extends SystemService {
1909        private final ActivityManagerService mService;
1910
1911        public Lifecycle(Context context) {
1912            super(context);
1913            mService = new ActivityManagerService(context);
1914        }
1915
1916        @Override
1917        public void onStart() {
1918            mService.start();
1919        }
1920
1921        public ActivityManagerService getService() {
1922            return mService;
1923        }
1924    }
1925
1926    // Note: This method is invoked on the main thread but may need to attach various
1927    // handlers to other threads.  So take care to be explicit about the looper.
1928    public ActivityManagerService(Context systemContext) {
1929        mContext = systemContext;
1930        mFactoryTest = FactoryTest.getMode();
1931        mSystemThread = ActivityThread.currentActivityThread();
1932
1933        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1934
1935        mHandlerThread = new ServiceThread(TAG,
1936                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1937        mHandlerThread.start();
1938        mHandler = new MainHandler(mHandlerThread.getLooper());
1939
1940        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1941                "foreground", BROADCAST_FG_TIMEOUT, false);
1942        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1943                "background", BROADCAST_BG_TIMEOUT, true);
1944        mBroadcastQueues[0] = mFgBroadcastQueue;
1945        mBroadcastQueues[1] = mBgBroadcastQueue;
1946
1947        mServices = new ActiveServices(this);
1948        mProviderMap = new ProviderMap(this);
1949
1950        // TODO: Move creation of battery stats service outside of activity manager service.
1951        File dataDir = Environment.getDataDirectory();
1952        File systemDir = new File(dataDir, "system");
1953        systemDir.mkdirs();
1954        mBatteryStatsService = new BatteryStatsService(new File(
1955                systemDir, "batterystats.bin").toString(), mHandler);
1956        mBatteryStatsService.getActiveStatistics().readLocked();
1957        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1958        mOnBattery = DEBUG_POWER ? true
1959                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1960        mBatteryStatsService.getActiveStatistics().setCallback(this);
1961
1962        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1963
1964        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1965        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1966
1967        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1968
1969        // User 0 is the first and only user that runs at boot.
1970        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1971        mUserLru.add(Integer.valueOf(0));
1972        updateStartedUserArrayLocked();
1973
1974        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1975            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1976
1977        mConfiguration.setToDefaults();
1978        mConfiguration.setLocale(Locale.getDefault());
1979
1980        mConfigurationSeq = mConfiguration.seq = 1;
1981        mProcessCpuTracker.init();
1982
1983        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1984        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1985        mStackSupervisor = new ActivityStackSupervisor(this);
1986
1987        mProcessCpuThread = new Thread("CpuTracker") {
1988            @Override
1989            public void run() {
1990                while (true) {
1991                    try {
1992                        try {
1993                            synchronized(this) {
1994                                final long now = SystemClock.uptimeMillis();
1995                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1996                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1997                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1998                                //        + ", write delay=" + nextWriteDelay);
1999                                if (nextWriteDelay < nextCpuDelay) {
2000                                    nextCpuDelay = nextWriteDelay;
2001                                }
2002                                if (nextCpuDelay > 0) {
2003                                    mProcessCpuMutexFree.set(true);
2004                                    this.wait(nextCpuDelay);
2005                                }
2006                            }
2007                        } catch (InterruptedException e) {
2008                        }
2009                        updateCpuStatsNow();
2010                    } catch (Exception e) {
2011                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2012                    }
2013                }
2014            }
2015        };
2016
2017        Watchdog.getInstance().addMonitor(this);
2018        Watchdog.getInstance().addThread(mHandler);
2019    }
2020
2021    private void start() {
2022        mProcessCpuThread.start();
2023
2024        mBatteryStatsService.publish(mContext);
2025        mUsageStatsService.publish(mContext);
2026        mAppOpsService.publish(mContext);
2027        startRunning(null, null, null, null);
2028    }
2029
2030    @Override
2031    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2032            throws RemoteException {
2033        if (code == SYSPROPS_TRANSACTION) {
2034            // We need to tell all apps about the system property change.
2035            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2036            synchronized(this) {
2037                final int NP = mProcessNames.getMap().size();
2038                for (int ip=0; ip<NP; ip++) {
2039                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2040                    final int NA = apps.size();
2041                    for (int ia=0; ia<NA; ia++) {
2042                        ProcessRecord app = apps.valueAt(ia);
2043                        if (app.thread != null) {
2044                            procs.add(app.thread.asBinder());
2045                        }
2046                    }
2047                }
2048            }
2049
2050            int N = procs.size();
2051            for (int i=0; i<N; i++) {
2052                Parcel data2 = Parcel.obtain();
2053                try {
2054                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2055                } catch (RemoteException e) {
2056                }
2057                data2.recycle();
2058            }
2059        }
2060        try {
2061            return super.onTransact(code, data, reply, flags);
2062        } catch (RuntimeException e) {
2063            // The activity manager only throws security exceptions, so let's
2064            // log all others.
2065            if (!(e instanceof SecurityException)) {
2066                Slog.wtf(TAG, "Activity Manager Crash", e);
2067            }
2068            throw e;
2069        }
2070    }
2071
2072    void updateCpuStats() {
2073        final long now = SystemClock.uptimeMillis();
2074        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2075            return;
2076        }
2077        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2078            synchronized (mProcessCpuThread) {
2079                mProcessCpuThread.notify();
2080            }
2081        }
2082    }
2083
2084    void updateCpuStatsNow() {
2085        synchronized (mProcessCpuThread) {
2086            mProcessCpuMutexFree.set(false);
2087            final long now = SystemClock.uptimeMillis();
2088            boolean haveNewCpuStats = false;
2089
2090            if (MONITOR_CPU_USAGE &&
2091                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2092                mLastCpuTime.set(now);
2093                haveNewCpuStats = true;
2094                mProcessCpuTracker.update();
2095                //Slog.i(TAG, mProcessCpu.printCurrentState());
2096                //Slog.i(TAG, "Total CPU usage: "
2097                //        + mProcessCpu.getTotalCpuPercent() + "%");
2098
2099                // Slog the cpu usage if the property is set.
2100                if ("true".equals(SystemProperties.get("events.cpu"))) {
2101                    int user = mProcessCpuTracker.getLastUserTime();
2102                    int system = mProcessCpuTracker.getLastSystemTime();
2103                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2104                    int irq = mProcessCpuTracker.getLastIrqTime();
2105                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2106                    int idle = mProcessCpuTracker.getLastIdleTime();
2107
2108                    int total = user + system + iowait + irq + softIrq + idle;
2109                    if (total == 0) total = 1;
2110
2111                    EventLog.writeEvent(EventLogTags.CPU,
2112                            ((user+system+iowait+irq+softIrq) * 100) / total,
2113                            (user * 100) / total,
2114                            (system * 100) / total,
2115                            (iowait * 100) / total,
2116                            (irq * 100) / total,
2117                            (softIrq * 100) / total);
2118                }
2119            }
2120
2121            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2122            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2123            synchronized(bstats) {
2124                synchronized(mPidsSelfLocked) {
2125                    if (haveNewCpuStats) {
2126                        if (mOnBattery) {
2127                            int perc = bstats.startAddingCpuLocked();
2128                            int totalUTime = 0;
2129                            int totalSTime = 0;
2130                            final int N = mProcessCpuTracker.countStats();
2131                            for (int i=0; i<N; i++) {
2132                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2133                                if (!st.working) {
2134                                    continue;
2135                                }
2136                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2137                                int otherUTime = (st.rel_utime*perc)/100;
2138                                int otherSTime = (st.rel_stime*perc)/100;
2139                                totalUTime += otherUTime;
2140                                totalSTime += otherSTime;
2141                                if (pr != null) {
2142                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2143                                    if (ps == null || !ps.isActive()) {
2144                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2145                                                pr.info.uid, pr.processName);
2146                                    }
2147                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2148                                            st.rel_stime-otherSTime);
2149                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2150                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2151                                } else {
2152                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2153                                    if (ps == null || !ps.isActive()) {
2154                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2155                                                bstats.mapUid(st.uid), st.name);
2156                                    }
2157                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2158                                            st.rel_stime-otherSTime);
2159                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2160                                }
2161                            }
2162                            bstats.finishAddingCpuLocked(perc, totalUTime,
2163                                    totalSTime, cpuSpeedTimes);
2164                        }
2165                    }
2166                }
2167
2168                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2169                    mLastWriteTime = now;
2170                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2171                }
2172            }
2173        }
2174    }
2175
2176    @Override
2177    public void batteryNeedsCpuUpdate() {
2178        updateCpuStatsNow();
2179    }
2180
2181    @Override
2182    public void batteryPowerChanged(boolean onBattery) {
2183        // When plugging in, update the CPU stats first before changing
2184        // the plug state.
2185        updateCpuStatsNow();
2186        synchronized (this) {
2187            synchronized(mPidsSelfLocked) {
2188                mOnBattery = DEBUG_POWER ? true : onBattery;
2189            }
2190        }
2191    }
2192
2193    /**
2194     * Initialize the application bind args. These are passed to each
2195     * process when the bindApplication() IPC is sent to the process. They're
2196     * lazily setup to make sure the services are running when they're asked for.
2197     */
2198    private HashMap<String, IBinder> getCommonServicesLocked() {
2199        if (mAppBindArgs == null) {
2200            mAppBindArgs = new HashMap<String, IBinder>();
2201
2202            // Setup the application init args
2203            mAppBindArgs.put("package", ServiceManager.getService("package"));
2204            mAppBindArgs.put("window", ServiceManager.getService("window"));
2205            mAppBindArgs.put(Context.ALARM_SERVICE,
2206                    ServiceManager.getService(Context.ALARM_SERVICE));
2207        }
2208        return mAppBindArgs;
2209    }
2210
2211    final void setFocusedActivityLocked(ActivityRecord r) {
2212        if (mFocusedActivity != r) {
2213            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2214            mFocusedActivity = r;
2215            mStackSupervisor.setFocusedStack(r);
2216            if (r != null) {
2217                mWindowManager.setFocusedApp(r.appToken, true);
2218            }
2219            applyUpdateLockStateLocked(r);
2220        }
2221    }
2222
2223    @Override
2224    public void setFocusedStack(int stackId) {
2225        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2226        synchronized (ActivityManagerService.this) {
2227            ActivityStack stack = mStackSupervisor.getStack(stackId);
2228            if (stack != null) {
2229                ActivityRecord r = stack.topRunningActivityLocked(null);
2230                if (r != null) {
2231                    setFocusedActivityLocked(r);
2232                }
2233            }
2234        }
2235    }
2236
2237    @Override
2238    public void notifyActivityDrawn(IBinder token) {
2239        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2240        synchronized (this) {
2241            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2242            if (r != null) {
2243                r.task.stack.notifyActivityDrawnLocked(r);
2244            }
2245        }
2246    }
2247
2248    final void applyUpdateLockStateLocked(ActivityRecord r) {
2249        // Modifications to the UpdateLock state are done on our handler, outside
2250        // the activity manager's locks.  The new state is determined based on the
2251        // state *now* of the relevant activity record.  The object is passed to
2252        // the handler solely for logging detail, not to be consulted/modified.
2253        final boolean nextState = r != null && r.immersive;
2254        mHandler.sendMessage(
2255                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2256    }
2257
2258    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2259        Message msg = Message.obtain();
2260        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2261        msg.obj = r.task.askedCompatMode ? null : r;
2262        mHandler.sendMessage(msg);
2263    }
2264
2265    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2266            String what, Object obj, ProcessRecord srcApp) {
2267        app.lastActivityTime = now;
2268
2269        if (app.activities.size() > 0) {
2270            // Don't want to touch dependent processes that are hosting activities.
2271            return index;
2272        }
2273
2274        int lrui = mLruProcesses.lastIndexOf(app);
2275        if (lrui < 0) {
2276            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2277                    + what + " " + obj + " from " + srcApp);
2278            return index;
2279        }
2280
2281        if (lrui >= index) {
2282            // Don't want to cause this to move dependent processes *back* in the
2283            // list as if they were less frequently used.
2284            return index;
2285        }
2286
2287        if (lrui >= mLruProcessActivityStart) {
2288            // Don't want to touch dependent processes that are hosting activities.
2289            return index;
2290        }
2291
2292        mLruProcesses.remove(lrui);
2293        if (index > 0) {
2294            index--;
2295        }
2296        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2297                + " in LRU list: " + app);
2298        mLruProcesses.add(index, app);
2299        return index;
2300    }
2301
2302    final void removeLruProcessLocked(ProcessRecord app) {
2303        int lrui = mLruProcesses.lastIndexOf(app);
2304        if (lrui >= 0) {
2305            if (lrui <= mLruProcessActivityStart) {
2306                mLruProcessActivityStart--;
2307            }
2308            if (lrui <= mLruProcessServiceStart) {
2309                mLruProcessServiceStart--;
2310            }
2311            mLruProcesses.remove(lrui);
2312        }
2313    }
2314
2315    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2316            ProcessRecord client) {
2317        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2318        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2319        if (!activityChange && hasActivity) {
2320            // The process has activties, so we are only going to allow activity-based
2321            // adjustments move it.  It should be kept in the front of the list with other
2322            // processes that have activities, and we don't want those to change their
2323            // order except due to activity operations.
2324            return;
2325        }
2326
2327        mLruSeq++;
2328        final long now = SystemClock.uptimeMillis();
2329        app.lastActivityTime = now;
2330
2331        // First a quick reject: if the app is already at the position we will
2332        // put it, then there is nothing to do.
2333        if (hasActivity) {
2334            final int N = mLruProcesses.size();
2335            if (N > 0 && mLruProcesses.get(N-1) == app) {
2336                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2337                return;
2338            }
2339        } else {
2340            if (mLruProcessServiceStart > 0
2341                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2342                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2343                return;
2344            }
2345        }
2346
2347        int lrui = mLruProcesses.lastIndexOf(app);
2348
2349        if (app.persistent && lrui >= 0) {
2350            // We don't care about the position of persistent processes, as long as
2351            // they are in the list.
2352            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2353            return;
2354        }
2355
2356        /* In progress: compute new position first, so we can avoid doing work
2357           if the process is not actually going to move.  Not yet working.
2358        int addIndex;
2359        int nextIndex;
2360        boolean inActivity = false, inService = false;
2361        if (hasActivity) {
2362            // Process has activities, put it at the very tipsy-top.
2363            addIndex = mLruProcesses.size();
2364            nextIndex = mLruProcessServiceStart;
2365            inActivity = true;
2366        } else if (hasService) {
2367            // Process has services, put it at the top of the service list.
2368            addIndex = mLruProcessActivityStart;
2369            nextIndex = mLruProcessServiceStart;
2370            inActivity = true;
2371            inService = true;
2372        } else  {
2373            // Process not otherwise of interest, it goes to the top of the non-service area.
2374            addIndex = mLruProcessServiceStart;
2375            if (client != null) {
2376                int clientIndex = mLruProcesses.lastIndexOf(client);
2377                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2378                        + app);
2379                if (clientIndex >= 0 && addIndex > clientIndex) {
2380                    addIndex = clientIndex;
2381                }
2382            }
2383            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2384        }
2385
2386        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2387                + mLruProcessActivityStart + "): " + app);
2388        */
2389
2390        if (lrui >= 0) {
2391            if (lrui < mLruProcessActivityStart) {
2392                mLruProcessActivityStart--;
2393            }
2394            if (lrui < mLruProcessServiceStart) {
2395                mLruProcessServiceStart--;
2396            }
2397            /*
2398            if (addIndex > lrui) {
2399                addIndex--;
2400            }
2401            if (nextIndex > lrui) {
2402                nextIndex--;
2403            }
2404            */
2405            mLruProcesses.remove(lrui);
2406        }
2407
2408        /*
2409        mLruProcesses.add(addIndex, app);
2410        if (inActivity) {
2411            mLruProcessActivityStart++;
2412        }
2413        if (inService) {
2414            mLruProcessActivityStart++;
2415        }
2416        */
2417
2418        int nextIndex;
2419        if (hasActivity) {
2420            final int N = mLruProcesses.size();
2421            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2422                // Process doesn't have activities, but has clients with
2423                // activities...  move it up, but one below the top (the top
2424                // should always have a real activity).
2425                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2426                mLruProcesses.add(N-1, app);
2427                // To keep it from spamming the LRU list (by making a bunch of clients),
2428                // we will push down any other entries owned by the app.
2429                final int uid = app.info.uid;
2430                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2431                    ProcessRecord subProc = mLruProcesses.get(i);
2432                    if (subProc.info.uid == uid) {
2433                        // We want to push this one down the list.  If the process after
2434                        // it is for the same uid, however, don't do so, because we don't
2435                        // want them internally to be re-ordered.
2436                        if (mLruProcesses.get(i-1).info.uid != uid) {
2437                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2438                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2439                            ProcessRecord tmp = mLruProcesses.get(i);
2440                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2441                            mLruProcesses.set(i-1, tmp);
2442                            i--;
2443                        }
2444                    } else {
2445                        // A gap, we can stop here.
2446                        break;
2447                    }
2448                }
2449            } else {
2450                // Process has activities, put it at the very tipsy-top.
2451                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2452                mLruProcesses.add(app);
2453            }
2454            nextIndex = mLruProcessServiceStart;
2455        } else if (hasService) {
2456            // Process has services, put it at the top of the service list.
2457            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2458            mLruProcesses.add(mLruProcessActivityStart, app);
2459            nextIndex = mLruProcessServiceStart;
2460            mLruProcessActivityStart++;
2461        } else  {
2462            // Process not otherwise of interest, it goes to the top of the non-service area.
2463            int index = mLruProcessServiceStart;
2464            if (client != null) {
2465                // If there is a client, don't allow the process to be moved up higher
2466                // in the list than that client.
2467                int clientIndex = mLruProcesses.lastIndexOf(client);
2468                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2469                        + " when updating " + app);
2470                if (clientIndex <= lrui) {
2471                    // Don't allow the client index restriction to push it down farther in the
2472                    // list than it already is.
2473                    clientIndex = lrui;
2474                }
2475                if (clientIndex >= 0 && index > clientIndex) {
2476                    index = clientIndex;
2477                }
2478            }
2479            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2480            mLruProcesses.add(index, app);
2481            nextIndex = index-1;
2482            mLruProcessActivityStart++;
2483            mLruProcessServiceStart++;
2484        }
2485
2486        // If the app is currently using a content provider or service,
2487        // bump those processes as well.
2488        for (int j=app.connections.size()-1; j>=0; j--) {
2489            ConnectionRecord cr = app.connections.valueAt(j);
2490            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2491                    && cr.binding.service.app != null
2492                    && cr.binding.service.app.lruSeq != mLruSeq
2493                    && !cr.binding.service.app.persistent) {
2494                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2495                        "service connection", cr, app);
2496            }
2497        }
2498        for (int j=app.conProviders.size()-1; j>=0; j--) {
2499            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2500            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2501                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2502                        "provider reference", cpr, app);
2503            }
2504        }
2505    }
2506
2507    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2508        if (uid == Process.SYSTEM_UID) {
2509            // The system gets to run in any process.  If there are multiple
2510            // processes with the same uid, just pick the first (this
2511            // should never happen).
2512            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2513            if (procs == null) return null;
2514            final int N = procs.size();
2515            for (int i = 0; i < N; i++) {
2516                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2517            }
2518        }
2519        ProcessRecord proc = mProcessNames.get(processName, uid);
2520        if (false && proc != null && !keepIfLarge
2521                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2522                && proc.lastCachedPss >= 4000) {
2523            // Turn this condition on to cause killing to happen regularly, for testing.
2524            if (proc.baseProcessTracker != null) {
2525                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2526            }
2527            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2528                    + "k from cached");
2529        } else if (proc != null && !keepIfLarge
2530                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2531                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2532            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2533            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2534                if (proc.baseProcessTracker != null) {
2535                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2536                }
2537                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2538                        + "k from cached");
2539            }
2540        }
2541        return proc;
2542    }
2543
2544    void ensurePackageDexOpt(String packageName) {
2545        IPackageManager pm = AppGlobals.getPackageManager();
2546        try {
2547            if (pm.performDexOpt(packageName)) {
2548                mDidDexOpt = true;
2549            }
2550        } catch (RemoteException e) {
2551        }
2552    }
2553
2554    boolean isNextTransitionForward() {
2555        int transit = mWindowManager.getPendingAppTransition();
2556        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2557                || transit == AppTransition.TRANSIT_TASK_OPEN
2558                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2559    }
2560
2561    final ProcessRecord startProcessLocked(String processName,
2562            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2563            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2564            boolean isolated, boolean keepIfLarge) {
2565        ProcessRecord app;
2566        if (!isolated) {
2567            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2568        } else {
2569            // If this is an isolated process, it can't re-use an existing process.
2570            app = null;
2571        }
2572        // We don't have to do anything more if:
2573        // (1) There is an existing application record; and
2574        // (2) The caller doesn't think it is dead, OR there is no thread
2575        //     object attached to it so we know it couldn't have crashed; and
2576        // (3) There is a pid assigned to it, so it is either starting or
2577        //     already running.
2578        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2579                + " app=" + app + " knownToBeDead=" + knownToBeDead
2580                + " thread=" + (app != null ? app.thread : null)
2581                + " pid=" + (app != null ? app.pid : -1));
2582        if (app != null && app.pid > 0) {
2583            if (!knownToBeDead || app.thread == null) {
2584                // We already have the app running, or are waiting for it to
2585                // come up (we have a pid but not yet its thread), so keep it.
2586                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2587                // If this is a new package in the process, add the package to the list
2588                app.addPackage(info.packageName, mProcessStats);
2589                return app;
2590            }
2591
2592            // An application record is attached to a previous process,
2593            // clean it up now.
2594            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2595            handleAppDiedLocked(app, true, true);
2596        }
2597
2598        String hostingNameStr = hostingName != null
2599                ? hostingName.flattenToShortString() : null;
2600
2601        if (!isolated) {
2602            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2603                // If we are in the background, then check to see if this process
2604                // is bad.  If so, we will just silently fail.
2605                if (mBadProcesses.get(info.processName, info.uid) != null) {
2606                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2607                            + "/" + info.processName);
2608                    return null;
2609                }
2610            } else {
2611                // When the user is explicitly starting a process, then clear its
2612                // crash count so that we won't make it bad until they see at
2613                // least one crash dialog again, and make the process good again
2614                // if it had been bad.
2615                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2616                        + "/" + info.processName);
2617                mProcessCrashTimes.remove(info.processName, info.uid);
2618                if (mBadProcesses.get(info.processName, info.uid) != null) {
2619                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2620                            UserHandle.getUserId(info.uid), info.uid,
2621                            info.processName);
2622                    mBadProcesses.remove(info.processName, info.uid);
2623                    if (app != null) {
2624                        app.bad = false;
2625                    }
2626                }
2627            }
2628        }
2629
2630        if (app == null) {
2631            app = newProcessRecordLocked(info, processName, isolated);
2632            if (app == null) {
2633                Slog.w(TAG, "Failed making new process record for "
2634                        + processName + "/" + info.uid + " isolated=" + isolated);
2635                return null;
2636            }
2637            mProcessNames.put(processName, app.uid, app);
2638            if (isolated) {
2639                mIsolatedProcesses.put(app.uid, app);
2640            }
2641        } else {
2642            // If this is a new package in the process, add the package to the list
2643            app.addPackage(info.packageName, mProcessStats);
2644        }
2645
2646        // If the system is not ready yet, then hold off on starting this
2647        // process until it is.
2648        if (!mProcessesReady
2649                && !isAllowedWhileBooting(info)
2650                && !allowWhileBooting) {
2651            if (!mProcessesOnHold.contains(app)) {
2652                mProcessesOnHold.add(app);
2653            }
2654            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2655            return app;
2656        }
2657
2658        startProcessLocked(app, hostingType, hostingNameStr);
2659        return (app.pid != 0) ? app : null;
2660    }
2661
2662    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2663        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2664    }
2665
2666    private final void startProcessLocked(ProcessRecord app,
2667            String hostingType, String hostingNameStr) {
2668        if (app.pid > 0 && app.pid != MY_PID) {
2669            synchronized (mPidsSelfLocked) {
2670                mPidsSelfLocked.remove(app.pid);
2671                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2672            }
2673            app.setPid(0);
2674        }
2675
2676        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2677                "startProcessLocked removing on hold: " + app);
2678        mProcessesOnHold.remove(app);
2679
2680        updateCpuStats();
2681
2682        try {
2683            int uid = app.uid;
2684
2685            int[] gids = null;
2686            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2687            if (!app.isolated) {
2688                int[] permGids = null;
2689                try {
2690                    final PackageManager pm = mContext.getPackageManager();
2691                    permGids = pm.getPackageGids(app.info.packageName);
2692
2693                    if (Environment.isExternalStorageEmulated()) {
2694                        if (pm.checkPermission(
2695                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2696                                app.info.packageName) == PERMISSION_GRANTED) {
2697                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2698                        } else {
2699                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2700                        }
2701                    }
2702                } catch (PackageManager.NameNotFoundException e) {
2703                    Slog.w(TAG, "Unable to retrieve gids", e);
2704                }
2705
2706                /*
2707                 * Add shared application GID so applications can share some
2708                 * resources like shared libraries
2709                 */
2710                if (permGids == null) {
2711                    gids = new int[1];
2712                } else {
2713                    gids = new int[permGids.length + 1];
2714                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2715                }
2716                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2717            }
2718            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2719                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2720                        && mTopComponent != null
2721                        && app.processName.equals(mTopComponent.getPackageName())) {
2722                    uid = 0;
2723                }
2724                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2725                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2726                    uid = 0;
2727                }
2728            }
2729            int debugFlags = 0;
2730            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2731                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2732                // Also turn on CheckJNI for debuggable apps. It's quite
2733                // awkward to turn on otherwise.
2734                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2735            }
2736            // Run the app in safe mode if its manifest requests so or the
2737            // system is booted in safe mode.
2738            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2739                Zygote.systemInSafeMode == true) {
2740                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2741            }
2742            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2743                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2744            }
2745            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2746                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2747            }
2748            if ("1".equals(SystemProperties.get("debug.assert"))) {
2749                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2750            }
2751
2752            // Start the process.  It will either succeed and return a result containing
2753            // the PID of the new process, or else throw a RuntimeException.
2754            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2755                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2756                    app.info.targetSdkVersion, app.info.seinfo, null);
2757
2758            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2759            synchronized (bs) {
2760                if (bs.isOnBattery()) {
2761                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2762                }
2763            }
2764
2765            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2766                    UserHandle.getUserId(uid), startResult.pid, uid,
2767                    app.processName, hostingType,
2768                    hostingNameStr != null ? hostingNameStr : "");
2769
2770            if (app.persistent) {
2771                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2772            }
2773
2774            StringBuilder buf = mStringBuilder;
2775            buf.setLength(0);
2776            buf.append("Start proc ");
2777            buf.append(app.processName);
2778            buf.append(" for ");
2779            buf.append(hostingType);
2780            if (hostingNameStr != null) {
2781                buf.append(" ");
2782                buf.append(hostingNameStr);
2783            }
2784            buf.append(": pid=");
2785            buf.append(startResult.pid);
2786            buf.append(" uid=");
2787            buf.append(uid);
2788            buf.append(" gids={");
2789            if (gids != null) {
2790                for (int gi=0; gi<gids.length; gi++) {
2791                    if (gi != 0) buf.append(", ");
2792                    buf.append(gids[gi]);
2793
2794                }
2795            }
2796            buf.append("}");
2797            Slog.i(TAG, buf.toString());
2798            app.setPid(startResult.pid);
2799            app.usingWrapper = startResult.usingWrapper;
2800            app.removed = false;
2801            synchronized (mPidsSelfLocked) {
2802                this.mPidsSelfLocked.put(startResult.pid, app);
2803                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2804                msg.obj = app;
2805                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2806                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2807            }
2808            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2809                    app.processName, app.info.uid);
2810            if (app.isolated) {
2811                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2812            }
2813        } catch (RuntimeException e) {
2814            // XXX do better error recovery.
2815            app.setPid(0);
2816            Slog.e(TAG, "Failure starting process " + app.processName, e);
2817        }
2818    }
2819
2820    void updateUsageStats(ActivityRecord component, boolean resumed) {
2821        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2822        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2823        if (resumed) {
2824            mUsageStatsService.noteResumeComponent(component.realActivity);
2825            synchronized (stats) {
2826                stats.noteActivityResumedLocked(component.app.uid);
2827            }
2828        } else {
2829            mUsageStatsService.notePauseComponent(component.realActivity);
2830            synchronized (stats) {
2831                stats.noteActivityPausedLocked(component.app.uid);
2832            }
2833        }
2834    }
2835
2836    Intent getHomeIntent() {
2837        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2838        intent.setComponent(mTopComponent);
2839        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2840            intent.addCategory(Intent.CATEGORY_HOME);
2841        }
2842        return intent;
2843    }
2844
2845    boolean startHomeActivityLocked(int userId) {
2846        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2847                && mTopAction == null) {
2848            // We are running in factory test mode, but unable to find
2849            // the factory test app, so just sit around displaying the
2850            // error message and don't try to start anything.
2851            return false;
2852        }
2853        Intent intent = getHomeIntent();
2854        ActivityInfo aInfo =
2855            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2856        if (aInfo != null) {
2857            intent.setComponent(new ComponentName(
2858                    aInfo.applicationInfo.packageName, aInfo.name));
2859            // Don't do this if the home app is currently being
2860            // instrumented.
2861            aInfo = new ActivityInfo(aInfo);
2862            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2863            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2864                    aInfo.applicationInfo.uid, true);
2865            if (app == null || app.instrumentationClass == null) {
2866                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2867                mStackSupervisor.startHomeActivity(intent, aInfo);
2868            }
2869        }
2870
2871        return true;
2872    }
2873
2874    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2875        ActivityInfo ai = null;
2876        ComponentName comp = intent.getComponent();
2877        try {
2878            if (comp != null) {
2879                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2880            } else {
2881                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2882                        intent,
2883                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2884                            flags, userId);
2885
2886                if (info != null) {
2887                    ai = info.activityInfo;
2888                }
2889            }
2890        } catch (RemoteException e) {
2891            // ignore
2892        }
2893
2894        return ai;
2895    }
2896
2897    /**
2898     * Starts the "new version setup screen" if appropriate.
2899     */
2900    void startSetupActivityLocked() {
2901        // Only do this once per boot.
2902        if (mCheckedForSetup) {
2903            return;
2904        }
2905
2906        // We will show this screen if the current one is a different
2907        // version than the last one shown, and we are not running in
2908        // low-level factory test mode.
2909        final ContentResolver resolver = mContext.getContentResolver();
2910        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2911                Settings.Global.getInt(resolver,
2912                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2913            mCheckedForSetup = true;
2914
2915            // See if we should be showing the platform update setup UI.
2916            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2917            List<ResolveInfo> ris = mContext.getPackageManager()
2918                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2919
2920            // We don't allow third party apps to replace this.
2921            ResolveInfo ri = null;
2922            for (int i=0; ris != null && i<ris.size(); i++) {
2923                if ((ris.get(i).activityInfo.applicationInfo.flags
2924                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2925                    ri = ris.get(i);
2926                    break;
2927                }
2928            }
2929
2930            if (ri != null) {
2931                String vers = ri.activityInfo.metaData != null
2932                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2933                        : null;
2934                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2935                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2936                            Intent.METADATA_SETUP_VERSION);
2937                }
2938                String lastVers = Settings.Secure.getString(
2939                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2940                if (vers != null && !vers.equals(lastVers)) {
2941                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2942                    intent.setComponent(new ComponentName(
2943                            ri.activityInfo.packageName, ri.activityInfo.name));
2944                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2945                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2946                }
2947            }
2948        }
2949    }
2950
2951    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2952        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2953    }
2954
2955    void enforceNotIsolatedCaller(String caller) {
2956        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2957            throw new SecurityException("Isolated process not allowed to call " + caller);
2958        }
2959    }
2960
2961    @Override
2962    public int getFrontActivityScreenCompatMode() {
2963        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2964        synchronized (this) {
2965            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2966        }
2967    }
2968
2969    @Override
2970    public void setFrontActivityScreenCompatMode(int mode) {
2971        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2972                "setFrontActivityScreenCompatMode");
2973        synchronized (this) {
2974            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2975        }
2976    }
2977
2978    @Override
2979    public int getPackageScreenCompatMode(String packageName) {
2980        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2981        synchronized (this) {
2982            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2983        }
2984    }
2985
2986    @Override
2987    public void setPackageScreenCompatMode(String packageName, int mode) {
2988        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2989                "setPackageScreenCompatMode");
2990        synchronized (this) {
2991            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2992        }
2993    }
2994
2995    @Override
2996    public boolean getPackageAskScreenCompat(String packageName) {
2997        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2998        synchronized (this) {
2999            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3000        }
3001    }
3002
3003    @Override
3004    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3005        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3006                "setPackageAskScreenCompat");
3007        synchronized (this) {
3008            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3009        }
3010    }
3011
3012    private void dispatchProcessesChanged() {
3013        int N;
3014        synchronized (this) {
3015            N = mPendingProcessChanges.size();
3016            if (mActiveProcessChanges.length < N) {
3017                mActiveProcessChanges = new ProcessChangeItem[N];
3018            }
3019            mPendingProcessChanges.toArray(mActiveProcessChanges);
3020            mAvailProcessChanges.addAll(mPendingProcessChanges);
3021            mPendingProcessChanges.clear();
3022            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3023        }
3024
3025        int i = mProcessObservers.beginBroadcast();
3026        while (i > 0) {
3027            i--;
3028            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3029            if (observer != null) {
3030                try {
3031                    for (int j=0; j<N; j++) {
3032                        ProcessChangeItem item = mActiveProcessChanges[j];
3033                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3034                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3035                                    + item.pid + " uid=" + item.uid + ": "
3036                                    + item.foregroundActivities);
3037                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3038                                    item.foregroundActivities);
3039                        }
3040                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3041                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3042                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3043                            observer.onImportanceChanged(item.pid, item.uid,
3044                                    item.importance);
3045                        }
3046                    }
3047                } catch (RemoteException e) {
3048                }
3049            }
3050        }
3051        mProcessObservers.finishBroadcast();
3052    }
3053
3054    private void dispatchProcessDied(int pid, int uid) {
3055        int i = mProcessObservers.beginBroadcast();
3056        while (i > 0) {
3057            i--;
3058            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3059            if (observer != null) {
3060                try {
3061                    observer.onProcessDied(pid, uid);
3062                } catch (RemoteException e) {
3063                }
3064            }
3065        }
3066        mProcessObservers.finishBroadcast();
3067    }
3068
3069    final void doPendingActivityLaunchesLocked(boolean doResume) {
3070        final int N = mPendingActivityLaunches.size();
3071        if (N <= 0) {
3072            return;
3073        }
3074        for (int i=0; i<N; i++) {
3075            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3076            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3077                    doResume && i == (N-1), null);
3078        }
3079        mPendingActivityLaunches.clear();
3080    }
3081
3082    @Override
3083    public final int startActivity(IApplicationThread caller, String callingPackage,
3084            Intent intent, String resolvedType, IBinder resultTo,
3085            String resultWho, int requestCode, int startFlags,
3086            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3087        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3088                resultWho, requestCode,
3089                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3090    }
3091
3092    @Override
3093    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3094            Intent intent, String resolvedType, IBinder resultTo,
3095            String resultWho, int requestCode, int startFlags,
3096            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3097        enforceNotIsolatedCaller("startActivity");
3098        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3099                false, true, "startActivity", null);
3100        // TODO: Switch to user app stacks here.
3101        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3102                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3103                null, null, options, userId, null);
3104    }
3105
3106    @Override
3107    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3108            Intent intent, String resolvedType, IBinder resultTo,
3109            String resultWho, int requestCode, int startFlags, String profileFile,
3110            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3111        enforceNotIsolatedCaller("startActivityAndWait");
3112        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3113                false, true, "startActivityAndWait", null);
3114        WaitResult res = new WaitResult();
3115        // TODO: Switch to user app stacks here.
3116        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3117                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3118                res, null, options, UserHandle.getCallingUserId(), null);
3119        return res;
3120    }
3121
3122    @Override
3123    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3124            Intent intent, String resolvedType, IBinder resultTo,
3125            String resultWho, int requestCode, int startFlags, Configuration config,
3126            Bundle options, int userId) {
3127        enforceNotIsolatedCaller("startActivityWithConfig");
3128        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3129                false, true, "startActivityWithConfig", null);
3130        // TODO: Switch to user app stacks here.
3131        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3132                resolvedType, resultTo, resultWho, requestCode, startFlags,
3133                null, null, null, config, options, userId, null);
3134        return ret;
3135    }
3136
3137    @Override
3138    public int startActivityIntentSender(IApplicationThread caller,
3139            IntentSender intent, Intent fillInIntent, String resolvedType,
3140            IBinder resultTo, String resultWho, int requestCode,
3141            int flagsMask, int flagsValues, Bundle options) {
3142        enforceNotIsolatedCaller("startActivityIntentSender");
3143        // Refuse possible leaked file descriptors
3144        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3145            throw new IllegalArgumentException("File descriptors passed in Intent");
3146        }
3147
3148        IIntentSender sender = intent.getTarget();
3149        if (!(sender instanceof PendingIntentRecord)) {
3150            throw new IllegalArgumentException("Bad PendingIntent object");
3151        }
3152
3153        PendingIntentRecord pir = (PendingIntentRecord)sender;
3154
3155        synchronized (this) {
3156            // If this is coming from the currently resumed activity, it is
3157            // effectively saying that app switches are allowed at this point.
3158            final ActivityStack stack = getFocusedStack();
3159            if (stack.mResumedActivity != null &&
3160                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3161                mAppSwitchesAllowedTime = 0;
3162            }
3163        }
3164        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3165                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3166        return ret;
3167    }
3168
3169    @Override
3170    public boolean startNextMatchingActivity(IBinder callingActivity,
3171            Intent intent, Bundle options) {
3172        // Refuse possible leaked file descriptors
3173        if (intent != null && intent.hasFileDescriptors() == true) {
3174            throw new IllegalArgumentException("File descriptors passed in Intent");
3175        }
3176
3177        synchronized (this) {
3178            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3179            if (r == null) {
3180                ActivityOptions.abort(options);
3181                return false;
3182            }
3183            if (r.app == null || r.app.thread == null) {
3184                // The caller is not running...  d'oh!
3185                ActivityOptions.abort(options);
3186                return false;
3187            }
3188            intent = new Intent(intent);
3189            // The caller is not allowed to change the data.
3190            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3191            // And we are resetting to find the next component...
3192            intent.setComponent(null);
3193
3194            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3195
3196            ActivityInfo aInfo = null;
3197            try {
3198                List<ResolveInfo> resolves =
3199                    AppGlobals.getPackageManager().queryIntentActivities(
3200                            intent, r.resolvedType,
3201                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3202                            UserHandle.getCallingUserId());
3203
3204                // Look for the original activity in the list...
3205                final int N = resolves != null ? resolves.size() : 0;
3206                for (int i=0; i<N; i++) {
3207                    ResolveInfo rInfo = resolves.get(i);
3208                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3209                            && rInfo.activityInfo.name.equals(r.info.name)) {
3210                        // We found the current one...  the next matching is
3211                        // after it.
3212                        i++;
3213                        if (i<N) {
3214                            aInfo = resolves.get(i).activityInfo;
3215                        }
3216                        if (debug) {
3217                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3218                                    + "/" + r.info.name);
3219                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3220                                    + "/" + aInfo.name);
3221                        }
3222                        break;
3223                    }
3224                }
3225            } catch (RemoteException e) {
3226            }
3227
3228            if (aInfo == null) {
3229                // Nobody who is next!
3230                ActivityOptions.abort(options);
3231                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3232                return false;
3233            }
3234
3235            intent.setComponent(new ComponentName(
3236                    aInfo.applicationInfo.packageName, aInfo.name));
3237            intent.setFlags(intent.getFlags()&~(
3238                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3239                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3240                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3241                    Intent.FLAG_ACTIVITY_NEW_TASK));
3242
3243            // Okay now we need to start the new activity, replacing the
3244            // currently running activity.  This is a little tricky because
3245            // we want to start the new one as if the current one is finished,
3246            // but not finish the current one first so that there is no flicker.
3247            // And thus...
3248            final boolean wasFinishing = r.finishing;
3249            r.finishing = true;
3250
3251            // Propagate reply information over to the new activity.
3252            final ActivityRecord resultTo = r.resultTo;
3253            final String resultWho = r.resultWho;
3254            final int requestCode = r.requestCode;
3255            r.resultTo = null;
3256            if (resultTo != null) {
3257                resultTo.removeResultsLocked(r, resultWho, requestCode);
3258            }
3259
3260            final long origId = Binder.clearCallingIdentity();
3261            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3262                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3263                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3264                    options, false, null, null);
3265            Binder.restoreCallingIdentity(origId);
3266
3267            r.finishing = wasFinishing;
3268            if (res != ActivityManager.START_SUCCESS) {
3269                return false;
3270            }
3271            return true;
3272        }
3273    }
3274
3275    final int startActivityInPackage(int uid, String callingPackage,
3276            Intent intent, String resolvedType, IBinder resultTo,
3277            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3278                    IActivityContainer container) {
3279
3280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3281                false, true, "startActivityInPackage", null);
3282
3283        // TODO: Switch to user app stacks here.
3284        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3285                resultTo, resultWho, requestCode, startFlags,
3286                null, null, null, null, options, userId, container);
3287        return ret;
3288    }
3289
3290    @Override
3291    public final int startActivities(IApplicationThread caller, String callingPackage,
3292            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3293            int userId) {
3294        enforceNotIsolatedCaller("startActivities");
3295        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3296                false, true, "startActivity", null);
3297        // TODO: Switch to user app stacks here.
3298        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3299                resolvedTypes, resultTo, options, userId);
3300        return ret;
3301    }
3302
3303    final int startActivitiesInPackage(int uid, String callingPackage,
3304            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3305            Bundle options, int userId) {
3306
3307        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3308                false, true, "startActivityInPackage", null);
3309        // TODO: Switch to user app stacks here.
3310        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3311                resultTo, options, userId);
3312        return ret;
3313    }
3314
3315    final void addRecentTaskLocked(TaskRecord task) {
3316        int N = mRecentTasks.size();
3317        // Quick case: check if the top-most recent task is the same.
3318        if (N > 0 && mRecentTasks.get(0) == task) {
3319            return;
3320        }
3321        // Remove any existing entries that are the same kind of task.
3322        final Intent intent = task.intent;
3323        final boolean document = intent != null && intent.isDocument();
3324        for (int i=0; i<N; i++) {
3325            TaskRecord tr = mRecentTasks.get(i);
3326            if (task != tr) {
3327                if (task.userId != tr.userId) {
3328                    continue;
3329                }
3330                final Intent trIntent = tr.intent;
3331                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3332                    (intent == null || !intent.filterEquals(trIntent))) {
3333                    continue;
3334                }
3335                if (document || trIntent != null && trIntent.isDocument()) {
3336                    // Document tasks do not match other tasks.
3337                    continue;
3338                }
3339            }
3340
3341            // Either task and tr are the same or, their affinities match or their intents match
3342            // and neither of them is a document.
3343            tr.disposeThumbnail();
3344            mRecentTasks.remove(i);
3345            i--;
3346            N--;
3347            if (task.intent == null) {
3348                // If the new recent task we are adding is not fully
3349                // specified, then replace it with the existing recent task.
3350                task = tr;
3351            }
3352        }
3353        if (N >= MAX_RECENT_TASKS) {
3354            mRecentTasks.remove(N-1).disposeThumbnail();
3355        }
3356        mRecentTasks.add(0, task);
3357    }
3358
3359    @Override
3360    public void reportActivityFullyDrawn(IBinder token) {
3361        synchronized (this) {
3362            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3363            if (r == null) {
3364                return;
3365            }
3366            r.reportFullyDrawnLocked();
3367        }
3368    }
3369
3370    @Override
3371    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3372        synchronized (this) {
3373            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3374            if (r == null) {
3375                return;
3376            }
3377            final long origId = Binder.clearCallingIdentity();
3378            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3379            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3380                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3381            if (config != null) {
3382                r.frozenBeforeDestroy = true;
3383                if (!updateConfigurationLocked(config, r, false, false)) {
3384                    mStackSupervisor.resumeTopActivitiesLocked();
3385                }
3386            }
3387            Binder.restoreCallingIdentity(origId);
3388        }
3389    }
3390
3391    @Override
3392    public int getRequestedOrientation(IBinder token) {
3393        synchronized (this) {
3394            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3395            if (r == null) {
3396                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3397            }
3398            return mWindowManager.getAppOrientation(r.appToken);
3399        }
3400    }
3401
3402    /**
3403     * This is the internal entry point for handling Activity.finish().
3404     *
3405     * @param token The Binder token referencing the Activity we want to finish.
3406     * @param resultCode Result code, if any, from this Activity.
3407     * @param resultData Result data (Intent), if any, from this Activity.
3408     *
3409     * @return Returns true if the activity successfully finished, or false if it is still running.
3410     */
3411    @Override
3412    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3413        // Refuse possible leaked file descriptors
3414        if (resultData != null && resultData.hasFileDescriptors() == true) {
3415            throw new IllegalArgumentException("File descriptors passed in Intent");
3416        }
3417
3418        synchronized(this) {
3419            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3420            if (r == null) {
3421                return true;
3422            }
3423            if (mController != null) {
3424                // Find the first activity that is not finishing.
3425                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3426                if (next != null) {
3427                    // ask watcher if this is allowed
3428                    boolean resumeOK = true;
3429                    try {
3430                        resumeOK = mController.activityResuming(next.packageName);
3431                    } catch (RemoteException e) {
3432                        mController = null;
3433                        Watchdog.getInstance().setActivityController(null);
3434                    }
3435
3436                    if (!resumeOK) {
3437                        return false;
3438                    }
3439                }
3440            }
3441            final long origId = Binder.clearCallingIdentity();
3442            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3443                    resultData, "app-request", true);
3444            Binder.restoreCallingIdentity(origId);
3445            return res;
3446        }
3447    }
3448
3449    @Override
3450    public final void finishHeavyWeightApp() {
3451        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3452                != PackageManager.PERMISSION_GRANTED) {
3453            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3454                    + Binder.getCallingPid()
3455                    + ", uid=" + Binder.getCallingUid()
3456                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3457            Slog.w(TAG, msg);
3458            throw new SecurityException(msg);
3459        }
3460
3461        synchronized(this) {
3462            if (mHeavyWeightProcess == null) {
3463                return;
3464            }
3465
3466            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3467                    mHeavyWeightProcess.activities);
3468            for (int i=0; i<activities.size(); i++) {
3469                ActivityRecord r = activities.get(i);
3470                if (!r.finishing) {
3471                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3472                            null, "finish-heavy", true);
3473                }
3474            }
3475
3476            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3477                    mHeavyWeightProcess.userId, 0));
3478            mHeavyWeightProcess = null;
3479        }
3480    }
3481
3482    @Override
3483    public void crashApplication(int uid, int initialPid, String packageName,
3484            String message) {
3485        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3486                != PackageManager.PERMISSION_GRANTED) {
3487            String msg = "Permission Denial: crashApplication() from pid="
3488                    + Binder.getCallingPid()
3489                    + ", uid=" + Binder.getCallingUid()
3490                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3491            Slog.w(TAG, msg);
3492            throw new SecurityException(msg);
3493        }
3494
3495        synchronized(this) {
3496            ProcessRecord proc = null;
3497
3498            // Figure out which process to kill.  We don't trust that initialPid
3499            // still has any relation to current pids, so must scan through the
3500            // list.
3501            synchronized (mPidsSelfLocked) {
3502                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3503                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3504                    if (p.uid != uid) {
3505                        continue;
3506                    }
3507                    if (p.pid == initialPid) {
3508                        proc = p;
3509                        break;
3510                    }
3511                    if (p.pkgList.containsKey(packageName)) {
3512                        proc = p;
3513                    }
3514                }
3515            }
3516
3517            if (proc == null) {
3518                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3519                        + " initialPid=" + initialPid
3520                        + " packageName=" + packageName);
3521                return;
3522            }
3523
3524            if (proc.thread != null) {
3525                if (proc.pid == Process.myPid()) {
3526                    Log.w(TAG, "crashApplication: trying to crash self!");
3527                    return;
3528                }
3529                long ident = Binder.clearCallingIdentity();
3530                try {
3531                    proc.thread.scheduleCrash(message);
3532                } catch (RemoteException e) {
3533                }
3534                Binder.restoreCallingIdentity(ident);
3535            }
3536        }
3537    }
3538
3539    @Override
3540    public final void finishSubActivity(IBinder token, String resultWho,
3541            int requestCode) {
3542        synchronized(this) {
3543            final long origId = Binder.clearCallingIdentity();
3544            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3545            if (r != null) {
3546                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3547            }
3548            Binder.restoreCallingIdentity(origId);
3549        }
3550    }
3551
3552    @Override
3553    public boolean finishActivityAffinity(IBinder token) {
3554        synchronized(this) {
3555            final long origId = Binder.clearCallingIdentity();
3556            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3557            boolean res = false;
3558            if (r != null) {
3559                res = r.task.stack.finishActivityAffinityLocked(r);
3560            }
3561            Binder.restoreCallingIdentity(origId);
3562            return res;
3563        }
3564    }
3565
3566    @Override
3567    public boolean willActivityBeVisible(IBinder token) {
3568        synchronized(this) {
3569            ActivityStack stack = ActivityRecord.getStackLocked(token);
3570            if (stack != null) {
3571                return stack.willActivityBeVisibleLocked(token);
3572            }
3573            return false;
3574        }
3575    }
3576
3577    @Override
3578    public void overridePendingTransition(IBinder token, String packageName,
3579            int enterAnim, int exitAnim) {
3580        synchronized(this) {
3581            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3582            if (self == null) {
3583                return;
3584            }
3585
3586            final long origId = Binder.clearCallingIdentity();
3587
3588            if (self.state == ActivityState.RESUMED
3589                    || self.state == ActivityState.PAUSING) {
3590                mWindowManager.overridePendingAppTransition(packageName,
3591                        enterAnim, exitAnim, null);
3592            }
3593
3594            Binder.restoreCallingIdentity(origId);
3595        }
3596    }
3597
3598    /**
3599     * Main function for removing an existing process from the activity manager
3600     * as a result of that process going away.  Clears out all connections
3601     * to the process.
3602     */
3603    private final void handleAppDiedLocked(ProcessRecord app,
3604            boolean restarting, boolean allowRestart) {
3605        int pid = app.pid;
3606        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3607        if (!restarting) {
3608            removeLruProcessLocked(app);
3609            if (pid > 0) {
3610                ProcessList.remove(pid);
3611            }
3612        }
3613
3614        if (mProfileProc == app) {
3615            clearProfilerLocked();
3616        }
3617
3618        // Remove this application's activities from active lists.
3619        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3620
3621        app.activities.clear();
3622
3623        if (app.instrumentationClass != null) {
3624            Slog.w(TAG, "Crash of app " + app.processName
3625                  + " running instrumentation " + app.instrumentationClass);
3626            Bundle info = new Bundle();
3627            info.putString("shortMsg", "Process crashed.");
3628            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3629        }
3630
3631        if (!restarting) {
3632            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3633                // If there was nothing to resume, and we are not already
3634                // restarting this process, but there is a visible activity that
3635                // is hosted by the process...  then make sure all visible
3636                // activities are running, taking care of restarting this
3637                // process.
3638                if (hasVisibleActivities) {
3639                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3640                }
3641            }
3642        }
3643    }
3644
3645    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3646        IBinder threadBinder = thread.asBinder();
3647        // Find the application record.
3648        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3649            ProcessRecord rec = mLruProcesses.get(i);
3650            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3651                return i;
3652            }
3653        }
3654        return -1;
3655    }
3656
3657    final ProcessRecord getRecordForAppLocked(
3658            IApplicationThread thread) {
3659        if (thread == null) {
3660            return null;
3661        }
3662
3663        int appIndex = getLRURecordIndexForAppLocked(thread);
3664        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3665    }
3666
3667    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3668        // If there are no longer any background processes running,
3669        // and the app that died was not running instrumentation,
3670        // then tell everyone we are now low on memory.
3671        boolean haveBg = false;
3672        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3673            ProcessRecord rec = mLruProcesses.get(i);
3674            if (rec.thread != null
3675                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3676                haveBg = true;
3677                break;
3678            }
3679        }
3680
3681        if (!haveBg) {
3682            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3683            if (doReport) {
3684                long now = SystemClock.uptimeMillis();
3685                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3686                    doReport = false;
3687                } else {
3688                    mLastMemUsageReportTime = now;
3689                }
3690            }
3691            final ArrayList<ProcessMemInfo> memInfos
3692                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3693            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3694            long now = SystemClock.uptimeMillis();
3695            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3696                ProcessRecord rec = mLruProcesses.get(i);
3697                if (rec == dyingProc || rec.thread == null) {
3698                    continue;
3699                }
3700                if (doReport) {
3701                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3702                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3703                }
3704                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3705                    // The low memory report is overriding any current
3706                    // state for a GC request.  Make sure to do
3707                    // heavy/important/visible/foreground processes first.
3708                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3709                        rec.lastRequestedGc = 0;
3710                    } else {
3711                        rec.lastRequestedGc = rec.lastLowMemory;
3712                    }
3713                    rec.reportLowMemory = true;
3714                    rec.lastLowMemory = now;
3715                    mProcessesToGc.remove(rec);
3716                    addProcessToGcListLocked(rec);
3717                }
3718            }
3719            if (doReport) {
3720                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3721                mHandler.sendMessage(msg);
3722            }
3723            scheduleAppGcsLocked();
3724        }
3725    }
3726
3727    final void appDiedLocked(ProcessRecord app, int pid,
3728            IApplicationThread thread) {
3729
3730        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3731        synchronized (stats) {
3732            stats.noteProcessDiedLocked(app.info.uid, pid);
3733        }
3734
3735        // Clean up already done if the process has been re-started.
3736        if (app.pid == pid && app.thread != null &&
3737                app.thread.asBinder() == thread.asBinder()) {
3738            boolean doLowMem = app.instrumentationClass == null;
3739            boolean doOomAdj = doLowMem;
3740            if (!app.killedByAm) {
3741                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3742                        + ") has died.");
3743                mAllowLowerMemLevel = true;
3744            } else {
3745                // Note that we always want to do oom adj to update our state with the
3746                // new number of procs.
3747                mAllowLowerMemLevel = false;
3748                doLowMem = false;
3749            }
3750            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3751            if (DEBUG_CLEANUP) Slog.v(
3752                TAG, "Dying app: " + app + ", pid: " + pid
3753                + ", thread: " + thread.asBinder());
3754            handleAppDiedLocked(app, false, true);
3755
3756            if (doOomAdj) {
3757                updateOomAdjLocked();
3758            }
3759            if (doLowMem) {
3760                doLowMemReportIfNeededLocked(app);
3761            }
3762        } else if (app.pid != pid) {
3763            // A new process has already been started.
3764            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3765                    + ") has died and restarted (pid " + app.pid + ").");
3766            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3767        } else if (DEBUG_PROCESSES) {
3768            Slog.d(TAG, "Received spurious death notification for thread "
3769                    + thread.asBinder());
3770        }
3771    }
3772
3773    /**
3774     * If a stack trace dump file is configured, dump process stack traces.
3775     * @param clearTraces causes the dump file to be erased prior to the new
3776     *    traces being written, if true; when false, the new traces will be
3777     *    appended to any existing file content.
3778     * @param firstPids of dalvik VM processes to dump stack traces for first
3779     * @param lastPids of dalvik VM processes to dump stack traces for last
3780     * @param nativeProcs optional list of native process names to dump stack crawls
3781     * @return file containing stack traces, or null if no dump file is configured
3782     */
3783    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3784            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3785        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3786        if (tracesPath == null || tracesPath.length() == 0) {
3787            return null;
3788        }
3789
3790        File tracesFile = new File(tracesPath);
3791        try {
3792            File tracesDir = tracesFile.getParentFile();
3793            if (!tracesDir.exists()) {
3794                tracesFile.mkdirs();
3795                if (!SELinux.restorecon(tracesDir)) {
3796                    return null;
3797                }
3798            }
3799            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3800
3801            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3802            tracesFile.createNewFile();
3803            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3804        } catch (IOException e) {
3805            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3806            return null;
3807        }
3808
3809        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3810        return tracesFile;
3811    }
3812
3813    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3814            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3815        // Use a FileObserver to detect when traces finish writing.
3816        // The order of traces is considered important to maintain for legibility.
3817        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3818            @Override
3819            public synchronized void onEvent(int event, String path) { notify(); }
3820        };
3821
3822        try {
3823            observer.startWatching();
3824
3825            // First collect all of the stacks of the most important pids.
3826            if (firstPids != null) {
3827                try {
3828                    int num = firstPids.size();
3829                    for (int i = 0; i < num; i++) {
3830                        synchronized (observer) {
3831                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3832                            observer.wait(200);  // Wait for write-close, give up after 200msec
3833                        }
3834                    }
3835                } catch (InterruptedException e) {
3836                    Log.wtf(TAG, e);
3837                }
3838            }
3839
3840            // Next collect the stacks of the native pids
3841            if (nativeProcs != null) {
3842                int[] pids = Process.getPidsForCommands(nativeProcs);
3843                if (pids != null) {
3844                    for (int pid : pids) {
3845                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3846                    }
3847                }
3848            }
3849
3850            // Lastly, measure CPU usage.
3851            if (processCpuTracker != null) {
3852                processCpuTracker.init();
3853                System.gc();
3854                processCpuTracker.update();
3855                try {
3856                    synchronized (processCpuTracker) {
3857                        processCpuTracker.wait(500); // measure over 1/2 second.
3858                    }
3859                } catch (InterruptedException e) {
3860                }
3861                processCpuTracker.update();
3862
3863                // We'll take the stack crawls of just the top apps using CPU.
3864                final int N = processCpuTracker.countWorkingStats();
3865                int numProcs = 0;
3866                for (int i=0; i<N && numProcs<5; i++) {
3867                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3868                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3869                        numProcs++;
3870                        try {
3871                            synchronized (observer) {
3872                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3873                                observer.wait(200);  // Wait for write-close, give up after 200msec
3874                            }
3875                        } catch (InterruptedException e) {
3876                            Log.wtf(TAG, e);
3877                        }
3878
3879                    }
3880                }
3881            }
3882        } finally {
3883            observer.stopWatching();
3884        }
3885    }
3886
3887    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3888        if (true || IS_USER_BUILD) {
3889            return;
3890        }
3891        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3892        if (tracesPath == null || tracesPath.length() == 0) {
3893            return;
3894        }
3895
3896        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3897        StrictMode.allowThreadDiskWrites();
3898        try {
3899            final File tracesFile = new File(tracesPath);
3900            final File tracesDir = tracesFile.getParentFile();
3901            final File tracesTmp = new File(tracesDir, "__tmp__");
3902            try {
3903                if (!tracesDir.exists()) {
3904                    tracesFile.mkdirs();
3905                    if (!SELinux.restorecon(tracesDir.getPath())) {
3906                        return;
3907                    }
3908                }
3909                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3910
3911                if (tracesFile.exists()) {
3912                    tracesTmp.delete();
3913                    tracesFile.renameTo(tracesTmp);
3914                }
3915                StringBuilder sb = new StringBuilder();
3916                Time tobj = new Time();
3917                tobj.set(System.currentTimeMillis());
3918                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3919                sb.append(": ");
3920                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3921                sb.append(" since ");
3922                sb.append(msg);
3923                FileOutputStream fos = new FileOutputStream(tracesFile);
3924                fos.write(sb.toString().getBytes());
3925                if (app == null) {
3926                    fos.write("\n*** No application process!".getBytes());
3927                }
3928                fos.close();
3929                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3930            } catch (IOException e) {
3931                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3932                return;
3933            }
3934
3935            if (app != null) {
3936                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3937                firstPids.add(app.pid);
3938                dumpStackTraces(tracesPath, firstPids, null, null, null);
3939            }
3940
3941            File lastTracesFile = null;
3942            File curTracesFile = null;
3943            for (int i=9; i>=0; i--) {
3944                String name = String.format(Locale.US, "slow%02d.txt", i);
3945                curTracesFile = new File(tracesDir, name);
3946                if (curTracesFile.exists()) {
3947                    if (lastTracesFile != null) {
3948                        curTracesFile.renameTo(lastTracesFile);
3949                    } else {
3950                        curTracesFile.delete();
3951                    }
3952                }
3953                lastTracesFile = curTracesFile;
3954            }
3955            tracesFile.renameTo(curTracesFile);
3956            if (tracesTmp.exists()) {
3957                tracesTmp.renameTo(tracesFile);
3958            }
3959        } finally {
3960            StrictMode.setThreadPolicy(oldPolicy);
3961        }
3962    }
3963
3964    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3965            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3966        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3967        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3968
3969        if (mController != null) {
3970            try {
3971                // 0 == continue, -1 = kill process immediately
3972                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3973                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3974            } catch (RemoteException e) {
3975                mController = null;
3976                Watchdog.getInstance().setActivityController(null);
3977            }
3978        }
3979
3980        long anrTime = SystemClock.uptimeMillis();
3981        if (MONITOR_CPU_USAGE) {
3982            updateCpuStatsNow();
3983        }
3984
3985        synchronized (this) {
3986            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3987            if (mShuttingDown) {
3988                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3989                return;
3990            } else if (app.notResponding) {
3991                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3992                return;
3993            } else if (app.crashing) {
3994                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3995                return;
3996            }
3997
3998            // In case we come through here for the same app before completing
3999            // this one, mark as anring now so we will bail out.
4000            app.notResponding = true;
4001
4002            // Log the ANR to the event log.
4003            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4004                    app.processName, app.info.flags, annotation);
4005
4006            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4007            firstPids.add(app.pid);
4008
4009            int parentPid = app.pid;
4010            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4011            if (parentPid != app.pid) firstPids.add(parentPid);
4012
4013            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4014
4015            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4016                ProcessRecord r = mLruProcesses.get(i);
4017                if (r != null && r.thread != null) {
4018                    int pid = r.pid;
4019                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4020                        if (r.persistent) {
4021                            firstPids.add(pid);
4022                        } else {
4023                            lastPids.put(pid, Boolean.TRUE);
4024                        }
4025                    }
4026                }
4027            }
4028        }
4029
4030        // Log the ANR to the main log.
4031        StringBuilder info = new StringBuilder();
4032        info.setLength(0);
4033        info.append("ANR in ").append(app.processName);
4034        if (activity != null && activity.shortComponentName != null) {
4035            info.append(" (").append(activity.shortComponentName).append(")");
4036        }
4037        info.append("\n");
4038        info.append("PID: ").append(app.pid).append("\n");
4039        if (annotation != null) {
4040            info.append("Reason: ").append(annotation).append("\n");
4041        }
4042        if (parent != null && parent != activity) {
4043            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4044        }
4045
4046        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4047
4048        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4049                NATIVE_STACKS_OF_INTEREST);
4050
4051        String cpuInfo = null;
4052        if (MONITOR_CPU_USAGE) {
4053            updateCpuStatsNow();
4054            synchronized (mProcessCpuThread) {
4055                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4056            }
4057            info.append(processCpuTracker.printCurrentLoad());
4058            info.append(cpuInfo);
4059        }
4060
4061        info.append(processCpuTracker.printCurrentState(anrTime));
4062
4063        Slog.e(TAG, info.toString());
4064        if (tracesFile == null) {
4065            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4066            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4067        }
4068
4069        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4070                cpuInfo, tracesFile, null);
4071
4072        if (mController != null) {
4073            try {
4074                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4075                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4076                if (res != 0) {
4077                    if (res < 0 && app.pid != MY_PID) {
4078                        Process.killProcess(app.pid);
4079                    } else {
4080                        synchronized (this) {
4081                            mServices.scheduleServiceTimeoutLocked(app);
4082                        }
4083                    }
4084                    return;
4085                }
4086            } catch (RemoteException e) {
4087                mController = null;
4088                Watchdog.getInstance().setActivityController(null);
4089            }
4090        }
4091
4092        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4093        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4094                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4095
4096        synchronized (this) {
4097            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4098                killUnneededProcessLocked(app, "background ANR");
4099                return;
4100            }
4101
4102            // Set the app's notResponding state, and look up the errorReportReceiver
4103            makeAppNotRespondingLocked(app,
4104                    activity != null ? activity.shortComponentName : null,
4105                    annotation != null ? "ANR " + annotation : "ANR",
4106                    info.toString());
4107
4108            // Bring up the infamous App Not Responding dialog
4109            Message msg = Message.obtain();
4110            HashMap<String, Object> map = new HashMap<String, Object>();
4111            msg.what = SHOW_NOT_RESPONDING_MSG;
4112            msg.obj = map;
4113            msg.arg1 = aboveSystem ? 1 : 0;
4114            map.put("app", app);
4115            if (activity != null) {
4116                map.put("activity", activity);
4117            }
4118
4119            mHandler.sendMessage(msg);
4120        }
4121    }
4122
4123    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4124        if (!mLaunchWarningShown) {
4125            mLaunchWarningShown = true;
4126            mHandler.post(new Runnable() {
4127                @Override
4128                public void run() {
4129                    synchronized (ActivityManagerService.this) {
4130                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4131                        d.show();
4132                        mHandler.postDelayed(new Runnable() {
4133                            @Override
4134                            public void run() {
4135                                synchronized (ActivityManagerService.this) {
4136                                    d.dismiss();
4137                                    mLaunchWarningShown = false;
4138                                }
4139                            }
4140                        }, 4000);
4141                    }
4142                }
4143            });
4144        }
4145    }
4146
4147    @Override
4148    public boolean clearApplicationUserData(final String packageName,
4149            final IPackageDataObserver observer, int userId) {
4150        enforceNotIsolatedCaller("clearApplicationUserData");
4151        int uid = Binder.getCallingUid();
4152        int pid = Binder.getCallingPid();
4153        userId = handleIncomingUser(pid, uid,
4154                userId, false, true, "clearApplicationUserData", null);
4155        long callingId = Binder.clearCallingIdentity();
4156        try {
4157            IPackageManager pm = AppGlobals.getPackageManager();
4158            int pkgUid = -1;
4159            synchronized(this) {
4160                try {
4161                    pkgUid = pm.getPackageUid(packageName, userId);
4162                } catch (RemoteException e) {
4163                }
4164                if (pkgUid == -1) {
4165                    Slog.w(TAG, "Invalid packageName: " + packageName);
4166                    if (observer != null) {
4167                        try {
4168                            observer.onRemoveCompleted(packageName, false);
4169                        } catch (RemoteException e) {
4170                            Slog.i(TAG, "Observer no longer exists.");
4171                        }
4172                    }
4173                    return false;
4174                }
4175                if (uid == pkgUid || checkComponentPermission(
4176                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4177                        pid, uid, -1, true)
4178                        == PackageManager.PERMISSION_GRANTED) {
4179                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4180                } else {
4181                    throw new SecurityException("PID " + pid + " does not have permission "
4182                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4183                                    + " of package " + packageName);
4184                }
4185            }
4186
4187            try {
4188                // Clear application user data
4189                pm.clearApplicationUserData(packageName, observer, userId);
4190
4191                // Remove all permissions granted from/to this package
4192                removeUriPermissionsForPackageLocked(packageName, userId, true);
4193
4194                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4195                        Uri.fromParts("package", packageName, null));
4196                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4197                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4198                        null, null, 0, null, null, null, false, false, userId);
4199            } catch (RemoteException e) {
4200            }
4201        } finally {
4202            Binder.restoreCallingIdentity(callingId);
4203        }
4204        return true;
4205    }
4206
4207    @Override
4208    public void killBackgroundProcesses(final String packageName, int userId) {
4209        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4210                != PackageManager.PERMISSION_GRANTED &&
4211                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4212                        != PackageManager.PERMISSION_GRANTED) {
4213            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4214                    + Binder.getCallingPid()
4215                    + ", uid=" + Binder.getCallingUid()
4216                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4217            Slog.w(TAG, msg);
4218            throw new SecurityException(msg);
4219        }
4220
4221        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4222                userId, true, true, "killBackgroundProcesses", null);
4223        long callingId = Binder.clearCallingIdentity();
4224        try {
4225            IPackageManager pm = AppGlobals.getPackageManager();
4226            synchronized(this) {
4227                int appId = -1;
4228                try {
4229                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4230                } catch (RemoteException e) {
4231                }
4232                if (appId == -1) {
4233                    Slog.w(TAG, "Invalid packageName: " + packageName);
4234                    return;
4235                }
4236                killPackageProcessesLocked(packageName, appId, userId,
4237                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4238            }
4239        } finally {
4240            Binder.restoreCallingIdentity(callingId);
4241        }
4242    }
4243
4244    @Override
4245    public void killAllBackgroundProcesses() {
4246        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4247                != PackageManager.PERMISSION_GRANTED) {
4248            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4249                    + Binder.getCallingPid()
4250                    + ", uid=" + Binder.getCallingUid()
4251                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4252            Slog.w(TAG, msg);
4253            throw new SecurityException(msg);
4254        }
4255
4256        long callingId = Binder.clearCallingIdentity();
4257        try {
4258            synchronized(this) {
4259                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4260                final int NP = mProcessNames.getMap().size();
4261                for (int ip=0; ip<NP; ip++) {
4262                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4263                    final int NA = apps.size();
4264                    for (int ia=0; ia<NA; ia++) {
4265                        ProcessRecord app = apps.valueAt(ia);
4266                        if (app.persistent) {
4267                            // we don't kill persistent processes
4268                            continue;
4269                        }
4270                        if (app.removed) {
4271                            procs.add(app);
4272                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4273                            app.removed = true;
4274                            procs.add(app);
4275                        }
4276                    }
4277                }
4278
4279                int N = procs.size();
4280                for (int i=0; i<N; i++) {
4281                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4282                }
4283                mAllowLowerMemLevel = true;
4284                updateOomAdjLocked();
4285                doLowMemReportIfNeededLocked(null);
4286            }
4287        } finally {
4288            Binder.restoreCallingIdentity(callingId);
4289        }
4290    }
4291
4292    @Override
4293    public void forceStopPackage(final String packageName, int userId) {
4294        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4295                != PackageManager.PERMISSION_GRANTED) {
4296            String msg = "Permission Denial: forceStopPackage() from pid="
4297                    + Binder.getCallingPid()
4298                    + ", uid=" + Binder.getCallingUid()
4299                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4300            Slog.w(TAG, msg);
4301            throw new SecurityException(msg);
4302        }
4303        final int callingPid = Binder.getCallingPid();
4304        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4305                userId, true, true, "forceStopPackage", null);
4306        long callingId = Binder.clearCallingIdentity();
4307        try {
4308            IPackageManager pm = AppGlobals.getPackageManager();
4309            synchronized(this) {
4310                int[] users = userId == UserHandle.USER_ALL
4311                        ? getUsersLocked() : new int[] { userId };
4312                for (int user : users) {
4313                    int pkgUid = -1;
4314                    try {
4315                        pkgUid = pm.getPackageUid(packageName, user);
4316                    } catch (RemoteException e) {
4317                    }
4318                    if (pkgUid == -1) {
4319                        Slog.w(TAG, "Invalid packageName: " + packageName);
4320                        continue;
4321                    }
4322                    try {
4323                        pm.setPackageStoppedState(packageName, true, user);
4324                    } catch (RemoteException e) {
4325                    } catch (IllegalArgumentException e) {
4326                        Slog.w(TAG, "Failed trying to unstop package "
4327                                + packageName + ": " + e);
4328                    }
4329                    if (isUserRunningLocked(user, false)) {
4330                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4331                    }
4332                }
4333            }
4334        } finally {
4335            Binder.restoreCallingIdentity(callingId);
4336        }
4337    }
4338
4339    /*
4340     * The pkg name and app id have to be specified.
4341     */
4342    @Override
4343    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4344        if (pkg == null) {
4345            return;
4346        }
4347        // Make sure the uid is valid.
4348        if (appid < 0) {
4349            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4350            return;
4351        }
4352        int callerUid = Binder.getCallingUid();
4353        // Only the system server can kill an application
4354        if (callerUid == Process.SYSTEM_UID) {
4355            // Post an aysnc message to kill the application
4356            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4357            msg.arg1 = appid;
4358            msg.arg2 = 0;
4359            Bundle bundle = new Bundle();
4360            bundle.putString("pkg", pkg);
4361            bundle.putString("reason", reason);
4362            msg.obj = bundle;
4363            mHandler.sendMessage(msg);
4364        } else {
4365            throw new SecurityException(callerUid + " cannot kill pkg: " +
4366                    pkg);
4367        }
4368    }
4369
4370    @Override
4371    public void closeSystemDialogs(String reason) {
4372        enforceNotIsolatedCaller("closeSystemDialogs");
4373
4374        final int pid = Binder.getCallingPid();
4375        final int uid = Binder.getCallingUid();
4376        final long origId = Binder.clearCallingIdentity();
4377        try {
4378            synchronized (this) {
4379                // Only allow this from foreground processes, so that background
4380                // applications can't abuse it to prevent system UI from being shown.
4381                if (uid >= Process.FIRST_APPLICATION_UID) {
4382                    ProcessRecord proc;
4383                    synchronized (mPidsSelfLocked) {
4384                        proc = mPidsSelfLocked.get(pid);
4385                    }
4386                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4387                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4388                                + " from background process " + proc);
4389                        return;
4390                    }
4391                }
4392                closeSystemDialogsLocked(reason);
4393            }
4394        } finally {
4395            Binder.restoreCallingIdentity(origId);
4396        }
4397    }
4398
4399    void closeSystemDialogsLocked(String reason) {
4400        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4401        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4402                | Intent.FLAG_RECEIVER_FOREGROUND);
4403        if (reason != null) {
4404            intent.putExtra("reason", reason);
4405        }
4406        mWindowManager.closeSystemDialogs(reason);
4407
4408        mStackSupervisor.closeSystemDialogsLocked();
4409
4410        broadcastIntentLocked(null, null, intent, null,
4411                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4412                Process.SYSTEM_UID, UserHandle.USER_ALL);
4413    }
4414
4415    @Override
4416    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4417        enforceNotIsolatedCaller("getProcessMemoryInfo");
4418        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4419        for (int i=pids.length-1; i>=0; i--) {
4420            ProcessRecord proc;
4421            int oomAdj;
4422            synchronized (this) {
4423                synchronized (mPidsSelfLocked) {
4424                    proc = mPidsSelfLocked.get(pids[i]);
4425                    oomAdj = proc != null ? proc.setAdj : 0;
4426                }
4427            }
4428            infos[i] = new Debug.MemoryInfo();
4429            Debug.getMemoryInfo(pids[i], infos[i]);
4430            if (proc != null) {
4431                synchronized (this) {
4432                    if (proc.thread != null && proc.setAdj == oomAdj) {
4433                        // Record this for posterity if the process has been stable.
4434                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4435                                infos[i].getTotalUss(), false, proc.pkgList);
4436                    }
4437                }
4438            }
4439        }
4440        return infos;
4441    }
4442
4443    @Override
4444    public long[] getProcessPss(int[] pids) {
4445        enforceNotIsolatedCaller("getProcessPss");
4446        long[] pss = new long[pids.length];
4447        for (int i=pids.length-1; i>=0; i--) {
4448            ProcessRecord proc;
4449            int oomAdj;
4450            synchronized (this) {
4451                synchronized (mPidsSelfLocked) {
4452                    proc = mPidsSelfLocked.get(pids[i]);
4453                    oomAdj = proc != null ? proc.setAdj : 0;
4454                }
4455            }
4456            long[] tmpUss = new long[1];
4457            pss[i] = Debug.getPss(pids[i], tmpUss);
4458            if (proc != null) {
4459                synchronized (this) {
4460                    if (proc.thread != null && proc.setAdj == oomAdj) {
4461                        // Record this for posterity if the process has been stable.
4462                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4463                    }
4464                }
4465            }
4466        }
4467        return pss;
4468    }
4469
4470    @Override
4471    public void killApplicationProcess(String processName, int uid) {
4472        if (processName == null) {
4473            return;
4474        }
4475
4476        int callerUid = Binder.getCallingUid();
4477        // Only the system server can kill an application
4478        if (callerUid == Process.SYSTEM_UID) {
4479            synchronized (this) {
4480                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4481                if (app != null && app.thread != null) {
4482                    try {
4483                        app.thread.scheduleSuicide();
4484                    } catch (RemoteException e) {
4485                        // If the other end already died, then our work here is done.
4486                    }
4487                } else {
4488                    Slog.w(TAG, "Process/uid not found attempting kill of "
4489                            + processName + " / " + uid);
4490                }
4491            }
4492        } else {
4493            throw new SecurityException(callerUid + " cannot kill app process: " +
4494                    processName);
4495        }
4496    }
4497
4498    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4499        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4500                false, true, false, false, UserHandle.getUserId(uid), reason);
4501        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4502                Uri.fromParts("package", packageName, null));
4503        if (!mProcessesReady) {
4504            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4505                    | Intent.FLAG_RECEIVER_FOREGROUND);
4506        }
4507        intent.putExtra(Intent.EXTRA_UID, uid);
4508        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4509        broadcastIntentLocked(null, null, intent,
4510                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4511                false, false,
4512                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4513    }
4514
4515    private void forceStopUserLocked(int userId, String reason) {
4516        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4517        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4518        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4519                | Intent.FLAG_RECEIVER_FOREGROUND);
4520        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4521        broadcastIntentLocked(null, null, intent,
4522                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4523                false, false,
4524                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4525    }
4526
4527    private final boolean killPackageProcessesLocked(String packageName, int appId,
4528            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4529            boolean doit, boolean evenPersistent, String reason) {
4530        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4531
4532        // Remove all processes this package may have touched: all with the
4533        // same UID (except for the system or root user), and all whose name
4534        // matches the package name.
4535        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4536        final int NP = mProcessNames.getMap().size();
4537        for (int ip=0; ip<NP; ip++) {
4538            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4539            final int NA = apps.size();
4540            for (int ia=0; ia<NA; ia++) {
4541                ProcessRecord app = apps.valueAt(ia);
4542                if (app.persistent && !evenPersistent) {
4543                    // we don't kill persistent processes
4544                    continue;
4545                }
4546                if (app.removed) {
4547                    if (doit) {
4548                        procs.add(app);
4549                    }
4550                    continue;
4551                }
4552
4553                // Skip process if it doesn't meet our oom adj requirement.
4554                if (app.setAdj < minOomAdj) {
4555                    continue;
4556                }
4557
4558                // If no package is specified, we call all processes under the
4559                // give user id.
4560                if (packageName == null) {
4561                    if (app.userId != userId) {
4562                        continue;
4563                    }
4564                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4565                        continue;
4566                    }
4567                // Package has been specified, we want to hit all processes
4568                // that match it.  We need to qualify this by the processes
4569                // that are running under the specified app and user ID.
4570                } else {
4571                    if (UserHandle.getAppId(app.uid) != appId) {
4572                        continue;
4573                    }
4574                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4575                        continue;
4576                    }
4577                    if (!app.pkgList.containsKey(packageName)) {
4578                        continue;
4579                    }
4580                }
4581
4582                // Process has passed all conditions, kill it!
4583                if (!doit) {
4584                    return true;
4585                }
4586                app.removed = true;
4587                procs.add(app);
4588            }
4589        }
4590
4591        int N = procs.size();
4592        for (int i=0; i<N; i++) {
4593            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4594        }
4595        updateOomAdjLocked();
4596        return N > 0;
4597    }
4598
4599    private final boolean forceStopPackageLocked(String name, int appId,
4600            boolean callerWillRestart, boolean purgeCache, boolean doit,
4601            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4602        int i;
4603        int N;
4604
4605        if (userId == UserHandle.USER_ALL && name == null) {
4606            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4607        }
4608
4609        if (appId < 0 && name != null) {
4610            try {
4611                appId = UserHandle.getAppId(
4612                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4613            } catch (RemoteException e) {
4614            }
4615        }
4616
4617        if (doit) {
4618            if (name != null) {
4619                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4620                        + " user=" + userId + ": " + reason);
4621            } else {
4622                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4623            }
4624
4625            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4626            for (int ip=pmap.size()-1; ip>=0; ip--) {
4627                SparseArray<Long> ba = pmap.valueAt(ip);
4628                for (i=ba.size()-1; i>=0; i--) {
4629                    boolean remove = false;
4630                    final int entUid = ba.keyAt(i);
4631                    if (name != null) {
4632                        if (userId == UserHandle.USER_ALL) {
4633                            if (UserHandle.getAppId(entUid) == appId) {
4634                                remove = true;
4635                            }
4636                        } else {
4637                            if (entUid == UserHandle.getUid(userId, appId)) {
4638                                remove = true;
4639                            }
4640                        }
4641                    } else if (UserHandle.getUserId(entUid) == userId) {
4642                        remove = true;
4643                    }
4644                    if (remove) {
4645                        ba.removeAt(i);
4646                    }
4647                }
4648                if (ba.size() == 0) {
4649                    pmap.removeAt(ip);
4650                }
4651            }
4652        }
4653
4654        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4655                -100, callerWillRestart, true, doit, evenPersistent,
4656                name == null ? ("stop user " + userId) : ("stop " + name));
4657
4658        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4659            if (!doit) {
4660                return true;
4661            }
4662            didSomething = true;
4663        }
4664
4665        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4666            if (!doit) {
4667                return true;
4668            }
4669            didSomething = true;
4670        }
4671
4672        if (name == null) {
4673            // Remove all sticky broadcasts from this user.
4674            mStickyBroadcasts.remove(userId);
4675        }
4676
4677        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4678        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4679                userId, providers)) {
4680            if (!doit) {
4681                return true;
4682            }
4683            didSomething = true;
4684        }
4685        N = providers.size();
4686        for (i=0; i<N; i++) {
4687            removeDyingProviderLocked(null, providers.get(i), true);
4688        }
4689
4690        // Remove transient permissions granted from/to this package/user
4691        removeUriPermissionsForPackageLocked(name, userId, false);
4692
4693        if (name == null || uninstalling) {
4694            // Remove pending intents.  For now we only do this when force
4695            // stopping users, because we have some problems when doing this
4696            // for packages -- app widgets are not currently cleaned up for
4697            // such packages, so they can be left with bad pending intents.
4698            if (mIntentSenderRecords.size() > 0) {
4699                Iterator<WeakReference<PendingIntentRecord>> it
4700                        = mIntentSenderRecords.values().iterator();
4701                while (it.hasNext()) {
4702                    WeakReference<PendingIntentRecord> wpir = it.next();
4703                    if (wpir == null) {
4704                        it.remove();
4705                        continue;
4706                    }
4707                    PendingIntentRecord pir = wpir.get();
4708                    if (pir == null) {
4709                        it.remove();
4710                        continue;
4711                    }
4712                    if (name == null) {
4713                        // Stopping user, remove all objects for the user.
4714                        if (pir.key.userId != userId) {
4715                            // Not the same user, skip it.
4716                            continue;
4717                        }
4718                    } else {
4719                        if (UserHandle.getAppId(pir.uid) != appId) {
4720                            // Different app id, skip it.
4721                            continue;
4722                        }
4723                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4724                            // Different user, skip it.
4725                            continue;
4726                        }
4727                        if (!pir.key.packageName.equals(name)) {
4728                            // Different package, skip it.
4729                            continue;
4730                        }
4731                    }
4732                    if (!doit) {
4733                        return true;
4734                    }
4735                    didSomething = true;
4736                    it.remove();
4737                    pir.canceled = true;
4738                    if (pir.key.activity != null) {
4739                        pir.key.activity.pendingResults.remove(pir.ref);
4740                    }
4741                }
4742            }
4743        }
4744
4745        if (doit) {
4746            if (purgeCache && name != null) {
4747                AttributeCache ac = AttributeCache.instance();
4748                if (ac != null) {
4749                    ac.removePackage(name);
4750                }
4751            }
4752            if (mBooted) {
4753                mStackSupervisor.resumeTopActivitiesLocked();
4754                mStackSupervisor.scheduleIdleLocked();
4755            }
4756        }
4757
4758        return didSomething;
4759    }
4760
4761    private final boolean removeProcessLocked(ProcessRecord app,
4762            boolean callerWillRestart, boolean allowRestart, String reason) {
4763        final String name = app.processName;
4764        final int uid = app.uid;
4765        if (DEBUG_PROCESSES) Slog.d(
4766            TAG, "Force removing proc " + app.toShortString() + " (" + name
4767            + "/" + uid + ")");
4768
4769        mProcessNames.remove(name, uid);
4770        mIsolatedProcesses.remove(app.uid);
4771        if (mHeavyWeightProcess == app) {
4772            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4773                    mHeavyWeightProcess.userId, 0));
4774            mHeavyWeightProcess = null;
4775        }
4776        boolean needRestart = false;
4777        if (app.pid > 0 && app.pid != MY_PID) {
4778            int pid = app.pid;
4779            synchronized (mPidsSelfLocked) {
4780                mPidsSelfLocked.remove(pid);
4781                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4782            }
4783            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4784                    app.processName, app.info.uid);
4785            if (app.isolated) {
4786                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4787            }
4788            killUnneededProcessLocked(app, reason);
4789            handleAppDiedLocked(app, true, allowRestart);
4790            removeLruProcessLocked(app);
4791
4792            if (app.persistent && !app.isolated) {
4793                if (!callerWillRestart) {
4794                    addAppLocked(app.info, false);
4795                } else {
4796                    needRestart = true;
4797                }
4798            }
4799        } else {
4800            mRemovedProcesses.add(app);
4801        }
4802
4803        return needRestart;
4804    }
4805
4806    private final void processStartTimedOutLocked(ProcessRecord app) {
4807        final int pid = app.pid;
4808        boolean gone = false;
4809        synchronized (mPidsSelfLocked) {
4810            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4811            if (knownApp != null && knownApp.thread == null) {
4812                mPidsSelfLocked.remove(pid);
4813                gone = true;
4814            }
4815        }
4816
4817        if (gone) {
4818            Slog.w(TAG, "Process " + app + " failed to attach");
4819            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4820                    pid, app.uid, app.processName);
4821            mProcessNames.remove(app.processName, app.uid);
4822            mIsolatedProcesses.remove(app.uid);
4823            if (mHeavyWeightProcess == app) {
4824                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4825                        mHeavyWeightProcess.userId, 0));
4826                mHeavyWeightProcess = null;
4827            }
4828            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4829                    app.processName, app.info.uid);
4830            if (app.isolated) {
4831                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4832            }
4833            // Take care of any launching providers waiting for this process.
4834            checkAppInLaunchingProvidersLocked(app, true);
4835            // Take care of any services that are waiting for the process.
4836            mServices.processStartTimedOutLocked(app);
4837            killUnneededProcessLocked(app, "start timeout");
4838            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4839                Slog.w(TAG, "Unattached app died before backup, skipping");
4840                try {
4841                    IBackupManager bm = IBackupManager.Stub.asInterface(
4842                            ServiceManager.getService(Context.BACKUP_SERVICE));
4843                    bm.agentDisconnected(app.info.packageName);
4844                } catch (RemoteException e) {
4845                    // Can't happen; the backup manager is local
4846                }
4847            }
4848            if (isPendingBroadcastProcessLocked(pid)) {
4849                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4850                skipPendingBroadcastLocked(pid);
4851            }
4852        } else {
4853            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4854        }
4855    }
4856
4857    private final boolean attachApplicationLocked(IApplicationThread thread,
4858            int pid) {
4859
4860        // Find the application record that is being attached...  either via
4861        // the pid if we are running in multiple processes, or just pull the
4862        // next app record if we are emulating process with anonymous threads.
4863        ProcessRecord app;
4864        if (pid != MY_PID && pid >= 0) {
4865            synchronized (mPidsSelfLocked) {
4866                app = mPidsSelfLocked.get(pid);
4867            }
4868        } else {
4869            app = null;
4870        }
4871
4872        if (app == null) {
4873            Slog.w(TAG, "No pending application record for pid " + pid
4874                    + " (IApplicationThread " + thread + "); dropping process");
4875            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4876            if (pid > 0 && pid != MY_PID) {
4877                Process.killProcessQuiet(pid);
4878            } else {
4879                try {
4880                    thread.scheduleExit();
4881                } catch (Exception e) {
4882                    // Ignore exceptions.
4883                }
4884            }
4885            return false;
4886        }
4887
4888        // If this application record is still attached to a previous
4889        // process, clean it up now.
4890        if (app.thread != null) {
4891            handleAppDiedLocked(app, true, true);
4892        }
4893
4894        // Tell the process all about itself.
4895
4896        if (localLOGV) Slog.v(
4897                TAG, "Binding process pid " + pid + " to record " + app);
4898
4899        final String processName = app.processName;
4900        try {
4901            AppDeathRecipient adr = new AppDeathRecipient(
4902                    app, pid, thread);
4903            thread.asBinder().linkToDeath(adr, 0);
4904            app.deathRecipient = adr;
4905        } catch (RemoteException e) {
4906            app.resetPackageList(mProcessStats);
4907            startProcessLocked(app, "link fail", processName);
4908            return false;
4909        }
4910
4911        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4912
4913        app.makeActive(thread, mProcessStats);
4914        app.curAdj = app.setAdj = -100;
4915        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4916        app.forcingToForeground = null;
4917        updateProcessForegroundLocked(app, false, false);
4918        app.hasShownUi = false;
4919        app.debugging = false;
4920        app.cached = false;
4921
4922        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4923
4924        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4925        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4926
4927        if (!normalMode) {
4928            Slog.i(TAG, "Launching preboot mode app: " + app);
4929        }
4930
4931        if (localLOGV) Slog.v(
4932            TAG, "New app record " + app
4933            + " thread=" + thread.asBinder() + " pid=" + pid);
4934        try {
4935            int testMode = IApplicationThread.DEBUG_OFF;
4936            if (mDebugApp != null && mDebugApp.equals(processName)) {
4937                testMode = mWaitForDebugger
4938                    ? IApplicationThread.DEBUG_WAIT
4939                    : IApplicationThread.DEBUG_ON;
4940                app.debugging = true;
4941                if (mDebugTransient) {
4942                    mDebugApp = mOrigDebugApp;
4943                    mWaitForDebugger = mOrigWaitForDebugger;
4944                }
4945            }
4946            String profileFile = app.instrumentationProfileFile;
4947            ParcelFileDescriptor profileFd = null;
4948            boolean profileAutoStop = false;
4949            if (mProfileApp != null && mProfileApp.equals(processName)) {
4950                mProfileProc = app;
4951                profileFile = mProfileFile;
4952                profileFd = mProfileFd;
4953                profileAutoStop = mAutoStopProfiler;
4954            }
4955            boolean enableOpenGlTrace = false;
4956            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4957                enableOpenGlTrace = true;
4958                mOpenGlTraceApp = null;
4959            }
4960
4961            // If the app is being launched for restore or full backup, set it up specially
4962            boolean isRestrictedBackupMode = false;
4963            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4964                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4965                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4966                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4967            }
4968
4969            ensurePackageDexOpt(app.instrumentationInfo != null
4970                    ? app.instrumentationInfo.packageName
4971                    : app.info.packageName);
4972            if (app.instrumentationClass != null) {
4973                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4974            }
4975            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4976                    + processName + " with config " + mConfiguration);
4977            ApplicationInfo appInfo = app.instrumentationInfo != null
4978                    ? app.instrumentationInfo : app.info;
4979            app.compat = compatibilityInfoForPackageLocked(appInfo);
4980            if (profileFd != null) {
4981                profileFd = profileFd.dup();
4982            }
4983            thread.bindApplication(processName, appInfo, providers,
4984                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4985                    app.instrumentationArguments, app.instrumentationWatcher,
4986                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4987                    isRestrictedBackupMode || !normalMode, app.persistent,
4988                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4989                    mCoreSettingsObserver.getCoreSettingsLocked());
4990            updateLruProcessLocked(app, false, null);
4991            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4992        } catch (Exception e) {
4993            // todo: Yikes!  What should we do?  For now we will try to
4994            // start another process, but that could easily get us in
4995            // an infinite loop of restarting processes...
4996            Slog.w(TAG, "Exception thrown during bind!", e);
4997
4998            app.resetPackageList(mProcessStats);
4999            app.unlinkDeathRecipient();
5000            startProcessLocked(app, "bind fail", processName);
5001            return false;
5002        }
5003
5004        // Remove this record from the list of starting applications.
5005        mPersistentStartingProcesses.remove(app);
5006        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5007                "Attach application locked removing on hold: " + app);
5008        mProcessesOnHold.remove(app);
5009
5010        boolean badApp = false;
5011        boolean didSomething = false;
5012
5013        // See if the top visible activity is waiting to run in this process...
5014        if (normalMode) {
5015            try {
5016                if (mStackSupervisor.attachApplicationLocked(app)) {
5017                    didSomething = true;
5018                }
5019            } catch (Exception e) {
5020                badApp = true;
5021            }
5022        }
5023
5024        // Find any services that should be running in this process...
5025        if (!badApp) {
5026            try {
5027                didSomething |= mServices.attachApplicationLocked(app, processName);
5028            } catch (Exception e) {
5029                badApp = true;
5030            }
5031        }
5032
5033        // Check if a next-broadcast receiver is in this process...
5034        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5035            try {
5036                didSomething |= sendPendingBroadcastsLocked(app);
5037            } catch (Exception e) {
5038                // If the app died trying to launch the receiver we declare it 'bad'
5039                badApp = true;
5040            }
5041        }
5042
5043        // Check whether the next backup agent is in this process...
5044        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5045            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5046            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5047            try {
5048                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5049                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5050                        mBackupTarget.backupMode);
5051            } catch (Exception e) {
5052                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5053                e.printStackTrace();
5054            }
5055        }
5056
5057        if (badApp) {
5058            // todo: Also need to kill application to deal with all
5059            // kinds of exceptions.
5060            handleAppDiedLocked(app, false, true);
5061            return false;
5062        }
5063
5064        if (!didSomething) {
5065            updateOomAdjLocked();
5066        }
5067
5068        return true;
5069    }
5070
5071    @Override
5072    public final void attachApplication(IApplicationThread thread) {
5073        synchronized (this) {
5074            int callingPid = Binder.getCallingPid();
5075            final long origId = Binder.clearCallingIdentity();
5076            attachApplicationLocked(thread, callingPid);
5077            Binder.restoreCallingIdentity(origId);
5078        }
5079    }
5080
5081    @Override
5082    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5083        final long origId = Binder.clearCallingIdentity();
5084        synchronized (this) {
5085            ActivityStack stack = ActivityRecord.getStackLocked(token);
5086            if (stack != null) {
5087                ActivityRecord r =
5088                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5089                if (stopProfiling) {
5090                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5091                        try {
5092                            mProfileFd.close();
5093                        } catch (IOException e) {
5094                        }
5095                        clearProfilerLocked();
5096                    }
5097                }
5098            }
5099        }
5100        Binder.restoreCallingIdentity(origId);
5101    }
5102
5103    void enableScreenAfterBoot() {
5104        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5105                SystemClock.uptimeMillis());
5106        mWindowManager.enableScreenAfterBoot();
5107
5108        synchronized (this) {
5109            updateEventDispatchingLocked();
5110        }
5111    }
5112
5113    @Override
5114    public void showBootMessage(final CharSequence msg, final boolean always) {
5115        enforceNotIsolatedCaller("showBootMessage");
5116        mWindowManager.showBootMessage(msg, always);
5117    }
5118
5119    @Override
5120    public void dismissKeyguardOnNextActivity() {
5121        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5122        final long token = Binder.clearCallingIdentity();
5123        try {
5124            synchronized (this) {
5125                if (DEBUG_LOCKSCREEN) logLockScreen("");
5126                if (mLockScreenShown) {
5127                    mLockScreenShown = false;
5128                    comeOutOfSleepIfNeededLocked();
5129                }
5130                mStackSupervisor.setDismissKeyguard(true);
5131            }
5132        } finally {
5133            Binder.restoreCallingIdentity(token);
5134        }
5135    }
5136
5137    final void finishBooting() {
5138        IntentFilter pkgFilter = new IntentFilter();
5139        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5140        pkgFilter.addDataScheme("package");
5141        mContext.registerReceiver(new BroadcastReceiver() {
5142            @Override
5143            public void onReceive(Context context, Intent intent) {
5144                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5145                if (pkgs != null) {
5146                    for (String pkg : pkgs) {
5147                        synchronized (ActivityManagerService.this) {
5148                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5149                                    "finished booting")) {
5150                                setResultCode(Activity.RESULT_OK);
5151                                return;
5152                            }
5153                        }
5154                    }
5155                }
5156            }
5157        }, pkgFilter);
5158
5159        synchronized (this) {
5160            // Ensure that any processes we had put on hold are now started
5161            // up.
5162            final int NP = mProcessesOnHold.size();
5163            if (NP > 0) {
5164                ArrayList<ProcessRecord> procs =
5165                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5166                for (int ip=0; ip<NP; ip++) {
5167                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5168                            + procs.get(ip));
5169                    startProcessLocked(procs.get(ip), "on-hold", null);
5170                }
5171            }
5172
5173            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5174                // Start looking for apps that are abusing wake locks.
5175                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5176                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5177                // Tell anyone interested that we are done booting!
5178                SystemProperties.set("sys.boot_completed", "1");
5179                SystemProperties.set("dev.bootcomplete", "1");
5180                for (int i=0; i<mStartedUsers.size(); i++) {
5181                    UserStartedState uss = mStartedUsers.valueAt(i);
5182                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5183                        uss.mState = UserStartedState.STATE_RUNNING;
5184                        final int userId = mStartedUsers.keyAt(i);
5185                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5186                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5187                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5188                        broadcastIntentLocked(null, null, intent, null,
5189                                new IIntentReceiver.Stub() {
5190                                    @Override
5191                                    public void performReceive(Intent intent, int resultCode,
5192                                            String data, Bundle extras, boolean ordered,
5193                                            boolean sticky, int sendingUser) {
5194                                        synchronized (ActivityManagerService.this) {
5195                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5196                                                    true, false);
5197                                        }
5198                                    }
5199                                },
5200                                0, null, null,
5201                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5202                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5203                                userId);
5204                    }
5205                }
5206                scheduleStartRelatedUsersLocked();
5207            }
5208        }
5209    }
5210
5211    final void ensureBootCompleted() {
5212        boolean booting;
5213        boolean enableScreen;
5214        synchronized (this) {
5215            booting = mBooting;
5216            mBooting = false;
5217            enableScreen = !mBooted;
5218            mBooted = true;
5219        }
5220
5221        if (booting) {
5222            finishBooting();
5223        }
5224
5225        if (enableScreen) {
5226            enableScreenAfterBoot();
5227        }
5228    }
5229
5230    @Override
5231    public final void activityResumed(IBinder token) {
5232        final long origId = Binder.clearCallingIdentity();
5233        synchronized(this) {
5234            ActivityStack stack = ActivityRecord.getStackLocked(token);
5235            if (stack != null) {
5236                ActivityRecord.activityResumedLocked(token);
5237            }
5238        }
5239        Binder.restoreCallingIdentity(origId);
5240    }
5241
5242    @Override
5243    public final void activityPaused(IBinder token) {
5244        final long origId = Binder.clearCallingIdentity();
5245        synchronized(this) {
5246            ActivityStack stack = ActivityRecord.getStackLocked(token);
5247            if (stack != null) {
5248                stack.activityPausedLocked(token, false);
5249            }
5250        }
5251        Binder.restoreCallingIdentity(origId);
5252    }
5253
5254    @Override
5255    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5256            CharSequence description) {
5257        if (localLOGV) Slog.v(
5258            TAG, "Activity stopped: token=" + token);
5259
5260        // Refuse possible leaked file descriptors
5261        if (icicle != null && icicle.hasFileDescriptors()) {
5262            throw new IllegalArgumentException("File descriptors passed in Bundle");
5263        }
5264
5265        ActivityRecord r = null;
5266
5267        final long origId = Binder.clearCallingIdentity();
5268
5269        synchronized (this) {
5270            r = ActivityRecord.isInStackLocked(token);
5271            if (r != null) {
5272                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5273            }
5274        }
5275
5276        if (r != null) {
5277            sendPendingThumbnail(r, null, null, null, false);
5278        }
5279
5280        trimApplications();
5281
5282        Binder.restoreCallingIdentity(origId);
5283    }
5284
5285    @Override
5286    public final void activityDestroyed(IBinder token) {
5287        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5288        synchronized (this) {
5289            ActivityStack stack = ActivityRecord.getStackLocked(token);
5290            if (stack != null) {
5291                stack.activityDestroyedLocked(token);
5292            }
5293        }
5294    }
5295
5296    @Override
5297    public String getCallingPackage(IBinder token) {
5298        synchronized (this) {
5299            ActivityRecord r = getCallingRecordLocked(token);
5300            return r != null ? r.info.packageName : null;
5301        }
5302    }
5303
5304    @Override
5305    public ComponentName getCallingActivity(IBinder token) {
5306        synchronized (this) {
5307            ActivityRecord r = getCallingRecordLocked(token);
5308            return r != null ? r.intent.getComponent() : null;
5309        }
5310    }
5311
5312    private ActivityRecord getCallingRecordLocked(IBinder token) {
5313        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5314        if (r == null) {
5315            return null;
5316        }
5317        return r.resultTo;
5318    }
5319
5320    @Override
5321    public ComponentName getActivityClassForToken(IBinder token) {
5322        synchronized(this) {
5323            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5324            if (r == null) {
5325                return null;
5326            }
5327            return r.intent.getComponent();
5328        }
5329    }
5330
5331    @Override
5332    public String getPackageForToken(IBinder token) {
5333        synchronized(this) {
5334            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5335            if (r == null) {
5336                return null;
5337            }
5338            return r.packageName;
5339        }
5340    }
5341
5342    @Override
5343    public IIntentSender getIntentSender(int type,
5344            String packageName, IBinder token, String resultWho,
5345            int requestCode, Intent[] intents, String[] resolvedTypes,
5346            int flags, Bundle options, int userId) {
5347        enforceNotIsolatedCaller("getIntentSender");
5348        // Refuse possible leaked file descriptors
5349        if (intents != null) {
5350            if (intents.length < 1) {
5351                throw new IllegalArgumentException("Intents array length must be >= 1");
5352            }
5353            for (int i=0; i<intents.length; i++) {
5354                Intent intent = intents[i];
5355                if (intent != null) {
5356                    if (intent.hasFileDescriptors()) {
5357                        throw new IllegalArgumentException("File descriptors passed in Intent");
5358                    }
5359                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5360                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5361                        throw new IllegalArgumentException(
5362                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5363                    }
5364                    intents[i] = new Intent(intent);
5365                }
5366            }
5367            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5368                throw new IllegalArgumentException(
5369                        "Intent array length does not match resolvedTypes length");
5370            }
5371        }
5372        if (options != null) {
5373            if (options.hasFileDescriptors()) {
5374                throw new IllegalArgumentException("File descriptors passed in options");
5375            }
5376        }
5377
5378        synchronized(this) {
5379            int callingUid = Binder.getCallingUid();
5380            int origUserId = userId;
5381            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5382                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5383                    "getIntentSender", null);
5384            if (origUserId == UserHandle.USER_CURRENT) {
5385                // We don't want to evaluate this until the pending intent is
5386                // actually executed.  However, we do want to always do the
5387                // security checking for it above.
5388                userId = UserHandle.USER_CURRENT;
5389            }
5390            try {
5391                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5392                    int uid = AppGlobals.getPackageManager()
5393                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5394                    if (!UserHandle.isSameApp(callingUid, uid)) {
5395                        String msg = "Permission Denial: getIntentSender() from pid="
5396                            + Binder.getCallingPid()
5397                            + ", uid=" + Binder.getCallingUid()
5398                            + ", (need uid=" + uid + ")"
5399                            + " is not allowed to send as package " + packageName;
5400                        Slog.w(TAG, msg);
5401                        throw new SecurityException(msg);
5402                    }
5403                }
5404
5405                return getIntentSenderLocked(type, packageName, callingUid, userId,
5406                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5407
5408            } catch (RemoteException e) {
5409                throw new SecurityException(e);
5410            }
5411        }
5412    }
5413
5414    IIntentSender getIntentSenderLocked(int type, String packageName,
5415            int callingUid, int userId, IBinder token, String resultWho,
5416            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5417            Bundle options) {
5418        if (DEBUG_MU)
5419            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5420        ActivityRecord activity = null;
5421        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5422            activity = ActivityRecord.isInStackLocked(token);
5423            if (activity == null) {
5424                return null;
5425            }
5426            if (activity.finishing) {
5427                return null;
5428            }
5429        }
5430
5431        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5432        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5433        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5434        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5435                |PendingIntent.FLAG_UPDATE_CURRENT);
5436
5437        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5438                type, packageName, activity, resultWho,
5439                requestCode, intents, resolvedTypes, flags, options, userId);
5440        WeakReference<PendingIntentRecord> ref;
5441        ref = mIntentSenderRecords.get(key);
5442        PendingIntentRecord rec = ref != null ? ref.get() : null;
5443        if (rec != null) {
5444            if (!cancelCurrent) {
5445                if (updateCurrent) {
5446                    if (rec.key.requestIntent != null) {
5447                        rec.key.requestIntent.replaceExtras(intents != null ?
5448                                intents[intents.length - 1] : null);
5449                    }
5450                    if (intents != null) {
5451                        intents[intents.length-1] = rec.key.requestIntent;
5452                        rec.key.allIntents = intents;
5453                        rec.key.allResolvedTypes = resolvedTypes;
5454                    } else {
5455                        rec.key.allIntents = null;
5456                        rec.key.allResolvedTypes = null;
5457                    }
5458                }
5459                return rec;
5460            }
5461            rec.canceled = true;
5462            mIntentSenderRecords.remove(key);
5463        }
5464        if (noCreate) {
5465            return rec;
5466        }
5467        rec = new PendingIntentRecord(this, key, callingUid);
5468        mIntentSenderRecords.put(key, rec.ref);
5469        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5470            if (activity.pendingResults == null) {
5471                activity.pendingResults
5472                        = new HashSet<WeakReference<PendingIntentRecord>>();
5473            }
5474            activity.pendingResults.add(rec.ref);
5475        }
5476        return rec;
5477    }
5478
5479    @Override
5480    public void cancelIntentSender(IIntentSender sender) {
5481        if (!(sender instanceof PendingIntentRecord)) {
5482            return;
5483        }
5484        synchronized(this) {
5485            PendingIntentRecord rec = (PendingIntentRecord)sender;
5486            try {
5487                int uid = AppGlobals.getPackageManager()
5488                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5489                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5490                    String msg = "Permission Denial: cancelIntentSender() from pid="
5491                        + Binder.getCallingPid()
5492                        + ", uid=" + Binder.getCallingUid()
5493                        + " is not allowed to cancel packges "
5494                        + rec.key.packageName;
5495                    Slog.w(TAG, msg);
5496                    throw new SecurityException(msg);
5497                }
5498            } catch (RemoteException e) {
5499                throw new SecurityException(e);
5500            }
5501            cancelIntentSenderLocked(rec, true);
5502        }
5503    }
5504
5505    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5506        rec.canceled = true;
5507        mIntentSenderRecords.remove(rec.key);
5508        if (cleanActivity && rec.key.activity != null) {
5509            rec.key.activity.pendingResults.remove(rec.ref);
5510        }
5511    }
5512
5513    @Override
5514    public String getPackageForIntentSender(IIntentSender pendingResult) {
5515        if (!(pendingResult instanceof PendingIntentRecord)) {
5516            return null;
5517        }
5518        try {
5519            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5520            return res.key.packageName;
5521        } catch (ClassCastException e) {
5522        }
5523        return null;
5524    }
5525
5526    @Override
5527    public int getUidForIntentSender(IIntentSender sender) {
5528        if (sender instanceof PendingIntentRecord) {
5529            try {
5530                PendingIntentRecord res = (PendingIntentRecord)sender;
5531                return res.uid;
5532            } catch (ClassCastException e) {
5533            }
5534        }
5535        return -1;
5536    }
5537
5538    @Override
5539    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5540        if (!(pendingResult instanceof PendingIntentRecord)) {
5541            return false;
5542        }
5543        try {
5544            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5545            if (res.key.allIntents == null) {
5546                return false;
5547            }
5548            for (int i=0; i<res.key.allIntents.length; i++) {
5549                Intent intent = res.key.allIntents[i];
5550                if (intent.getPackage() != null && intent.getComponent() != null) {
5551                    return false;
5552                }
5553            }
5554            return true;
5555        } catch (ClassCastException e) {
5556        }
5557        return false;
5558    }
5559
5560    @Override
5561    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5562        if (!(pendingResult instanceof PendingIntentRecord)) {
5563            return false;
5564        }
5565        try {
5566            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5567            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5568                return true;
5569            }
5570            return false;
5571        } catch (ClassCastException e) {
5572        }
5573        return false;
5574    }
5575
5576    @Override
5577    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5578        if (!(pendingResult instanceof PendingIntentRecord)) {
5579            return null;
5580        }
5581        try {
5582            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5583            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5584        } catch (ClassCastException e) {
5585        }
5586        return null;
5587    }
5588
5589    @Override
5590    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5591        if (!(pendingResult instanceof PendingIntentRecord)) {
5592            return null;
5593        }
5594        try {
5595            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5596            Intent intent = res.key.requestIntent;
5597            if (intent != null) {
5598                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5599                        || res.lastTagPrefix.equals(prefix))) {
5600                    return res.lastTag;
5601                }
5602                res.lastTagPrefix = prefix;
5603                StringBuilder sb = new StringBuilder(128);
5604                if (prefix != null) {
5605                    sb.append(prefix);
5606                }
5607                if (intent.getAction() != null) {
5608                    sb.append(intent.getAction());
5609                } else if (intent.getComponent() != null) {
5610                    intent.getComponent().appendShortString(sb);
5611                } else {
5612                    sb.append("?");
5613                }
5614                return res.lastTag = sb.toString();
5615            }
5616        } catch (ClassCastException e) {
5617        }
5618        return null;
5619    }
5620
5621    @Override
5622    public void setProcessLimit(int max) {
5623        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5624                "setProcessLimit()");
5625        synchronized (this) {
5626            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5627            mProcessLimitOverride = max;
5628        }
5629        trimApplications();
5630    }
5631
5632    @Override
5633    public int getProcessLimit() {
5634        synchronized (this) {
5635            return mProcessLimitOverride;
5636        }
5637    }
5638
5639    void foregroundTokenDied(ForegroundToken token) {
5640        synchronized (ActivityManagerService.this) {
5641            synchronized (mPidsSelfLocked) {
5642                ForegroundToken cur
5643                    = mForegroundProcesses.get(token.pid);
5644                if (cur != token) {
5645                    return;
5646                }
5647                mForegroundProcesses.remove(token.pid);
5648                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5649                if (pr == null) {
5650                    return;
5651                }
5652                pr.forcingToForeground = null;
5653                updateProcessForegroundLocked(pr, false, false);
5654            }
5655            updateOomAdjLocked();
5656        }
5657    }
5658
5659    @Override
5660    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5661        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5662                "setProcessForeground()");
5663        synchronized(this) {
5664            boolean changed = false;
5665
5666            synchronized (mPidsSelfLocked) {
5667                ProcessRecord pr = mPidsSelfLocked.get(pid);
5668                if (pr == null && isForeground) {
5669                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5670                    return;
5671                }
5672                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5673                if (oldToken != null) {
5674                    oldToken.token.unlinkToDeath(oldToken, 0);
5675                    mForegroundProcesses.remove(pid);
5676                    if (pr != null) {
5677                        pr.forcingToForeground = null;
5678                    }
5679                    changed = true;
5680                }
5681                if (isForeground && token != null) {
5682                    ForegroundToken newToken = new ForegroundToken() {
5683                        @Override
5684                        public void binderDied() {
5685                            foregroundTokenDied(this);
5686                        }
5687                    };
5688                    newToken.pid = pid;
5689                    newToken.token = token;
5690                    try {
5691                        token.linkToDeath(newToken, 0);
5692                        mForegroundProcesses.put(pid, newToken);
5693                        pr.forcingToForeground = token;
5694                        changed = true;
5695                    } catch (RemoteException e) {
5696                        // If the process died while doing this, we will later
5697                        // do the cleanup with the process death link.
5698                    }
5699                }
5700            }
5701
5702            if (changed) {
5703                updateOomAdjLocked();
5704            }
5705        }
5706    }
5707
5708    // =========================================================
5709    // PERMISSIONS
5710    // =========================================================
5711
5712    static class PermissionController extends IPermissionController.Stub {
5713        ActivityManagerService mActivityManagerService;
5714        PermissionController(ActivityManagerService activityManagerService) {
5715            mActivityManagerService = activityManagerService;
5716        }
5717
5718        @Override
5719        public boolean checkPermission(String permission, int pid, int uid) {
5720            return mActivityManagerService.checkPermission(permission, pid,
5721                    uid) == PackageManager.PERMISSION_GRANTED;
5722        }
5723    }
5724
5725    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5726        @Override
5727        public int checkComponentPermission(String permission, int pid, int uid,
5728                int owningUid, boolean exported) {
5729            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5730                    owningUid, exported);
5731        }
5732
5733        @Override
5734        public Object getAMSLock() {
5735            return ActivityManagerService.this;
5736        }
5737    }
5738
5739    /**
5740     * This can be called with or without the global lock held.
5741     */
5742    int checkComponentPermission(String permission, int pid, int uid,
5743            int owningUid, boolean exported) {
5744        // We might be performing an operation on behalf of an indirect binder
5745        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5746        // client identity accordingly before proceeding.
5747        Identity tlsIdentity = sCallerIdentity.get();
5748        if (tlsIdentity != null) {
5749            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5750                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5751            uid = tlsIdentity.uid;
5752            pid = tlsIdentity.pid;
5753        }
5754
5755        if (pid == MY_PID) {
5756            return PackageManager.PERMISSION_GRANTED;
5757        }
5758
5759        return ActivityManager.checkComponentPermission(permission, uid,
5760                owningUid, exported);
5761    }
5762
5763    /**
5764     * As the only public entry point for permissions checking, this method
5765     * can enforce the semantic that requesting a check on a null global
5766     * permission is automatically denied.  (Internally a null permission
5767     * string is used when calling {@link #checkComponentPermission} in cases
5768     * when only uid-based security is needed.)
5769     *
5770     * This can be called with or without the global lock held.
5771     */
5772    @Override
5773    public int checkPermission(String permission, int pid, int uid) {
5774        if (permission == null) {
5775            return PackageManager.PERMISSION_DENIED;
5776        }
5777        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5778    }
5779
5780    /**
5781     * Binder IPC calls go through the public entry point.
5782     * This can be called with or without the global lock held.
5783     */
5784    int checkCallingPermission(String permission) {
5785        return checkPermission(permission,
5786                Binder.getCallingPid(),
5787                UserHandle.getAppId(Binder.getCallingUid()));
5788    }
5789
5790    /**
5791     * This can be called with or without the global lock held.
5792     */
5793    void enforceCallingPermission(String permission, String func) {
5794        if (checkCallingPermission(permission)
5795                == PackageManager.PERMISSION_GRANTED) {
5796            return;
5797        }
5798
5799        String msg = "Permission Denial: " + func + " from pid="
5800                + Binder.getCallingPid()
5801                + ", uid=" + Binder.getCallingUid()
5802                + " requires " + permission;
5803        Slog.w(TAG, msg);
5804        throw new SecurityException(msg);
5805    }
5806
5807    /**
5808     * Determine if UID is holding permissions required to access {@link Uri} in
5809     * the given {@link ProviderInfo}. Final permission checking is always done
5810     * in {@link ContentProvider}.
5811     */
5812    private final boolean checkHoldingPermissionsLocked(
5813            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5814        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5815                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5816
5817        if (pi.applicationInfo.uid == uid) {
5818            return true;
5819        } else if (!pi.exported) {
5820            return false;
5821        }
5822
5823        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5824        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5825        try {
5826            // check if target holds top-level <provider> permissions
5827            if (!readMet && pi.readPermission != null
5828                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5829                readMet = true;
5830            }
5831            if (!writeMet && pi.writePermission != null
5832                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5833                writeMet = true;
5834            }
5835
5836            // track if unprotected read/write is allowed; any denied
5837            // <path-permission> below removes this ability
5838            boolean allowDefaultRead = pi.readPermission == null;
5839            boolean allowDefaultWrite = pi.writePermission == null;
5840
5841            // check if target holds any <path-permission> that match uri
5842            final PathPermission[] pps = pi.pathPermissions;
5843            if (pps != null) {
5844                final String path = uri.getPath();
5845                int i = pps.length;
5846                while (i > 0 && (!readMet || !writeMet)) {
5847                    i--;
5848                    PathPermission pp = pps[i];
5849                    if (pp.match(path)) {
5850                        if (!readMet) {
5851                            final String pprperm = pp.getReadPermission();
5852                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5853                                    + pprperm + " for " + pp.getPath()
5854                                    + ": match=" + pp.match(path)
5855                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5856                            if (pprperm != null) {
5857                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5858                                    readMet = true;
5859                                } else {
5860                                    allowDefaultRead = false;
5861                                }
5862                            }
5863                        }
5864                        if (!writeMet) {
5865                            final String ppwperm = pp.getWritePermission();
5866                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5867                                    + ppwperm + " for " + pp.getPath()
5868                                    + ": match=" + pp.match(path)
5869                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5870                            if (ppwperm != null) {
5871                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5872                                    writeMet = true;
5873                                } else {
5874                                    allowDefaultWrite = false;
5875                                }
5876                            }
5877                        }
5878                    }
5879                }
5880            }
5881
5882            // grant unprotected <provider> read/write, if not blocked by
5883            // <path-permission> above
5884            if (allowDefaultRead) readMet = true;
5885            if (allowDefaultWrite) writeMet = true;
5886
5887        } catch (RemoteException e) {
5888            return false;
5889        }
5890
5891        return readMet && writeMet;
5892    }
5893
5894    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5895        ProviderInfo pi = null;
5896        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5897        if (cpr != null) {
5898            pi = cpr.info;
5899        } else {
5900            try {
5901                pi = AppGlobals.getPackageManager().resolveContentProvider(
5902                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5903            } catch (RemoteException ex) {
5904            }
5905        }
5906        return pi;
5907    }
5908
5909    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5910        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5911        if (targetUris != null) {
5912            return targetUris.get(uri);
5913        } else {
5914            return null;
5915        }
5916    }
5917
5918    private UriPermission findOrCreateUriPermissionLocked(
5919            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5920        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5921        if (targetUris == null) {
5922            targetUris = Maps.newArrayMap();
5923            mGrantedUriPermissions.put(targetUid, targetUris);
5924        }
5925
5926        UriPermission perm = targetUris.get(uri);
5927        if (perm == null) {
5928            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5929            targetUris.put(uri, perm);
5930        }
5931
5932        return perm;
5933    }
5934
5935    private final boolean checkUriPermissionLocked(
5936            Uri uri, int uid, int modeFlags, int minStrength) {
5937        // Root gets to do everything.
5938        if (uid == 0) {
5939            return true;
5940        }
5941        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5942        if (perms == null) return false;
5943        UriPermission perm = perms.get(uri);
5944        if (perm == null) return false;
5945        return perm.getStrength(modeFlags) >= minStrength;
5946    }
5947
5948    @Override
5949    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5950        enforceNotIsolatedCaller("checkUriPermission");
5951
5952        // Another redirected-binder-call permissions check as in
5953        // {@link checkComponentPermission}.
5954        Identity tlsIdentity = sCallerIdentity.get();
5955        if (tlsIdentity != null) {
5956            uid = tlsIdentity.uid;
5957            pid = tlsIdentity.pid;
5958        }
5959
5960        // Our own process gets to do everything.
5961        if (pid == MY_PID) {
5962            return PackageManager.PERMISSION_GRANTED;
5963        }
5964        synchronized(this) {
5965            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5966                    ? PackageManager.PERMISSION_GRANTED
5967                    : PackageManager.PERMISSION_DENIED;
5968        }
5969    }
5970
5971    /**
5972     * Check if the targetPkg can be granted permission to access uri by
5973     * the callingUid using the given modeFlags.  Throws a security exception
5974     * if callingUid is not allowed to do this.  Returns the uid of the target
5975     * if the URI permission grant should be performed; returns -1 if it is not
5976     * needed (for example targetPkg already has permission to access the URI).
5977     * If you already know the uid of the target, you can supply it in
5978     * lastTargetUid else set that to -1.
5979     */
5980    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5981            Uri uri, int modeFlags, int lastTargetUid) {
5982        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5983        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5984                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5985        if (modeFlags == 0) {
5986            return -1;
5987        }
5988
5989        if (targetPkg != null) {
5990            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5991                    "Checking grant " + targetPkg + " permission to " + uri);
5992        }
5993
5994        final IPackageManager pm = AppGlobals.getPackageManager();
5995
5996        // If this is not a content: uri, we can't do anything with it.
5997        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5998            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5999                    "Can't grant URI permission for non-content URI: " + uri);
6000            return -1;
6001        }
6002
6003        final String authority = uri.getAuthority();
6004        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6005        if (pi == null) {
6006            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6007            return -1;
6008        }
6009
6010        int targetUid = lastTargetUid;
6011        if (targetUid < 0 && targetPkg != null) {
6012            try {
6013                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6014                if (targetUid < 0) {
6015                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6016                            "Can't grant URI permission no uid for: " + targetPkg);
6017                    return -1;
6018                }
6019            } catch (RemoteException ex) {
6020                return -1;
6021            }
6022        }
6023
6024        if (targetUid >= 0) {
6025            // First...  does the target actually need this permission?
6026            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6027                // No need to grant the target this permission.
6028                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6029                        "Target " + targetPkg + " already has full permission to " + uri);
6030                return -1;
6031            }
6032        } else {
6033            // First...  there is no target package, so can anyone access it?
6034            boolean allowed = pi.exported;
6035            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6036                if (pi.readPermission != null) {
6037                    allowed = false;
6038                }
6039            }
6040            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6041                if (pi.writePermission != null) {
6042                    allowed = false;
6043                }
6044            }
6045            if (allowed) {
6046                return -1;
6047            }
6048        }
6049
6050        // Second...  is the provider allowing granting of URI permissions?
6051        if (!pi.grantUriPermissions) {
6052            throw new SecurityException("Provider " + pi.packageName
6053                    + "/" + pi.name
6054                    + " does not allow granting of Uri permissions (uri "
6055                    + uri + ")");
6056        }
6057        if (pi.uriPermissionPatterns != null) {
6058            final int N = pi.uriPermissionPatterns.length;
6059            boolean allowed = false;
6060            for (int i=0; i<N; i++) {
6061                if (pi.uriPermissionPatterns[i] != null
6062                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6063                    allowed = true;
6064                    break;
6065                }
6066            }
6067            if (!allowed) {
6068                throw new SecurityException("Provider " + pi.packageName
6069                        + "/" + pi.name
6070                        + " does not allow granting of permission to path of Uri "
6071                        + uri);
6072            }
6073        }
6074
6075        // Third...  does the caller itself have permission to access
6076        // this uri?
6077        if (callingUid != Process.myUid()) {
6078            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6079                // Require they hold a strong enough Uri permission
6080                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6081                        : UriPermission.STRENGTH_OWNED;
6082                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6083                    throw new SecurityException("Uid " + callingUid
6084                            + " does not have permission to uri " + uri);
6085                }
6086            }
6087        }
6088
6089        return targetUid;
6090    }
6091
6092    @Override
6093    public int checkGrantUriPermission(int callingUid, String targetPkg,
6094            Uri uri, int modeFlags) {
6095        enforceNotIsolatedCaller("checkGrantUriPermission");
6096        synchronized(this) {
6097            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6098        }
6099    }
6100
6101    void grantUriPermissionUncheckedLocked(
6102            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6103        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6104        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6105                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6106        if (modeFlags == 0) {
6107            return;
6108        }
6109
6110        // So here we are: the caller has the assumed permission
6111        // to the uri, and the target doesn't.  Let's now give this to
6112        // the target.
6113
6114        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6115                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6116
6117        final String authority = uri.getAuthority();
6118        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6119        if (pi == null) {
6120            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6121            return;
6122        }
6123
6124        final UriPermission perm = findOrCreateUriPermissionLocked(
6125                pi.packageName, targetPkg, targetUid, uri);
6126        perm.grantModes(modeFlags, persistable, owner);
6127    }
6128
6129    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6130            int modeFlags, UriPermissionOwner owner) {
6131        if (targetPkg == null) {
6132            throw new NullPointerException("targetPkg");
6133        }
6134
6135        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6136        if (targetUid < 0) {
6137            return;
6138        }
6139
6140        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6141    }
6142
6143    static class NeededUriGrants extends ArrayList<Uri> {
6144        final String targetPkg;
6145        final int targetUid;
6146        final int flags;
6147
6148        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6149            this.targetPkg = targetPkg;
6150            this.targetUid = targetUid;
6151            this.flags = flags;
6152        }
6153    }
6154
6155    /**
6156     * Like checkGrantUriPermissionLocked, but takes an Intent.
6157     */
6158    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6159            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6160        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6161                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6162                + " clip=" + (intent != null ? intent.getClipData() : null)
6163                + " from " + intent + "; flags=0x"
6164                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6165
6166        if (targetPkg == null) {
6167            throw new NullPointerException("targetPkg");
6168        }
6169
6170        if (intent == null) {
6171            return null;
6172        }
6173        Uri data = intent.getData();
6174        ClipData clip = intent.getClipData();
6175        if (data == null && clip == null) {
6176            return null;
6177        }
6178
6179        if (data != null) {
6180            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6181                mode, needed != null ? needed.targetUid : -1);
6182            if (targetUid > 0) {
6183                if (needed == null) {
6184                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6185                }
6186                needed.add(data);
6187            }
6188        }
6189        if (clip != null) {
6190            for (int i=0; i<clip.getItemCount(); i++) {
6191                Uri uri = clip.getItemAt(i).getUri();
6192                if (uri != null) {
6193                    int targetUid = -1;
6194                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6195                            mode, needed != null ? needed.targetUid : -1);
6196                    if (targetUid > 0) {
6197                        if (needed == null) {
6198                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6199                        }
6200                        needed.add(uri);
6201                    }
6202                } else {
6203                    Intent clipIntent = clip.getItemAt(i).getIntent();
6204                    if (clipIntent != null) {
6205                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6206                                callingUid, targetPkg, clipIntent, mode, needed);
6207                        if (newNeeded != null) {
6208                            needed = newNeeded;
6209                        }
6210                    }
6211                }
6212            }
6213        }
6214
6215        return needed;
6216    }
6217
6218    /**
6219     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6220     */
6221    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6222            UriPermissionOwner owner) {
6223        if (needed != null) {
6224            for (int i=0; i<needed.size(); i++) {
6225                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6226                        needed.get(i), needed.flags, owner);
6227            }
6228        }
6229    }
6230
6231    void grantUriPermissionFromIntentLocked(int callingUid,
6232            String targetPkg, Intent intent, UriPermissionOwner owner) {
6233        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6234                intent, intent != null ? intent.getFlags() : 0, null);
6235        if (needed == null) {
6236            return;
6237        }
6238
6239        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6240    }
6241
6242    @Override
6243    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6244            Uri uri, int modeFlags) {
6245        enforceNotIsolatedCaller("grantUriPermission");
6246        synchronized(this) {
6247            final ProcessRecord r = getRecordForAppLocked(caller);
6248            if (r == null) {
6249                throw new SecurityException("Unable to find app for caller "
6250                        + caller
6251                        + " when granting permission to uri " + uri);
6252            }
6253            if (targetPkg == null) {
6254                throw new IllegalArgumentException("null target");
6255            }
6256            if (uri == null) {
6257                throw new IllegalArgumentException("null uri");
6258            }
6259
6260            // Persistable only supported through Intents
6261            Preconditions.checkFlagsArgument(modeFlags,
6262                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6263
6264            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6265                    null);
6266        }
6267    }
6268
6269    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6270        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6271                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6272            ArrayMap<Uri, UriPermission> perms
6273                    = mGrantedUriPermissions.get(perm.targetUid);
6274            if (perms != null) {
6275                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6276                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6277                perms.remove(perm.uri);
6278                if (perms.size() == 0) {
6279                    mGrantedUriPermissions.remove(perm.targetUid);
6280                }
6281            }
6282        }
6283    }
6284
6285    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6286        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6287
6288        final IPackageManager pm = AppGlobals.getPackageManager();
6289        final String authority = uri.getAuthority();
6290        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6291        if (pi == null) {
6292            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6293            return;
6294        }
6295
6296        // Does the caller have this permission on the URI?
6297        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6298            // Right now, if you are not the original owner of the permission,
6299            // you are not allowed to revoke it.
6300            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6301                throw new SecurityException("Uid " + callingUid
6302                        + " does not have permission to uri " + uri);
6303            //}
6304        }
6305
6306        boolean persistChanged = false;
6307
6308        // Go through all of the permissions and remove any that match.
6309        final List<String> SEGMENTS = uri.getPathSegments();
6310        if (SEGMENTS != null) {
6311            final int NS = SEGMENTS.size();
6312            int N = mGrantedUriPermissions.size();
6313            for (int i=0; i<N; i++) {
6314                ArrayMap<Uri, UriPermission> perms
6315                        = mGrantedUriPermissions.valueAt(i);
6316                Iterator<UriPermission> it = perms.values().iterator();
6317            toploop:
6318                while (it.hasNext()) {
6319                    UriPermission perm = it.next();
6320                    Uri targetUri = perm.uri;
6321                    if (!authority.equals(targetUri.getAuthority())) {
6322                        continue;
6323                    }
6324                    List<String> targetSegments = targetUri.getPathSegments();
6325                    if (targetSegments == null) {
6326                        continue;
6327                    }
6328                    if (targetSegments.size() < NS) {
6329                        continue;
6330                    }
6331                    for (int j=0; j<NS; j++) {
6332                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6333                            continue toploop;
6334                        }
6335                    }
6336                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6337                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6338                    persistChanged |= perm.clearModes(modeFlags, true);
6339                    if (perm.modeFlags == 0) {
6340                        it.remove();
6341                    }
6342                }
6343                if (perms.size() == 0) {
6344                    mGrantedUriPermissions.remove(
6345                            mGrantedUriPermissions.keyAt(i));
6346                    N--;
6347                    i--;
6348                }
6349            }
6350        }
6351
6352        if (persistChanged) {
6353            schedulePersistUriGrants();
6354        }
6355    }
6356
6357    @Override
6358    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6359            int modeFlags) {
6360        enforceNotIsolatedCaller("revokeUriPermission");
6361        synchronized(this) {
6362            final ProcessRecord r = getRecordForAppLocked(caller);
6363            if (r == null) {
6364                throw new SecurityException("Unable to find app for caller "
6365                        + caller
6366                        + " when revoking permission to uri " + uri);
6367            }
6368            if (uri == null) {
6369                Slog.w(TAG, "revokeUriPermission: null uri");
6370                return;
6371            }
6372
6373            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6374                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6375            if (modeFlags == 0) {
6376                return;
6377            }
6378
6379            final IPackageManager pm = AppGlobals.getPackageManager();
6380            final String authority = uri.getAuthority();
6381            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6382            if (pi == null) {
6383                Slog.w(TAG, "No content provider found for permission revoke: "
6384                        + uri.toSafeString());
6385                return;
6386            }
6387
6388            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6389        }
6390    }
6391
6392    /**
6393     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6394     * given package.
6395     *
6396     * @param packageName Package name to match, or {@code null} to apply to all
6397     *            packages.
6398     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6399     *            to all users.
6400     * @param persistable If persistable grants should be removed.
6401     */
6402    private void removeUriPermissionsForPackageLocked(
6403            String packageName, int userHandle, boolean persistable) {
6404        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6405            throw new IllegalArgumentException("Must narrow by either package or user");
6406        }
6407
6408        boolean persistChanged = false;
6409
6410        final int size = mGrantedUriPermissions.size();
6411        for (int i = 0; i < size; i++) {
6412            // Only inspect grants matching user
6413            if (userHandle == UserHandle.USER_ALL
6414                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6415                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6416                        .values().iterator();
6417                while (it.hasNext()) {
6418                    final UriPermission perm = it.next();
6419
6420                    // Only inspect grants matching package
6421                    if (packageName == null || perm.sourcePkg.equals(packageName)
6422                            || perm.targetPkg.equals(packageName)) {
6423                        persistChanged |= perm.clearModes(~0, persistable);
6424
6425                        // Only remove when no modes remain; any persisted grants
6426                        // will keep this alive.
6427                        if (perm.modeFlags == 0) {
6428                            it.remove();
6429                        }
6430                    }
6431                }
6432            }
6433        }
6434
6435        if (persistChanged) {
6436            schedulePersistUriGrants();
6437        }
6438    }
6439
6440    @Override
6441    public IBinder newUriPermissionOwner(String name) {
6442        enforceNotIsolatedCaller("newUriPermissionOwner");
6443        synchronized(this) {
6444            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6445            return owner.getExternalTokenLocked();
6446        }
6447    }
6448
6449    @Override
6450    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6451            Uri uri, int modeFlags) {
6452        synchronized(this) {
6453            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6454            if (owner == null) {
6455                throw new IllegalArgumentException("Unknown owner: " + token);
6456            }
6457            if (fromUid != Binder.getCallingUid()) {
6458                if (Binder.getCallingUid() != Process.myUid()) {
6459                    // Only system code can grant URI permissions on behalf
6460                    // of other users.
6461                    throw new SecurityException("nice try");
6462                }
6463            }
6464            if (targetPkg == null) {
6465                throw new IllegalArgumentException("null target");
6466            }
6467            if (uri == null) {
6468                throw new IllegalArgumentException("null uri");
6469            }
6470
6471            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6472        }
6473    }
6474
6475    @Override
6476    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6477        synchronized(this) {
6478            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6479            if (owner == null) {
6480                throw new IllegalArgumentException("Unknown owner: " + token);
6481            }
6482
6483            if (uri == null) {
6484                owner.removeUriPermissionsLocked(mode);
6485            } else {
6486                owner.removeUriPermissionLocked(uri, mode);
6487            }
6488        }
6489    }
6490
6491    private void schedulePersistUriGrants() {
6492        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6493            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6494                    10 * DateUtils.SECOND_IN_MILLIS);
6495        }
6496    }
6497
6498    private void writeGrantedUriPermissions() {
6499        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6500
6501        // Snapshot permissions so we can persist without lock
6502        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6503        synchronized (this) {
6504            final int size = mGrantedUriPermissions.size();
6505            for (int i = 0 ; i < size; i++) {
6506                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6507                    if (perm.persistedModeFlags != 0) {
6508                        persist.add(perm.snapshot());
6509                    }
6510                }
6511            }
6512        }
6513
6514        FileOutputStream fos = null;
6515        try {
6516            fos = mGrantFile.startWrite();
6517
6518            XmlSerializer out = new FastXmlSerializer();
6519            out.setOutput(fos, "utf-8");
6520            out.startDocument(null, true);
6521            out.startTag(null, TAG_URI_GRANTS);
6522            for (UriPermission.Snapshot perm : persist) {
6523                out.startTag(null, TAG_URI_GRANT);
6524                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6525                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6526                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6527                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6528                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6529                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6530                out.endTag(null, TAG_URI_GRANT);
6531            }
6532            out.endTag(null, TAG_URI_GRANTS);
6533            out.endDocument();
6534
6535            mGrantFile.finishWrite(fos);
6536        } catch (IOException e) {
6537            if (fos != null) {
6538                mGrantFile.failWrite(fos);
6539            }
6540        }
6541    }
6542
6543    private void readGrantedUriPermissionsLocked() {
6544        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6545
6546        final long now = System.currentTimeMillis();
6547
6548        FileInputStream fis = null;
6549        try {
6550            fis = mGrantFile.openRead();
6551            final XmlPullParser in = Xml.newPullParser();
6552            in.setInput(fis, null);
6553
6554            int type;
6555            while ((type = in.next()) != END_DOCUMENT) {
6556                final String tag = in.getName();
6557                if (type == START_TAG) {
6558                    if (TAG_URI_GRANT.equals(tag)) {
6559                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6560                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6561                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6562                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6563                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6564                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6565
6566                        // Sanity check that provider still belongs to source package
6567                        final ProviderInfo pi = getProviderInfoLocked(
6568                                uri.getAuthority(), userHandle);
6569                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6570                            int targetUid = -1;
6571                            try {
6572                                targetUid = AppGlobals.getPackageManager()
6573                                        .getPackageUid(targetPkg, userHandle);
6574                            } catch (RemoteException e) {
6575                            }
6576                            if (targetUid != -1) {
6577                                final UriPermission perm = findOrCreateUriPermissionLocked(
6578                                        sourcePkg, targetPkg, targetUid, uri);
6579                                perm.initPersistedModes(modeFlags, createdTime);
6580                            }
6581                        } else {
6582                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6583                                    + " but instead found " + pi);
6584                        }
6585                    }
6586                }
6587            }
6588        } catch (FileNotFoundException e) {
6589            // Missing grants is okay
6590        } catch (IOException e) {
6591            Log.wtf(TAG, "Failed reading Uri grants", e);
6592        } catch (XmlPullParserException e) {
6593            Log.wtf(TAG, "Failed reading Uri grants", e);
6594        } finally {
6595            IoUtils.closeQuietly(fis);
6596        }
6597    }
6598
6599    @Override
6600    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6601        enforceNotIsolatedCaller("takePersistableUriPermission");
6602
6603        Preconditions.checkFlagsArgument(modeFlags,
6604                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6605
6606        synchronized (this) {
6607            final int callingUid = Binder.getCallingUid();
6608            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6609            if (perm == null) {
6610                throw new SecurityException("No permission grant found for UID " + callingUid
6611                        + " and Uri " + uri.toSafeString());
6612            }
6613
6614            boolean persistChanged = perm.takePersistableModes(modeFlags);
6615            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6616
6617            if (persistChanged) {
6618                schedulePersistUriGrants();
6619            }
6620        }
6621    }
6622
6623    @Override
6624    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6625        enforceNotIsolatedCaller("releasePersistableUriPermission");
6626
6627        Preconditions.checkFlagsArgument(modeFlags,
6628                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6629
6630        synchronized (this) {
6631            final int callingUid = Binder.getCallingUid();
6632
6633            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6634            if (perm == null) {
6635                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6636                        + uri.toSafeString());
6637                return;
6638            }
6639
6640            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6641            removeUriPermissionIfNeededLocked(perm);
6642            if (persistChanged) {
6643                schedulePersistUriGrants();
6644            }
6645        }
6646    }
6647
6648    /**
6649     * Prune any older {@link UriPermission} for the given UID until outstanding
6650     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6651     *
6652     * @return if any mutations occured that require persisting.
6653     */
6654    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6655        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6656        if (perms == null) return false;
6657        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6658
6659        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6660        for (UriPermission perm : perms.values()) {
6661            if (perm.persistedModeFlags != 0) {
6662                persisted.add(perm);
6663            }
6664        }
6665
6666        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6667        if (trimCount <= 0) return false;
6668
6669        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6670        for (int i = 0; i < trimCount; i++) {
6671            final UriPermission perm = persisted.get(i);
6672
6673            if (DEBUG_URI_PERMISSION) {
6674                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6675            }
6676
6677            perm.releasePersistableModes(~0);
6678            removeUriPermissionIfNeededLocked(perm);
6679        }
6680
6681        return true;
6682    }
6683
6684    @Override
6685    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6686            String packageName, boolean incoming) {
6687        enforceNotIsolatedCaller("getPersistedUriPermissions");
6688        Preconditions.checkNotNull(packageName, "packageName");
6689
6690        final int callingUid = Binder.getCallingUid();
6691        final IPackageManager pm = AppGlobals.getPackageManager();
6692        try {
6693            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6694            if (packageUid != callingUid) {
6695                throw new SecurityException(
6696                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6697            }
6698        } catch (RemoteException e) {
6699            throw new SecurityException("Failed to verify package name ownership");
6700        }
6701
6702        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6703        synchronized (this) {
6704            if (incoming) {
6705                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6706                if (perms == null) {
6707                    Slog.w(TAG, "No permission grants found for " + packageName);
6708                } else {
6709                    final int size = perms.size();
6710                    for (int i = 0; i < size; i++) {
6711                        final UriPermission perm = perms.valueAt(i);
6712                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6713                            result.add(perm.buildPersistedPublicApiObject());
6714                        }
6715                    }
6716                }
6717            } else {
6718                final int size = mGrantedUriPermissions.size();
6719                for (int i = 0; i < size; i++) {
6720                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6721                    final int permsSize = perms.size();
6722                    for (int j = 0; j < permsSize; j++) {
6723                        final UriPermission perm = perms.valueAt(j);
6724                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6725                            result.add(perm.buildPersistedPublicApiObject());
6726                        }
6727                    }
6728                }
6729            }
6730        }
6731        return new ParceledListSlice<android.content.UriPermission>(result);
6732    }
6733
6734    @Override
6735    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6736        synchronized (this) {
6737            ProcessRecord app =
6738                who != null ? getRecordForAppLocked(who) : null;
6739            if (app == null) return;
6740
6741            Message msg = Message.obtain();
6742            msg.what = WAIT_FOR_DEBUGGER_MSG;
6743            msg.obj = app;
6744            msg.arg1 = waiting ? 1 : 0;
6745            mHandler.sendMessage(msg);
6746        }
6747    }
6748
6749    @Override
6750    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6751        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6752        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6753        outInfo.availMem = Process.getFreeMemory();
6754        outInfo.totalMem = Process.getTotalMemory();
6755        outInfo.threshold = homeAppMem;
6756        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6757        outInfo.hiddenAppThreshold = cachedAppMem;
6758        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6759                ProcessList.SERVICE_ADJ);
6760        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6761                ProcessList.VISIBLE_APP_ADJ);
6762        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6763                ProcessList.FOREGROUND_APP_ADJ);
6764    }
6765
6766    // =========================================================
6767    // TASK MANAGEMENT
6768    // =========================================================
6769
6770    @Override
6771    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6772                         IThumbnailReceiver receiver) {
6773        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6774
6775        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6776        ActivityRecord topRecord = null;
6777
6778        synchronized(this) {
6779            if (localLOGV) Slog.v(
6780                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6781                + ", receiver=" + receiver);
6782
6783            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6784                    != PackageManager.PERMISSION_GRANTED) {
6785                if (receiver != null) {
6786                    // If the caller wants to wait for pending thumbnails,
6787                    // it ain't gonna get them.
6788                    try {
6789                        receiver.finished();
6790                    } catch (RemoteException ex) {
6791                    }
6792                }
6793                String msg = "Permission Denial: getTasks() from pid="
6794                        + Binder.getCallingPid()
6795                        + ", uid=" + Binder.getCallingUid()
6796                        + " requires " + android.Manifest.permission.GET_TASKS;
6797                Slog.w(TAG, msg);
6798                throw new SecurityException(msg);
6799            }
6800
6801            // TODO: Improve with MRU list from all ActivityStacks.
6802            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6803
6804            if (!pending.pendingRecords.isEmpty()) {
6805                mPendingThumbnails.add(pending);
6806            }
6807        }
6808
6809        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6810
6811        if (topRecord != null) {
6812            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6813            try {
6814                IApplicationThread topThumbnail = topRecord.app.thread;
6815                topThumbnail.requestThumbnail(topRecord.appToken);
6816            } catch (Exception e) {
6817                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6818                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6819            }
6820        }
6821
6822        if (pending == null && receiver != null) {
6823            // In this case all thumbnails were available and the client
6824            // is being asked to be told when the remaining ones come in...
6825            // which is unusually, since the top-most currently running
6826            // activity should never have a canned thumbnail!  Oh well.
6827            try {
6828                receiver.finished();
6829            } catch (RemoteException ex) {
6830            }
6831        }
6832
6833        return list;
6834    }
6835
6836    TaskRecord getMostRecentTask() {
6837        return mRecentTasks.get(0);
6838    }
6839
6840    @Override
6841    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6842            int flags, int userId) {
6843        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6844                false, true, "getRecentTasks", null);
6845
6846        synchronized (this) {
6847            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6848                    "getRecentTasks()");
6849            final boolean detailed = checkCallingPermission(
6850                    android.Manifest.permission.GET_DETAILED_TASKS)
6851                    == PackageManager.PERMISSION_GRANTED;
6852
6853            IPackageManager pm = AppGlobals.getPackageManager();
6854
6855            final int N = mRecentTasks.size();
6856            ArrayList<ActivityManager.RecentTaskInfo> res
6857                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6858                            maxNum < N ? maxNum : N);
6859
6860            final Set<Integer> includedUsers;
6861            if ((flags & ActivityManager.RECENT_INCLUDE_RELATED) != 0) {
6862                includedUsers = getRelatedUsersLocked(userId);
6863            } else {
6864                includedUsers = new HashSet<Integer>();
6865            }
6866            includedUsers.add(Integer.valueOf(userId));
6867            for (int i=0; i<N && maxNum > 0; i++) {
6868                TaskRecord tr = mRecentTasks.get(i);
6869                // Only add calling user or related users recent tasks
6870                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6871
6872                // Return the entry if desired by the caller.  We always return
6873                // the first entry, because callers always expect this to be the
6874                // foreground app.  We may filter others if the caller has
6875                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6876                // we should exclude the entry.
6877
6878                if (i == 0
6879                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6880                        || (tr.intent == null)
6881                        || ((tr.intent.getFlags()
6882                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6883                    ActivityManager.RecentTaskInfo rti
6884                            = new ActivityManager.RecentTaskInfo();
6885                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6886                    rti.persistentId = tr.taskId;
6887                    rti.baseIntent = new Intent(
6888                            tr.intent != null ? tr.intent : tr.affinityIntent);
6889                    if (!detailed) {
6890                        rti.baseIntent.replaceExtras((Bundle)null);
6891                    }
6892                    rti.origActivity = tr.origActivity;
6893                    rti.description = tr.lastDescription;
6894                    rti.stackId = tr.stack.mStackId;
6895                    rti.userId = tr.userId;
6896
6897                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6898                        // Check whether this activity is currently available.
6899                        try {
6900                            if (rti.origActivity != null) {
6901                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6902                                        == null) {
6903                                    continue;
6904                                }
6905                            } else if (rti.baseIntent != null) {
6906                                if (pm.queryIntentActivities(rti.baseIntent,
6907                                        null, 0, userId) == null) {
6908                                    continue;
6909                                }
6910                            }
6911                        } catch (RemoteException e) {
6912                            // Will never happen.
6913                        }
6914                    }
6915
6916                    res.add(rti);
6917                    maxNum--;
6918                }
6919            }
6920            return res;
6921        }
6922    }
6923
6924    private TaskRecord recentTaskForIdLocked(int id) {
6925        final int N = mRecentTasks.size();
6926            for (int i=0; i<N; i++) {
6927                TaskRecord tr = mRecentTasks.get(i);
6928                if (tr.taskId == id) {
6929                    return tr;
6930                }
6931            }
6932            return null;
6933    }
6934
6935    @Override
6936    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6937        synchronized (this) {
6938            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6939                    "getTaskThumbnails()");
6940            TaskRecord tr = recentTaskForIdLocked(id);
6941            if (tr != null) {
6942                return tr.getTaskThumbnailsLocked();
6943            }
6944        }
6945        return null;
6946    }
6947
6948    @Override
6949    public Bitmap getTaskTopThumbnail(int id) {
6950        synchronized (this) {
6951            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6952                    "getTaskTopThumbnail()");
6953            TaskRecord tr = recentTaskForIdLocked(id);
6954            if (tr != null) {
6955                return tr.getTaskTopThumbnailLocked();
6956            }
6957        }
6958        return null;
6959    }
6960
6961    @Override
6962    public boolean removeSubTask(int taskId, int subTaskIndex) {
6963        synchronized (this) {
6964            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6965                    "removeSubTask()");
6966            long ident = Binder.clearCallingIdentity();
6967            try {
6968                TaskRecord tr = recentTaskForIdLocked(taskId);
6969                if (tr != null) {
6970                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6971                }
6972                return false;
6973            } finally {
6974                Binder.restoreCallingIdentity(ident);
6975            }
6976        }
6977    }
6978
6979    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6980        if (!pr.killedByAm) {
6981            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6982            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6983                    pr.processName, pr.setAdj, reason);
6984            pr.killedByAm = true;
6985            Process.killProcessQuiet(pr.pid);
6986        }
6987    }
6988
6989    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6990        tr.disposeThumbnail();
6991        mRecentTasks.remove(tr);
6992        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6993        Intent baseIntent = new Intent(
6994                tr.intent != null ? tr.intent : tr.affinityIntent);
6995        ComponentName component = baseIntent.getComponent();
6996        if (component == null) {
6997            Slog.w(TAG, "Now component for base intent of task: " + tr);
6998            return;
6999        }
7000
7001        // Find any running services associated with this app.
7002        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7003
7004        if (killProcesses) {
7005            // Find any running processes associated with this app.
7006            final String pkg = component.getPackageName();
7007            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7008            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7009            for (int i=0; i<pmap.size(); i++) {
7010                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7011                for (int j=0; j<uids.size(); j++) {
7012                    ProcessRecord proc = uids.valueAt(j);
7013                    if (proc.userId != tr.userId) {
7014                        continue;
7015                    }
7016                    if (!proc.pkgList.containsKey(pkg)) {
7017                        continue;
7018                    }
7019                    procs.add(proc);
7020                }
7021            }
7022
7023            // Kill the running processes.
7024            for (int i=0; i<procs.size(); i++) {
7025                ProcessRecord pr = procs.get(i);
7026                if (pr == mHomeProcess) {
7027                    // Don't kill the home process along with tasks from the same package.
7028                    continue;
7029                }
7030                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7031                    killUnneededProcessLocked(pr, "remove task");
7032                } else {
7033                    pr.waitingToKill = "remove task";
7034                }
7035            }
7036        }
7037    }
7038
7039    @Override
7040    public boolean removeTask(int taskId, int flags) {
7041        synchronized (this) {
7042            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7043                    "removeTask()");
7044            long ident = Binder.clearCallingIdentity();
7045            try {
7046                TaskRecord tr = recentTaskForIdLocked(taskId);
7047                if (tr != null) {
7048                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7049                    if (r != null) {
7050                        cleanUpRemovedTaskLocked(tr, flags);
7051                        return true;
7052                    }
7053                    if (tr.mActivities.size() == 0) {
7054                        // Caller is just removing a recent task that is
7055                        // not actively running.  That is easy!
7056                        cleanUpRemovedTaskLocked(tr, flags);
7057                        return true;
7058                    }
7059                    Slog.w(TAG, "removeTask: task " + taskId
7060                            + " does not have activities to remove, "
7061                            + " but numActivities=" + tr.numActivities
7062                            + ": " + tr);
7063                }
7064            } finally {
7065                Binder.restoreCallingIdentity(ident);
7066            }
7067        }
7068        return false;
7069    }
7070
7071    /**
7072     * TODO: Add mController hook
7073     */
7074    @Override
7075    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7076        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7077                "moveTaskToFront()");
7078
7079        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7080        synchronized(this) {
7081            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7082                    Binder.getCallingUid(), "Task to front")) {
7083                ActivityOptions.abort(options);
7084                return;
7085            }
7086            final long origId = Binder.clearCallingIdentity();
7087            try {
7088                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7089                if (task == null) {
7090                    return;
7091                }
7092                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7093                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7094                    return;
7095                }
7096                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7097            } finally {
7098                Binder.restoreCallingIdentity(origId);
7099            }
7100            ActivityOptions.abort(options);
7101        }
7102    }
7103
7104    @Override
7105    public void moveTaskToBack(int taskId) {
7106        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7107                "moveTaskToBack()");
7108
7109        synchronized(this) {
7110            TaskRecord tr = recentTaskForIdLocked(taskId);
7111            if (tr != null) {
7112                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7113                ActivityStack stack = tr.stack;
7114                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7115                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7116                            Binder.getCallingUid(), "Task to back")) {
7117                        return;
7118                    }
7119                }
7120                final long origId = Binder.clearCallingIdentity();
7121                try {
7122                    stack.moveTaskToBackLocked(taskId, null);
7123                } finally {
7124                    Binder.restoreCallingIdentity(origId);
7125                }
7126            }
7127        }
7128    }
7129
7130    /**
7131     * Moves an activity, and all of the other activities within the same task, to the bottom
7132     * of the history stack.  The activity's order within the task is unchanged.
7133     *
7134     * @param token A reference to the activity we wish to move
7135     * @param nonRoot If false then this only works if the activity is the root
7136     *                of a task; if true it will work for any activity in a task.
7137     * @return Returns true if the move completed, false if not.
7138     */
7139    @Override
7140    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7141        enforceNotIsolatedCaller("moveActivityTaskToBack");
7142        synchronized(this) {
7143            final long origId = Binder.clearCallingIdentity();
7144            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7145            if (taskId >= 0) {
7146                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7147            }
7148            Binder.restoreCallingIdentity(origId);
7149        }
7150        return false;
7151    }
7152
7153    @Override
7154    public void moveTaskBackwards(int task) {
7155        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7156                "moveTaskBackwards()");
7157
7158        synchronized(this) {
7159            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7160                    Binder.getCallingUid(), "Task backwards")) {
7161                return;
7162            }
7163            final long origId = Binder.clearCallingIdentity();
7164            moveTaskBackwardsLocked(task);
7165            Binder.restoreCallingIdentity(origId);
7166        }
7167    }
7168
7169    private final void moveTaskBackwardsLocked(int task) {
7170        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7171    }
7172
7173    @Override
7174    public IBinder getHomeActivityToken() throws RemoteException {
7175        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7176                "getHomeActivityToken()");
7177        synchronized (this) {
7178            return mStackSupervisor.getHomeActivityToken();
7179        }
7180    }
7181
7182    @Override
7183    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7184            IActivityContainerCallback callback) throws RemoteException {
7185        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7186                "createActivityContainer()");
7187        synchronized (this) {
7188            if (parentActivityToken == null) {
7189                throw new IllegalArgumentException("parent token must not be null");
7190            }
7191            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7192            if (r == null) {
7193                return null;
7194            }
7195            return mStackSupervisor.createActivityContainer(r, callback);
7196        }
7197    }
7198
7199    @Override
7200    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7201        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7202                "deleteActivityContainer()");
7203        synchronized (this) {
7204            mStackSupervisor.deleteActivityContainer(container);
7205        }
7206    }
7207
7208    @Override
7209    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7210            throws RemoteException {
7211        synchronized (this) {
7212            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7213            if (stack != null) {
7214                return stack.mActivityContainer;
7215            }
7216            return null;
7217        }
7218    }
7219
7220    @Override
7221    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7222        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7223                "moveTaskToStack()");
7224        if (stackId == HOME_STACK_ID) {
7225            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7226                    new RuntimeException("here").fillInStackTrace());
7227        }
7228        synchronized (this) {
7229            long ident = Binder.clearCallingIdentity();
7230            try {
7231                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7232                        + stackId + " toTop=" + toTop);
7233                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7234            } finally {
7235                Binder.restoreCallingIdentity(ident);
7236            }
7237        }
7238    }
7239
7240    @Override
7241    public void resizeStack(int stackBoxId, Rect bounds) {
7242        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7243                "resizeStackBox()");
7244        long ident = Binder.clearCallingIdentity();
7245        try {
7246            mWindowManager.resizeStack(stackBoxId, bounds);
7247        } finally {
7248            Binder.restoreCallingIdentity(ident);
7249        }
7250    }
7251
7252    @Override
7253    public List<StackInfo> getAllStackInfos() {
7254        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7255                "getAllStackInfos()");
7256        long ident = Binder.clearCallingIdentity();
7257        try {
7258            synchronized (this) {
7259                return mStackSupervisor.getAllStackInfosLocked();
7260            }
7261        } finally {
7262            Binder.restoreCallingIdentity(ident);
7263        }
7264    }
7265
7266    @Override
7267    public StackInfo getStackInfo(int stackId) {
7268        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7269                "getStackInfo()");
7270        long ident = Binder.clearCallingIdentity();
7271        try {
7272            synchronized (this) {
7273                return mStackSupervisor.getStackInfoLocked(stackId);
7274            }
7275        } finally {
7276            Binder.restoreCallingIdentity(ident);
7277        }
7278    }
7279
7280    @Override
7281    public boolean isInHomeStack(int taskId) {
7282        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7283                "getStackInfo()");
7284        long ident = Binder.clearCallingIdentity();
7285        try {
7286            synchronized (this) {
7287                TaskRecord tr = recentTaskForIdLocked(taskId);
7288                if (tr != null) {
7289                    return tr.stack.isHomeStack();
7290                }
7291            }
7292        } finally {
7293            Binder.restoreCallingIdentity(ident);
7294        }
7295        return false;
7296    }
7297
7298    @Override
7299    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7300        synchronized(this) {
7301            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7302        }
7303    }
7304
7305    private boolean isLockTaskAuthorized(ComponentName name) {
7306//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7307//                "startLockTaskMode()");
7308//        DevicePolicyManager dpm = (DevicePolicyManager)
7309//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7310//        return dpm != null && dpm.isLockTaskPermitted(name);
7311        return true;
7312    }
7313
7314    private void startLockTaskMode(TaskRecord task) {
7315        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7316            return;
7317        }
7318        long ident = Binder.clearCallingIdentity();
7319        try {
7320            synchronized (this) {
7321                // Since we lost lock on task, make sure it is still there.
7322                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7323                if (task != null) {
7324                    mStackSupervisor.setLockTaskModeLocked(task);
7325                }
7326            }
7327        } finally {
7328            Binder.restoreCallingIdentity(ident);
7329        }
7330    }
7331
7332    @Override
7333    public void startLockTaskMode(int taskId) {
7334        long ident = Binder.clearCallingIdentity();
7335        try {
7336            final TaskRecord task;
7337            synchronized (this) {
7338                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7339            }
7340            if (task != null) {
7341                startLockTaskMode(task);
7342            }
7343        } finally {
7344            Binder.restoreCallingIdentity(ident);
7345        }
7346    }
7347
7348    @Override
7349    public void startLockTaskMode(IBinder token) {
7350        long ident = Binder.clearCallingIdentity();
7351        try {
7352            final TaskRecord task;
7353            synchronized (this) {
7354                final ActivityRecord r = ActivityRecord.forToken(token);
7355                if (r == null) {
7356                    return;
7357                }
7358                task = r.task;
7359            }
7360            if (task != null) {
7361                startLockTaskMode(task);
7362            }
7363        } finally {
7364            Binder.restoreCallingIdentity(ident);
7365        }
7366    }
7367
7368    @Override
7369    public void stopLockTaskMode() {
7370//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7371//                "stopLockTaskMode()");
7372        synchronized (this) {
7373            mStackSupervisor.setLockTaskModeLocked(null);
7374        }
7375    }
7376
7377    @Override
7378    public boolean isInLockTaskMode() {
7379        synchronized (this) {
7380            return mStackSupervisor.isInLockTaskMode();
7381        }
7382    }
7383
7384    // =========================================================
7385    // THUMBNAILS
7386    // =========================================================
7387
7388    public void reportThumbnail(IBinder token,
7389            Bitmap thumbnail, CharSequence description) {
7390        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7391        final long origId = Binder.clearCallingIdentity();
7392        sendPendingThumbnail(null, token, thumbnail, description, true);
7393        Binder.restoreCallingIdentity(origId);
7394    }
7395
7396    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7397            Bitmap thumbnail, CharSequence description, boolean always) {
7398        TaskRecord task;
7399        ArrayList<PendingThumbnailsRecord> receivers = null;
7400
7401        //System.out.println("Send pending thumbnail: " + r);
7402
7403        synchronized(this) {
7404            if (r == null) {
7405                r = ActivityRecord.isInStackLocked(token);
7406                if (r == null) {
7407                    return;
7408                }
7409            }
7410            if (thumbnail == null && r.thumbHolder != null) {
7411                thumbnail = r.thumbHolder.lastThumbnail;
7412                description = r.thumbHolder.lastDescription;
7413            }
7414            if (thumbnail == null && !always) {
7415                // If there is no thumbnail, and this entry is not actually
7416                // going away, then abort for now and pick up the next
7417                // thumbnail we get.
7418                return;
7419            }
7420            task = r.task;
7421
7422            int N = mPendingThumbnails.size();
7423            int i=0;
7424            while (i<N) {
7425                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7426                //System.out.println("Looking in " + pr.pendingRecords);
7427                if (pr.pendingRecords.remove(r)) {
7428                    if (receivers == null) {
7429                        receivers = new ArrayList<PendingThumbnailsRecord>();
7430                    }
7431                    receivers.add(pr);
7432                    if (pr.pendingRecords.size() == 0) {
7433                        pr.finished = true;
7434                        mPendingThumbnails.remove(i);
7435                        N--;
7436                        continue;
7437                    }
7438                }
7439                i++;
7440            }
7441        }
7442
7443        if (receivers != null) {
7444            final int N = receivers.size();
7445            for (int i=0; i<N; i++) {
7446                try {
7447                    PendingThumbnailsRecord pr = receivers.get(i);
7448                    pr.receiver.newThumbnail(
7449                        task != null ? task.taskId : -1, thumbnail, description);
7450                    if (pr.finished) {
7451                        pr.receiver.finished();
7452                    }
7453                } catch (Exception e) {
7454                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7455                }
7456            }
7457        }
7458    }
7459
7460    // =========================================================
7461    // CONTENT PROVIDERS
7462    // =========================================================
7463
7464    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7465        List<ProviderInfo> providers = null;
7466        try {
7467            providers = AppGlobals.getPackageManager().
7468                queryContentProviders(app.processName, app.uid,
7469                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7470        } catch (RemoteException ex) {
7471        }
7472        if (DEBUG_MU)
7473            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7474        int userId = app.userId;
7475        if (providers != null) {
7476            int N = providers.size();
7477            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7478            for (int i=0; i<N; i++) {
7479                ProviderInfo cpi =
7480                    (ProviderInfo)providers.get(i);
7481                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7482                        cpi.name, cpi.flags);
7483                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7484                    // This is a singleton provider, but a user besides the
7485                    // default user is asking to initialize a process it runs
7486                    // in...  well, no, it doesn't actually run in this process,
7487                    // it runs in the process of the default user.  Get rid of it.
7488                    providers.remove(i);
7489                    N--;
7490                    i--;
7491                    continue;
7492                }
7493
7494                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7495                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7496                if (cpr == null) {
7497                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7498                    mProviderMap.putProviderByClass(comp, cpr);
7499                }
7500                if (DEBUG_MU)
7501                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7502                app.pubProviders.put(cpi.name, cpr);
7503                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7504                    // Don't add this if it is a platform component that is marked
7505                    // to run in multiple processes, because this is actually
7506                    // part of the framework so doesn't make sense to track as a
7507                    // separate apk in the process.
7508                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7509                }
7510                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7511            }
7512        }
7513        return providers;
7514    }
7515
7516    /**
7517     * Check if {@link ProcessRecord} has a possible chance at accessing the
7518     * given {@link ProviderInfo}. Final permission checking is always done
7519     * in {@link ContentProvider}.
7520     */
7521    private final String checkContentProviderPermissionLocked(
7522            ProviderInfo cpi, ProcessRecord r) {
7523        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7524        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7525        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7526                cpi.applicationInfo.uid, cpi.exported)
7527                == PackageManager.PERMISSION_GRANTED) {
7528            return null;
7529        }
7530        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7531                cpi.applicationInfo.uid, cpi.exported)
7532                == PackageManager.PERMISSION_GRANTED) {
7533            return null;
7534        }
7535
7536        PathPermission[] pps = cpi.pathPermissions;
7537        if (pps != null) {
7538            int i = pps.length;
7539            while (i > 0) {
7540                i--;
7541                PathPermission pp = pps[i];
7542                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7543                        cpi.applicationInfo.uid, cpi.exported)
7544                        == PackageManager.PERMISSION_GRANTED) {
7545                    return null;
7546                }
7547                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7548                        cpi.applicationInfo.uid, cpi.exported)
7549                        == PackageManager.PERMISSION_GRANTED) {
7550                    return null;
7551                }
7552            }
7553        }
7554
7555        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7556        if (perms != null) {
7557            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7558                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7559                    return null;
7560                }
7561            }
7562        }
7563
7564        String msg;
7565        if (!cpi.exported) {
7566            msg = "Permission Denial: opening provider " + cpi.name
7567                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7568                    + ", uid=" + callingUid + ") that is not exported from uid "
7569                    + cpi.applicationInfo.uid;
7570        } else {
7571            msg = "Permission Denial: opening provider " + cpi.name
7572                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7573                    + ", uid=" + callingUid + ") requires "
7574                    + cpi.readPermission + " or " + cpi.writePermission;
7575        }
7576        Slog.w(TAG, msg);
7577        return msg;
7578    }
7579
7580    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7581            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7582        if (r != null) {
7583            for (int i=0; i<r.conProviders.size(); i++) {
7584                ContentProviderConnection conn = r.conProviders.get(i);
7585                if (conn.provider == cpr) {
7586                    if (DEBUG_PROVIDER) Slog.v(TAG,
7587                            "Adding provider requested by "
7588                            + r.processName + " from process "
7589                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7590                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7591                    if (stable) {
7592                        conn.stableCount++;
7593                        conn.numStableIncs++;
7594                    } else {
7595                        conn.unstableCount++;
7596                        conn.numUnstableIncs++;
7597                    }
7598                    return conn;
7599                }
7600            }
7601            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7602            if (stable) {
7603                conn.stableCount = 1;
7604                conn.numStableIncs = 1;
7605            } else {
7606                conn.unstableCount = 1;
7607                conn.numUnstableIncs = 1;
7608            }
7609            cpr.connections.add(conn);
7610            r.conProviders.add(conn);
7611            return conn;
7612        }
7613        cpr.addExternalProcessHandleLocked(externalProcessToken);
7614        return null;
7615    }
7616
7617    boolean decProviderCountLocked(ContentProviderConnection conn,
7618            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7619        if (conn != null) {
7620            cpr = conn.provider;
7621            if (DEBUG_PROVIDER) Slog.v(TAG,
7622                    "Removing provider requested by "
7623                    + conn.client.processName + " from process "
7624                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7625                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7626            if (stable) {
7627                conn.stableCount--;
7628            } else {
7629                conn.unstableCount--;
7630            }
7631            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7632                cpr.connections.remove(conn);
7633                conn.client.conProviders.remove(conn);
7634                return true;
7635            }
7636            return false;
7637        }
7638        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7639        return false;
7640    }
7641
7642    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7643            String name, IBinder token, boolean stable, int userId) {
7644        ContentProviderRecord cpr;
7645        ContentProviderConnection conn = null;
7646        ProviderInfo cpi = null;
7647
7648        synchronized(this) {
7649            ProcessRecord r = null;
7650            if (caller != null) {
7651                r = getRecordForAppLocked(caller);
7652                if (r == null) {
7653                    throw new SecurityException(
7654                            "Unable to find app for caller " + caller
7655                          + " (pid=" + Binder.getCallingPid()
7656                          + ") when getting content provider " + name);
7657                }
7658            }
7659
7660            // First check if this content provider has been published...
7661            cpr = mProviderMap.getProviderByName(name, userId);
7662            boolean providerRunning = cpr != null;
7663            if (providerRunning) {
7664                cpi = cpr.info;
7665                String msg;
7666                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7667                    throw new SecurityException(msg);
7668                }
7669
7670                if (r != null && cpr.canRunHere(r)) {
7671                    // This provider has been published or is in the process
7672                    // of being published...  but it is also allowed to run
7673                    // in the caller's process, so don't make a connection
7674                    // and just let the caller instantiate its own instance.
7675                    ContentProviderHolder holder = cpr.newHolder(null);
7676                    // don't give caller the provider object, it needs
7677                    // to make its own.
7678                    holder.provider = null;
7679                    return holder;
7680                }
7681
7682                final long origId = Binder.clearCallingIdentity();
7683
7684                // In this case the provider instance already exists, so we can
7685                // return it right away.
7686                conn = incProviderCountLocked(r, cpr, token, stable);
7687                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7688                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7689                        // If this is a perceptible app accessing the provider,
7690                        // make sure to count it as being accessed and thus
7691                        // back up on the LRU list.  This is good because
7692                        // content providers are often expensive to start.
7693                        updateLruProcessLocked(cpr.proc, false, null);
7694                    }
7695                }
7696
7697                if (cpr.proc != null) {
7698                    if (false) {
7699                        if (cpr.name.flattenToShortString().equals(
7700                                "com.android.providers.calendar/.CalendarProvider2")) {
7701                            Slog.v(TAG, "****************** KILLING "
7702                                + cpr.name.flattenToShortString());
7703                            Process.killProcess(cpr.proc.pid);
7704                        }
7705                    }
7706                    boolean success = updateOomAdjLocked(cpr.proc);
7707                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7708                    // NOTE: there is still a race here where a signal could be
7709                    // pending on the process even though we managed to update its
7710                    // adj level.  Not sure what to do about this, but at least
7711                    // the race is now smaller.
7712                    if (!success) {
7713                        // Uh oh...  it looks like the provider's process
7714                        // has been killed on us.  We need to wait for a new
7715                        // process to be started, and make sure its death
7716                        // doesn't kill our process.
7717                        Slog.i(TAG,
7718                                "Existing provider " + cpr.name.flattenToShortString()
7719                                + " is crashing; detaching " + r);
7720                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7721                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7722                        if (!lastRef) {
7723                            // This wasn't the last ref our process had on
7724                            // the provider...  we have now been killed, bail.
7725                            return null;
7726                        }
7727                        providerRunning = false;
7728                        conn = null;
7729                    }
7730                }
7731
7732                Binder.restoreCallingIdentity(origId);
7733            }
7734
7735            boolean singleton;
7736            if (!providerRunning) {
7737                try {
7738                    cpi = AppGlobals.getPackageManager().
7739                        resolveContentProvider(name,
7740                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7741                } catch (RemoteException ex) {
7742                }
7743                if (cpi == null) {
7744                    return null;
7745                }
7746                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7747                        cpi.name, cpi.flags);
7748                if (singleton) {
7749                    userId = 0;
7750                }
7751                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7752
7753                String msg;
7754                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7755                    throw new SecurityException(msg);
7756                }
7757
7758                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7759                        && !cpi.processName.equals("system")) {
7760                    // If this content provider does not run in the system
7761                    // process, and the system is not yet ready to run other
7762                    // processes, then fail fast instead of hanging.
7763                    throw new IllegalArgumentException(
7764                            "Attempt to launch content provider before system ready");
7765                }
7766
7767                // Make sure that the user who owns this provider is started.  If not,
7768                // we don't want to allow it to run.
7769                if (mStartedUsers.get(userId) == null) {
7770                    Slog.w(TAG, "Unable to launch app "
7771                            + cpi.applicationInfo.packageName + "/"
7772                            + cpi.applicationInfo.uid + " for provider "
7773                            + name + ": user " + userId + " is stopped");
7774                    return null;
7775                }
7776
7777                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7778                cpr = mProviderMap.getProviderByClass(comp, userId);
7779                final boolean firstClass = cpr == null;
7780                if (firstClass) {
7781                    try {
7782                        ApplicationInfo ai =
7783                            AppGlobals.getPackageManager().
7784                                getApplicationInfo(
7785                                        cpi.applicationInfo.packageName,
7786                                        STOCK_PM_FLAGS, userId);
7787                        if (ai == null) {
7788                            Slog.w(TAG, "No package info for content provider "
7789                                    + cpi.name);
7790                            return null;
7791                        }
7792                        ai = getAppInfoForUser(ai, userId);
7793                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7794                    } catch (RemoteException ex) {
7795                        // pm is in same process, this will never happen.
7796                    }
7797                }
7798
7799                if (r != null && cpr.canRunHere(r)) {
7800                    // If this is a multiprocess provider, then just return its
7801                    // info and allow the caller to instantiate it.  Only do
7802                    // this if the provider is the same user as the caller's
7803                    // process, or can run as root (so can be in any process).
7804                    return cpr.newHolder(null);
7805                }
7806
7807                if (DEBUG_PROVIDER) {
7808                    RuntimeException e = new RuntimeException("here");
7809                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7810                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7811                }
7812
7813                // This is single process, and our app is now connecting to it.
7814                // See if we are already in the process of launching this
7815                // provider.
7816                final int N = mLaunchingProviders.size();
7817                int i;
7818                for (i=0; i<N; i++) {
7819                    if (mLaunchingProviders.get(i) == cpr) {
7820                        break;
7821                    }
7822                }
7823
7824                // If the provider is not already being launched, then get it
7825                // started.
7826                if (i >= N) {
7827                    final long origId = Binder.clearCallingIdentity();
7828
7829                    try {
7830                        // Content provider is now in use, its package can't be stopped.
7831                        try {
7832                            AppGlobals.getPackageManager().setPackageStoppedState(
7833                                    cpr.appInfo.packageName, false, userId);
7834                        } catch (RemoteException e) {
7835                        } catch (IllegalArgumentException e) {
7836                            Slog.w(TAG, "Failed trying to unstop package "
7837                                    + cpr.appInfo.packageName + ": " + e);
7838                        }
7839
7840                        // Use existing process if already started
7841                        ProcessRecord proc = getProcessRecordLocked(
7842                                cpi.processName, cpr.appInfo.uid, false);
7843                        if (proc != null && proc.thread != null) {
7844                            if (DEBUG_PROVIDER) {
7845                                Slog.d(TAG, "Installing in existing process " + proc);
7846                            }
7847                            proc.pubProviders.put(cpi.name, cpr);
7848                            try {
7849                                proc.thread.scheduleInstallProvider(cpi);
7850                            } catch (RemoteException e) {
7851                            }
7852                        } else {
7853                            proc = startProcessLocked(cpi.processName,
7854                                    cpr.appInfo, false, 0, "content provider",
7855                                    new ComponentName(cpi.applicationInfo.packageName,
7856                                            cpi.name), false, false, false);
7857                            if (proc == null) {
7858                                Slog.w(TAG, "Unable to launch app "
7859                                        + cpi.applicationInfo.packageName + "/"
7860                                        + cpi.applicationInfo.uid + " for provider "
7861                                        + name + ": process is bad");
7862                                return null;
7863                            }
7864                        }
7865                        cpr.launchingApp = proc;
7866                        mLaunchingProviders.add(cpr);
7867                    } finally {
7868                        Binder.restoreCallingIdentity(origId);
7869                    }
7870                }
7871
7872                // Make sure the provider is published (the same provider class
7873                // may be published under multiple names).
7874                if (firstClass) {
7875                    mProviderMap.putProviderByClass(comp, cpr);
7876                }
7877
7878                mProviderMap.putProviderByName(name, cpr);
7879                conn = incProviderCountLocked(r, cpr, token, stable);
7880                if (conn != null) {
7881                    conn.waiting = true;
7882                }
7883            }
7884        }
7885
7886        // Wait for the provider to be published...
7887        synchronized (cpr) {
7888            while (cpr.provider == null) {
7889                if (cpr.launchingApp == null) {
7890                    Slog.w(TAG, "Unable to launch app "
7891                            + cpi.applicationInfo.packageName + "/"
7892                            + cpi.applicationInfo.uid + " for provider "
7893                            + name + ": launching app became null");
7894                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7895                            UserHandle.getUserId(cpi.applicationInfo.uid),
7896                            cpi.applicationInfo.packageName,
7897                            cpi.applicationInfo.uid, name);
7898                    return null;
7899                }
7900                try {
7901                    if (DEBUG_MU) {
7902                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7903                                + cpr.launchingApp);
7904                    }
7905                    if (conn != null) {
7906                        conn.waiting = true;
7907                    }
7908                    cpr.wait();
7909                } catch (InterruptedException ex) {
7910                } finally {
7911                    if (conn != null) {
7912                        conn.waiting = false;
7913                    }
7914                }
7915            }
7916        }
7917        return cpr != null ? cpr.newHolder(conn) : null;
7918    }
7919
7920    public final ContentProviderHolder getContentProvider(
7921            IApplicationThread caller, String name, int userId, boolean stable) {
7922        enforceNotIsolatedCaller("getContentProvider");
7923        if (caller == null) {
7924            String msg = "null IApplicationThread when getting content provider "
7925                    + name;
7926            Slog.w(TAG, msg);
7927            throw new SecurityException(msg);
7928        }
7929
7930        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7931                false, true, "getContentProvider", null);
7932        return getContentProviderImpl(caller, name, null, stable, userId);
7933    }
7934
7935    public ContentProviderHolder getContentProviderExternal(
7936            String name, int userId, IBinder token) {
7937        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7938            "Do not have permission in call getContentProviderExternal()");
7939        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7940                false, true, "getContentProvider", null);
7941        return getContentProviderExternalUnchecked(name, token, userId);
7942    }
7943
7944    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7945            IBinder token, int userId) {
7946        return getContentProviderImpl(null, name, token, true, userId);
7947    }
7948
7949    /**
7950     * Drop a content provider from a ProcessRecord's bookkeeping
7951     */
7952    public void removeContentProvider(IBinder connection, boolean stable) {
7953        enforceNotIsolatedCaller("removeContentProvider");
7954        long ident = Binder.clearCallingIdentity();
7955        try {
7956            synchronized (this) {
7957                ContentProviderConnection conn;
7958                try {
7959                    conn = (ContentProviderConnection)connection;
7960                } catch (ClassCastException e) {
7961                    String msg ="removeContentProvider: " + connection
7962                            + " not a ContentProviderConnection";
7963                    Slog.w(TAG, msg);
7964                    throw new IllegalArgumentException(msg);
7965                }
7966                if (conn == null) {
7967                    throw new NullPointerException("connection is null");
7968                }
7969                if (decProviderCountLocked(conn, null, null, stable)) {
7970                    updateOomAdjLocked();
7971                }
7972            }
7973        } finally {
7974            Binder.restoreCallingIdentity(ident);
7975        }
7976    }
7977
7978    public void removeContentProviderExternal(String name, IBinder token) {
7979        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7980            "Do not have permission in call removeContentProviderExternal()");
7981        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7982    }
7983
7984    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7985        synchronized (this) {
7986            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7987            if(cpr == null) {
7988                //remove from mProvidersByClass
7989                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7990                return;
7991            }
7992
7993            //update content provider record entry info
7994            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7995            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7996            if (localCpr.hasExternalProcessHandles()) {
7997                if (localCpr.removeExternalProcessHandleLocked(token)) {
7998                    updateOomAdjLocked();
7999                } else {
8000                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8001                            + " with no external reference for token: "
8002                            + token + ".");
8003                }
8004            } else {
8005                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8006                        + " with no external references.");
8007            }
8008        }
8009    }
8010
8011    public final void publishContentProviders(IApplicationThread caller,
8012            List<ContentProviderHolder> providers) {
8013        if (providers == null) {
8014            return;
8015        }
8016
8017        enforceNotIsolatedCaller("publishContentProviders");
8018        synchronized (this) {
8019            final ProcessRecord r = getRecordForAppLocked(caller);
8020            if (DEBUG_MU)
8021                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8022            if (r == null) {
8023                throw new SecurityException(
8024                        "Unable to find app for caller " + caller
8025                      + " (pid=" + Binder.getCallingPid()
8026                      + ") when publishing content providers");
8027            }
8028
8029            final long origId = Binder.clearCallingIdentity();
8030
8031            final int N = providers.size();
8032            for (int i=0; i<N; i++) {
8033                ContentProviderHolder src = providers.get(i);
8034                if (src == null || src.info == null || src.provider == null) {
8035                    continue;
8036                }
8037                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8038                if (DEBUG_MU)
8039                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8040                if (dst != null) {
8041                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8042                    mProviderMap.putProviderByClass(comp, dst);
8043                    String names[] = dst.info.authority.split(";");
8044                    for (int j = 0; j < names.length; j++) {
8045                        mProviderMap.putProviderByName(names[j], dst);
8046                    }
8047
8048                    int NL = mLaunchingProviders.size();
8049                    int j;
8050                    for (j=0; j<NL; j++) {
8051                        if (mLaunchingProviders.get(j) == dst) {
8052                            mLaunchingProviders.remove(j);
8053                            j--;
8054                            NL--;
8055                        }
8056                    }
8057                    synchronized (dst) {
8058                        dst.provider = src.provider;
8059                        dst.proc = r;
8060                        dst.notifyAll();
8061                    }
8062                    updateOomAdjLocked(r);
8063                }
8064            }
8065
8066            Binder.restoreCallingIdentity(origId);
8067        }
8068    }
8069
8070    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8071        ContentProviderConnection conn;
8072        try {
8073            conn = (ContentProviderConnection)connection;
8074        } catch (ClassCastException e) {
8075            String msg ="refContentProvider: " + connection
8076                    + " not a ContentProviderConnection";
8077            Slog.w(TAG, msg);
8078            throw new IllegalArgumentException(msg);
8079        }
8080        if (conn == null) {
8081            throw new NullPointerException("connection is null");
8082        }
8083
8084        synchronized (this) {
8085            if (stable > 0) {
8086                conn.numStableIncs += stable;
8087            }
8088            stable = conn.stableCount + stable;
8089            if (stable < 0) {
8090                throw new IllegalStateException("stableCount < 0: " + stable);
8091            }
8092
8093            if (unstable > 0) {
8094                conn.numUnstableIncs += unstable;
8095            }
8096            unstable = conn.unstableCount + unstable;
8097            if (unstable < 0) {
8098                throw new IllegalStateException("unstableCount < 0: " + unstable);
8099            }
8100
8101            if ((stable+unstable) <= 0) {
8102                throw new IllegalStateException("ref counts can't go to zero here: stable="
8103                        + stable + " unstable=" + unstable);
8104            }
8105            conn.stableCount = stable;
8106            conn.unstableCount = unstable;
8107            return !conn.dead;
8108        }
8109    }
8110
8111    public void unstableProviderDied(IBinder connection) {
8112        ContentProviderConnection conn;
8113        try {
8114            conn = (ContentProviderConnection)connection;
8115        } catch (ClassCastException e) {
8116            String msg ="refContentProvider: " + connection
8117                    + " not a ContentProviderConnection";
8118            Slog.w(TAG, msg);
8119            throw new IllegalArgumentException(msg);
8120        }
8121        if (conn == null) {
8122            throw new NullPointerException("connection is null");
8123        }
8124
8125        // Safely retrieve the content provider associated with the connection.
8126        IContentProvider provider;
8127        synchronized (this) {
8128            provider = conn.provider.provider;
8129        }
8130
8131        if (provider == null) {
8132            // Um, yeah, we're way ahead of you.
8133            return;
8134        }
8135
8136        // Make sure the caller is being honest with us.
8137        if (provider.asBinder().pingBinder()) {
8138            // Er, no, still looks good to us.
8139            synchronized (this) {
8140                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8141                        + " says " + conn + " died, but we don't agree");
8142                return;
8143            }
8144        }
8145
8146        // Well look at that!  It's dead!
8147        synchronized (this) {
8148            if (conn.provider.provider != provider) {
8149                // But something changed...  good enough.
8150                return;
8151            }
8152
8153            ProcessRecord proc = conn.provider.proc;
8154            if (proc == null || proc.thread == null) {
8155                // Seems like the process is already cleaned up.
8156                return;
8157            }
8158
8159            // As far as we're concerned, this is just like receiving a
8160            // death notification...  just a bit prematurely.
8161            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8162                    + ") early provider death");
8163            final long ident = Binder.clearCallingIdentity();
8164            try {
8165                appDiedLocked(proc, proc.pid, proc.thread);
8166            } finally {
8167                Binder.restoreCallingIdentity(ident);
8168            }
8169        }
8170    }
8171
8172    @Override
8173    public void appNotRespondingViaProvider(IBinder connection) {
8174        enforceCallingPermission(
8175                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8176
8177        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8178        if (conn == null) {
8179            Slog.w(TAG, "ContentProviderConnection is null");
8180            return;
8181        }
8182
8183        final ProcessRecord host = conn.provider.proc;
8184        if (host == null) {
8185            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8186            return;
8187        }
8188
8189        final long token = Binder.clearCallingIdentity();
8190        try {
8191            appNotResponding(host, null, null, false, "ContentProvider not responding");
8192        } finally {
8193            Binder.restoreCallingIdentity(token);
8194        }
8195    }
8196
8197    public final void installSystemProviders() {
8198        List<ProviderInfo> providers;
8199        synchronized (this) {
8200            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8201            providers = generateApplicationProvidersLocked(app);
8202            if (providers != null) {
8203                for (int i=providers.size()-1; i>=0; i--) {
8204                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8205                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8206                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8207                                + ": not system .apk");
8208                        providers.remove(i);
8209                    }
8210                }
8211            }
8212        }
8213        if (providers != null) {
8214            mSystemThread.installSystemProviders(providers);
8215        }
8216
8217        mCoreSettingsObserver = new CoreSettingsObserver(this);
8218
8219        mUsageStatsService.monitorPackages();
8220    }
8221
8222    /**
8223     * Allows app to retrieve the MIME type of a URI without having permission
8224     * to access its content provider.
8225     *
8226     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8227     *
8228     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8229     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8230     */
8231    public String getProviderMimeType(Uri uri, int userId) {
8232        enforceNotIsolatedCaller("getProviderMimeType");
8233        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8234                userId, false, true, "getProviderMimeType", null);
8235        final String name = uri.getAuthority();
8236        final long ident = Binder.clearCallingIdentity();
8237        ContentProviderHolder holder = null;
8238
8239        try {
8240            holder = getContentProviderExternalUnchecked(name, null, userId);
8241            if (holder != null) {
8242                return holder.provider.getType(uri);
8243            }
8244        } catch (RemoteException e) {
8245            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8246            return null;
8247        } finally {
8248            if (holder != null) {
8249                removeContentProviderExternalUnchecked(name, null, userId);
8250            }
8251            Binder.restoreCallingIdentity(ident);
8252        }
8253
8254        return null;
8255    }
8256
8257    // =========================================================
8258    // GLOBAL MANAGEMENT
8259    // =========================================================
8260
8261    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8262            boolean isolated) {
8263        String proc = customProcess != null ? customProcess : info.processName;
8264        BatteryStatsImpl.Uid.Proc ps = null;
8265        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8266        int uid = info.uid;
8267        if (isolated) {
8268            int userId = UserHandle.getUserId(uid);
8269            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8270            while (true) {
8271                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8272                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8273                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8274                }
8275                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8276                mNextIsolatedProcessUid++;
8277                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8278                    // No process for this uid, use it.
8279                    break;
8280                }
8281                stepsLeft--;
8282                if (stepsLeft <= 0) {
8283                    return null;
8284                }
8285            }
8286        }
8287        return new ProcessRecord(stats, info, proc, uid);
8288    }
8289
8290    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8291        ProcessRecord app;
8292        if (!isolated) {
8293            app = getProcessRecordLocked(info.processName, info.uid, true);
8294        } else {
8295            app = null;
8296        }
8297
8298        if (app == null) {
8299            app = newProcessRecordLocked(info, null, isolated);
8300            mProcessNames.put(info.processName, app.uid, app);
8301            if (isolated) {
8302                mIsolatedProcesses.put(app.uid, app);
8303            }
8304            updateLruProcessLocked(app, false, null);
8305            updateOomAdjLocked();
8306        }
8307
8308        // This package really, really can not be stopped.
8309        try {
8310            AppGlobals.getPackageManager().setPackageStoppedState(
8311                    info.packageName, false, UserHandle.getUserId(app.uid));
8312        } catch (RemoteException e) {
8313        } catch (IllegalArgumentException e) {
8314            Slog.w(TAG, "Failed trying to unstop package "
8315                    + info.packageName + ": " + e);
8316        }
8317
8318        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8319                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8320            app.persistent = true;
8321            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8322        }
8323        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8324            mPersistentStartingProcesses.add(app);
8325            startProcessLocked(app, "added application", app.processName);
8326        }
8327
8328        return app;
8329    }
8330
8331    public void unhandledBack() {
8332        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8333                "unhandledBack()");
8334
8335        synchronized(this) {
8336            final long origId = Binder.clearCallingIdentity();
8337            try {
8338                getFocusedStack().unhandledBackLocked();
8339            } finally {
8340                Binder.restoreCallingIdentity(origId);
8341            }
8342        }
8343    }
8344
8345    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8346        enforceNotIsolatedCaller("openContentUri");
8347        final int userId = UserHandle.getCallingUserId();
8348        String name = uri.getAuthority();
8349        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8350        ParcelFileDescriptor pfd = null;
8351        if (cph != null) {
8352            // We record the binder invoker's uid in thread-local storage before
8353            // going to the content provider to open the file.  Later, in the code
8354            // that handles all permissions checks, we look for this uid and use
8355            // that rather than the Activity Manager's own uid.  The effect is that
8356            // we do the check against the caller's permissions even though it looks
8357            // to the content provider like the Activity Manager itself is making
8358            // the request.
8359            sCallerIdentity.set(new Identity(
8360                    Binder.getCallingPid(), Binder.getCallingUid()));
8361            try {
8362                pfd = cph.provider.openFile(null, uri, "r", null);
8363            } catch (FileNotFoundException e) {
8364                // do nothing; pfd will be returned null
8365            } finally {
8366                // Ensure that whatever happens, we clean up the identity state
8367                sCallerIdentity.remove();
8368            }
8369
8370            // We've got the fd now, so we're done with the provider.
8371            removeContentProviderExternalUnchecked(name, null, userId);
8372        } else {
8373            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8374        }
8375        return pfd;
8376    }
8377
8378    // Actually is sleeping or shutting down or whatever else in the future
8379    // is an inactive state.
8380    public boolean isSleepingOrShuttingDown() {
8381        return mSleeping || mShuttingDown;
8382    }
8383
8384    public void goingToSleep() {
8385        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8386                != PackageManager.PERMISSION_GRANTED) {
8387            throw new SecurityException("Requires permission "
8388                    + android.Manifest.permission.DEVICE_POWER);
8389        }
8390
8391        synchronized(this) {
8392            mWentToSleep = true;
8393            updateEventDispatchingLocked();
8394
8395            if (!mSleeping) {
8396                mSleeping = true;
8397                mStackSupervisor.goingToSleepLocked();
8398
8399                // Initialize the wake times of all processes.
8400                checkExcessivePowerUsageLocked(false);
8401                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8402                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8403                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8404            }
8405        }
8406    }
8407
8408    @Override
8409    public boolean shutdown(int timeout) {
8410        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8411                != PackageManager.PERMISSION_GRANTED) {
8412            throw new SecurityException("Requires permission "
8413                    + android.Manifest.permission.SHUTDOWN);
8414        }
8415
8416        boolean timedout = false;
8417
8418        synchronized(this) {
8419            mShuttingDown = true;
8420            updateEventDispatchingLocked();
8421            timedout = mStackSupervisor.shutdownLocked(timeout);
8422        }
8423
8424        mAppOpsService.shutdown();
8425        mUsageStatsService.shutdown();
8426        mBatteryStatsService.shutdown();
8427        synchronized (this) {
8428            mProcessStats.shutdownLocked();
8429        }
8430
8431        return timedout;
8432    }
8433
8434    public final void activitySlept(IBinder token) {
8435        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8436
8437        final long origId = Binder.clearCallingIdentity();
8438
8439        synchronized (this) {
8440            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8441            if (r != null) {
8442                mStackSupervisor.activitySleptLocked(r);
8443            }
8444        }
8445
8446        Binder.restoreCallingIdentity(origId);
8447    }
8448
8449    void logLockScreen(String msg) {
8450        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8451                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8452                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8453                mStackSupervisor.mDismissKeyguardOnNextActivity);
8454    }
8455
8456    private void comeOutOfSleepIfNeededLocked() {
8457        if (!mWentToSleep && !mLockScreenShown) {
8458            if (mSleeping) {
8459                mSleeping = false;
8460                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8461            }
8462        }
8463    }
8464
8465    public void wakingUp() {
8466        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8467                != PackageManager.PERMISSION_GRANTED) {
8468            throw new SecurityException("Requires permission "
8469                    + android.Manifest.permission.DEVICE_POWER);
8470        }
8471
8472        synchronized(this) {
8473            mWentToSleep = false;
8474            updateEventDispatchingLocked();
8475            comeOutOfSleepIfNeededLocked();
8476        }
8477    }
8478
8479    private void updateEventDispatchingLocked() {
8480        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8481    }
8482
8483    public void setLockScreenShown(boolean shown) {
8484        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8485                != PackageManager.PERMISSION_GRANTED) {
8486            throw new SecurityException("Requires permission "
8487                    + android.Manifest.permission.DEVICE_POWER);
8488        }
8489
8490        synchronized(this) {
8491            long ident = Binder.clearCallingIdentity();
8492            try {
8493                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8494                mLockScreenShown = shown;
8495                comeOutOfSleepIfNeededLocked();
8496            } finally {
8497                Binder.restoreCallingIdentity(ident);
8498            }
8499        }
8500    }
8501
8502    public void stopAppSwitches() {
8503        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8504                != PackageManager.PERMISSION_GRANTED) {
8505            throw new SecurityException("Requires permission "
8506                    + android.Manifest.permission.STOP_APP_SWITCHES);
8507        }
8508
8509        synchronized(this) {
8510            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8511                    + APP_SWITCH_DELAY_TIME;
8512            mDidAppSwitch = false;
8513            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8514            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8515            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8516        }
8517    }
8518
8519    public void resumeAppSwitches() {
8520        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8521                != PackageManager.PERMISSION_GRANTED) {
8522            throw new SecurityException("Requires permission "
8523                    + android.Manifest.permission.STOP_APP_SWITCHES);
8524        }
8525
8526        synchronized(this) {
8527            // Note that we don't execute any pending app switches... we will
8528            // let those wait until either the timeout, or the next start
8529            // activity request.
8530            mAppSwitchesAllowedTime = 0;
8531        }
8532    }
8533
8534    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8535            String name) {
8536        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8537            return true;
8538        }
8539
8540        final int perm = checkComponentPermission(
8541                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8542                callingUid, -1, true);
8543        if (perm == PackageManager.PERMISSION_GRANTED) {
8544            return true;
8545        }
8546
8547        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8548        return false;
8549    }
8550
8551    public void setDebugApp(String packageName, boolean waitForDebugger,
8552            boolean persistent) {
8553        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8554                "setDebugApp()");
8555
8556        long ident = Binder.clearCallingIdentity();
8557        try {
8558            // Note that this is not really thread safe if there are multiple
8559            // callers into it at the same time, but that's not a situation we
8560            // care about.
8561            if (persistent) {
8562                final ContentResolver resolver = mContext.getContentResolver();
8563                Settings.Global.putString(
8564                    resolver, Settings.Global.DEBUG_APP,
8565                    packageName);
8566                Settings.Global.putInt(
8567                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8568                    waitForDebugger ? 1 : 0);
8569            }
8570
8571            synchronized (this) {
8572                if (!persistent) {
8573                    mOrigDebugApp = mDebugApp;
8574                    mOrigWaitForDebugger = mWaitForDebugger;
8575                }
8576                mDebugApp = packageName;
8577                mWaitForDebugger = waitForDebugger;
8578                mDebugTransient = !persistent;
8579                if (packageName != null) {
8580                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8581                            false, UserHandle.USER_ALL, "set debug app");
8582                }
8583            }
8584        } finally {
8585            Binder.restoreCallingIdentity(ident);
8586        }
8587    }
8588
8589    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8590        synchronized (this) {
8591            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8592            if (!isDebuggable) {
8593                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8594                    throw new SecurityException("Process not debuggable: " + app.packageName);
8595                }
8596            }
8597
8598            mOpenGlTraceApp = processName;
8599        }
8600    }
8601
8602    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8603            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8604        synchronized (this) {
8605            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8606            if (!isDebuggable) {
8607                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8608                    throw new SecurityException("Process not debuggable: " + app.packageName);
8609                }
8610            }
8611            mProfileApp = processName;
8612            mProfileFile = profileFile;
8613            if (mProfileFd != null) {
8614                try {
8615                    mProfileFd.close();
8616                } catch (IOException e) {
8617                }
8618                mProfileFd = null;
8619            }
8620            mProfileFd = profileFd;
8621            mProfileType = 0;
8622            mAutoStopProfiler = autoStopProfiler;
8623        }
8624    }
8625
8626    @Override
8627    public void setAlwaysFinish(boolean enabled) {
8628        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8629                "setAlwaysFinish()");
8630
8631        Settings.Global.putInt(
8632                mContext.getContentResolver(),
8633                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8634
8635        synchronized (this) {
8636            mAlwaysFinishActivities = enabled;
8637        }
8638    }
8639
8640    @Override
8641    public void setActivityController(IActivityController controller) {
8642        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8643                "setActivityController()");
8644        synchronized (this) {
8645            mController = controller;
8646            Watchdog.getInstance().setActivityController(controller);
8647        }
8648    }
8649
8650    @Override
8651    public void setUserIsMonkey(boolean userIsMonkey) {
8652        synchronized (this) {
8653            synchronized (mPidsSelfLocked) {
8654                final int callingPid = Binder.getCallingPid();
8655                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8656                if (precessRecord == null) {
8657                    throw new SecurityException("Unknown process: " + callingPid);
8658                }
8659                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8660                    throw new SecurityException("Only an instrumentation process "
8661                            + "with a UiAutomation can call setUserIsMonkey");
8662                }
8663            }
8664            mUserIsMonkey = userIsMonkey;
8665        }
8666    }
8667
8668    @Override
8669    public boolean isUserAMonkey() {
8670        synchronized (this) {
8671            // If there is a controller also implies the user is a monkey.
8672            return (mUserIsMonkey || mController != null);
8673        }
8674    }
8675
8676    public void requestBugReport() {
8677        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8678        SystemProperties.set("ctl.start", "bugreport");
8679    }
8680
8681    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8682        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8683    }
8684
8685    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8686        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8687            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8688        }
8689        return KEY_DISPATCHING_TIMEOUT;
8690    }
8691
8692    @Override
8693    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8694        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8695                != PackageManager.PERMISSION_GRANTED) {
8696            throw new SecurityException("Requires permission "
8697                    + android.Manifest.permission.FILTER_EVENTS);
8698        }
8699        ProcessRecord proc;
8700        long timeout;
8701        synchronized (this) {
8702            synchronized (mPidsSelfLocked) {
8703                proc = mPidsSelfLocked.get(pid);
8704            }
8705            timeout = getInputDispatchingTimeoutLocked(proc);
8706        }
8707
8708        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8709            return -1;
8710        }
8711
8712        return timeout;
8713    }
8714
8715    /**
8716     * Handle input dispatching timeouts.
8717     * Returns whether input dispatching should be aborted or not.
8718     */
8719    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8720            final ActivityRecord activity, final ActivityRecord parent,
8721            final boolean aboveSystem, String reason) {
8722        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8723                != PackageManager.PERMISSION_GRANTED) {
8724            throw new SecurityException("Requires permission "
8725                    + android.Manifest.permission.FILTER_EVENTS);
8726        }
8727
8728        final String annotation;
8729        if (reason == null) {
8730            annotation = "Input dispatching timed out";
8731        } else {
8732            annotation = "Input dispatching timed out (" + reason + ")";
8733        }
8734
8735        if (proc != null) {
8736            synchronized (this) {
8737                if (proc.debugging) {
8738                    return false;
8739                }
8740
8741                if (mDidDexOpt) {
8742                    // Give more time since we were dexopting.
8743                    mDidDexOpt = false;
8744                    return false;
8745                }
8746
8747                if (proc.instrumentationClass != null) {
8748                    Bundle info = new Bundle();
8749                    info.putString("shortMsg", "keyDispatchingTimedOut");
8750                    info.putString("longMsg", annotation);
8751                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8752                    return true;
8753                }
8754            }
8755            mHandler.post(new Runnable() {
8756                @Override
8757                public void run() {
8758                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8759                }
8760            });
8761        }
8762
8763        return true;
8764    }
8765
8766    public Bundle getAssistContextExtras(int requestType) {
8767        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8768                "getAssistContextExtras()");
8769        PendingAssistExtras pae;
8770        Bundle extras = new Bundle();
8771        synchronized (this) {
8772            ActivityRecord activity = getFocusedStack().mResumedActivity;
8773            if (activity == null) {
8774                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8775                return null;
8776            }
8777            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8778            if (activity.app == null || activity.app.thread == null) {
8779                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8780                return extras;
8781            }
8782            if (activity.app.pid == Binder.getCallingPid()) {
8783                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8784                return extras;
8785            }
8786            pae = new PendingAssistExtras(activity);
8787            try {
8788                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8789                        requestType);
8790                mPendingAssistExtras.add(pae);
8791                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8792            } catch (RemoteException e) {
8793                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8794                return extras;
8795            }
8796        }
8797        synchronized (pae) {
8798            while (!pae.haveResult) {
8799                try {
8800                    pae.wait();
8801                } catch (InterruptedException e) {
8802                }
8803            }
8804            if (pae.result != null) {
8805                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8806            }
8807        }
8808        synchronized (this) {
8809            mPendingAssistExtras.remove(pae);
8810            mHandler.removeCallbacks(pae);
8811        }
8812        return extras;
8813    }
8814
8815    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8816        PendingAssistExtras pae = (PendingAssistExtras)token;
8817        synchronized (pae) {
8818            pae.result = extras;
8819            pae.haveResult = true;
8820            pae.notifyAll();
8821        }
8822    }
8823
8824    public void registerProcessObserver(IProcessObserver observer) {
8825        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8826                "registerProcessObserver()");
8827        synchronized (this) {
8828            mProcessObservers.register(observer);
8829        }
8830    }
8831
8832    @Override
8833    public void unregisterProcessObserver(IProcessObserver observer) {
8834        synchronized (this) {
8835            mProcessObservers.unregister(observer);
8836        }
8837    }
8838
8839    @Override
8840    public boolean convertFromTranslucent(IBinder token) {
8841        final long origId = Binder.clearCallingIdentity();
8842        try {
8843            synchronized (this) {
8844                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8845                if (r == null) {
8846                    return false;
8847                }
8848                if (r.changeWindowTranslucency(true)) {
8849                    mWindowManager.setAppFullscreen(token, true);
8850                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8851                    return true;
8852                }
8853                return false;
8854            }
8855        } finally {
8856            Binder.restoreCallingIdentity(origId);
8857        }
8858    }
8859
8860    @Override
8861    public boolean convertToTranslucent(IBinder token) {
8862        final long origId = Binder.clearCallingIdentity();
8863        try {
8864            synchronized (this) {
8865                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8866                if (r == null) {
8867                    return false;
8868                }
8869                if (r.changeWindowTranslucency(false)) {
8870                    r.task.stack.convertToTranslucent(r);
8871                    mWindowManager.setAppFullscreen(token, false);
8872                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8873                    return true;
8874                }
8875                return false;
8876            }
8877        } finally {
8878            Binder.restoreCallingIdentity(origId);
8879        }
8880    }
8881
8882    @Override
8883    public void setImmersive(IBinder token, boolean immersive) {
8884        synchronized(this) {
8885            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8886            if (r == null) {
8887                throw new IllegalArgumentException();
8888            }
8889            r.immersive = immersive;
8890
8891            // update associated state if we're frontmost
8892            if (r == mFocusedActivity) {
8893                if (DEBUG_IMMERSIVE) {
8894                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8895                }
8896                applyUpdateLockStateLocked(r);
8897            }
8898        }
8899    }
8900
8901    @Override
8902    public boolean isImmersive(IBinder token) {
8903        synchronized (this) {
8904            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8905            if (r == null) {
8906                throw new IllegalArgumentException();
8907            }
8908            return r.immersive;
8909        }
8910    }
8911
8912    public boolean isTopActivityImmersive() {
8913        enforceNotIsolatedCaller("startActivity");
8914        synchronized (this) {
8915            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8916            return (r != null) ? r.immersive : false;
8917        }
8918    }
8919
8920    public final void enterSafeMode() {
8921        synchronized(this) {
8922            // It only makes sense to do this before the system is ready
8923            // and started launching other packages.
8924            if (!mSystemReady) {
8925                try {
8926                    AppGlobals.getPackageManager().enterSafeMode();
8927                } catch (RemoteException e) {
8928                }
8929            }
8930        }
8931    }
8932
8933    public final void showSafeModeOverlay() {
8934        View v = LayoutInflater.from(mContext).inflate(
8935                com.android.internal.R.layout.safe_mode, null);
8936        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8937        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8938        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8939        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8940        lp.gravity = Gravity.BOTTOM | Gravity.START;
8941        lp.format = v.getBackground().getOpacity();
8942        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8943                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8944        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8945        ((WindowManager)mContext.getSystemService(
8946                Context.WINDOW_SERVICE)).addView(v, lp);
8947    }
8948
8949    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8950        if (!(sender instanceof PendingIntentRecord)) {
8951            return;
8952        }
8953        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8954        synchronized (stats) {
8955            if (mBatteryStatsService.isOnBattery()) {
8956                mBatteryStatsService.enforceCallingPermission();
8957                PendingIntentRecord rec = (PendingIntentRecord)sender;
8958                int MY_UID = Binder.getCallingUid();
8959                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8960                BatteryStatsImpl.Uid.Pkg pkg =
8961                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8962                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8963                pkg.incWakeupsLocked();
8964            }
8965        }
8966    }
8967
8968    public boolean killPids(int[] pids, String pReason, boolean secure) {
8969        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8970            throw new SecurityException("killPids only available to the system");
8971        }
8972        String reason = (pReason == null) ? "Unknown" : pReason;
8973        // XXX Note: don't acquire main activity lock here, because the window
8974        // manager calls in with its locks held.
8975
8976        boolean killed = false;
8977        synchronized (mPidsSelfLocked) {
8978            int[] types = new int[pids.length];
8979            int worstType = 0;
8980            for (int i=0; i<pids.length; i++) {
8981                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8982                if (proc != null) {
8983                    int type = proc.setAdj;
8984                    types[i] = type;
8985                    if (type > worstType) {
8986                        worstType = type;
8987                    }
8988                }
8989            }
8990
8991            // If the worst oom_adj is somewhere in the cached proc LRU range,
8992            // then constrain it so we will kill all cached procs.
8993            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8994                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8995                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8996            }
8997
8998            // If this is not a secure call, don't let it kill processes that
8999            // are important.
9000            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9001                worstType = ProcessList.SERVICE_ADJ;
9002            }
9003
9004            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9005            for (int i=0; i<pids.length; i++) {
9006                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9007                if (proc == null) {
9008                    continue;
9009                }
9010                int adj = proc.setAdj;
9011                if (adj >= worstType && !proc.killedByAm) {
9012                    killUnneededProcessLocked(proc, reason);
9013                    killed = true;
9014                }
9015            }
9016        }
9017        return killed;
9018    }
9019
9020    @Override
9021    public void killUid(int uid, String reason) {
9022        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9023            throw new SecurityException("killUid only available to the system");
9024        }
9025        synchronized (this) {
9026            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9027                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9028                    reason != null ? reason : "kill uid");
9029        }
9030    }
9031
9032    @Override
9033    public boolean killProcessesBelowForeground(String reason) {
9034        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9035            throw new SecurityException("killProcessesBelowForeground() only available to system");
9036        }
9037
9038        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9039    }
9040
9041    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9042        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9043            throw new SecurityException("killProcessesBelowAdj() only available to system");
9044        }
9045
9046        boolean killed = false;
9047        synchronized (mPidsSelfLocked) {
9048            final int size = mPidsSelfLocked.size();
9049            for (int i = 0; i < size; i++) {
9050                final int pid = mPidsSelfLocked.keyAt(i);
9051                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9052                if (proc == null) continue;
9053
9054                final int adj = proc.setAdj;
9055                if (adj > belowAdj && !proc.killedByAm) {
9056                    killUnneededProcessLocked(proc, reason);
9057                    killed = true;
9058                }
9059            }
9060        }
9061        return killed;
9062    }
9063
9064    @Override
9065    public void hang(final IBinder who, boolean allowRestart) {
9066        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9067                != PackageManager.PERMISSION_GRANTED) {
9068            throw new SecurityException("Requires permission "
9069                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9070        }
9071
9072        final IBinder.DeathRecipient death = new DeathRecipient() {
9073            @Override
9074            public void binderDied() {
9075                synchronized (this) {
9076                    notifyAll();
9077                }
9078            }
9079        };
9080
9081        try {
9082            who.linkToDeath(death, 0);
9083        } catch (RemoteException e) {
9084            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9085            return;
9086        }
9087
9088        synchronized (this) {
9089            Watchdog.getInstance().setAllowRestart(allowRestart);
9090            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9091            synchronized (death) {
9092                while (who.isBinderAlive()) {
9093                    try {
9094                        death.wait();
9095                    } catch (InterruptedException e) {
9096                    }
9097                }
9098            }
9099            Watchdog.getInstance().setAllowRestart(true);
9100        }
9101    }
9102
9103    @Override
9104    public void restart() {
9105        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9106                != PackageManager.PERMISSION_GRANTED) {
9107            throw new SecurityException("Requires permission "
9108                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9109        }
9110
9111        Log.i(TAG, "Sending shutdown broadcast...");
9112
9113        BroadcastReceiver br = new BroadcastReceiver() {
9114            @Override public void onReceive(Context context, Intent intent) {
9115                // Now the broadcast is done, finish up the low-level shutdown.
9116                Log.i(TAG, "Shutting down activity manager...");
9117                shutdown(10000);
9118                Log.i(TAG, "Shutdown complete, restarting!");
9119                Process.killProcess(Process.myPid());
9120                System.exit(10);
9121            }
9122        };
9123
9124        // First send the high-level shut down broadcast.
9125        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9126        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9127        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9128        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9129        mContext.sendOrderedBroadcastAsUser(intent,
9130                UserHandle.ALL, null, br, mHandler, 0, null, null);
9131        */
9132        br.onReceive(mContext, intent);
9133    }
9134
9135    private long getLowRamTimeSinceIdle(long now) {
9136        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9137    }
9138
9139    @Override
9140    public void performIdleMaintenance() {
9141        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9142                != PackageManager.PERMISSION_GRANTED) {
9143            throw new SecurityException("Requires permission "
9144                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9145        }
9146
9147        synchronized (this) {
9148            final long now = SystemClock.uptimeMillis();
9149            final long timeSinceLastIdle = now - mLastIdleTime;
9150            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9151            mLastIdleTime = now;
9152            mLowRamTimeSinceLastIdle = 0;
9153            if (mLowRamStartTime != 0) {
9154                mLowRamStartTime = now;
9155            }
9156
9157            StringBuilder sb = new StringBuilder(128);
9158            sb.append("Idle maintenance over ");
9159            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9160            sb.append(" low RAM for ");
9161            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9162            Slog.i(TAG, sb.toString());
9163
9164            // If at least 1/3 of our time since the last idle period has been spent
9165            // with RAM low, then we want to kill processes.
9166            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9167
9168            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9169                ProcessRecord proc = mLruProcesses.get(i);
9170                if (proc.notCachedSinceIdle) {
9171                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9172                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9173                        if (doKilling && proc.initialIdlePss != 0
9174                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9175                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9176                                    + " from " + proc.initialIdlePss + ")");
9177                        }
9178                    }
9179                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9180                    proc.notCachedSinceIdle = true;
9181                    proc.initialIdlePss = 0;
9182                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9183                            mSleeping, now);
9184                }
9185            }
9186
9187            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9188            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9189        }
9190    }
9191
9192    public final void startRunning(String pkg, String cls, String action,
9193            String data) {
9194        synchronized(this) {
9195            if (mStartRunning) {
9196                return;
9197            }
9198            mStartRunning = true;
9199            mTopComponent = pkg != null && cls != null
9200                    ? new ComponentName(pkg, cls) : null;
9201            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9202            mTopData = data;
9203            if (!mSystemReady) {
9204                return;
9205            }
9206        }
9207
9208        systemReady(null);
9209    }
9210
9211    private void retrieveSettings() {
9212        final ContentResolver resolver = mContext.getContentResolver();
9213        String debugApp = Settings.Global.getString(
9214            resolver, Settings.Global.DEBUG_APP);
9215        boolean waitForDebugger = Settings.Global.getInt(
9216            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9217        boolean alwaysFinishActivities = Settings.Global.getInt(
9218            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9219        boolean forceRtl = Settings.Global.getInt(
9220                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9221        // Transfer any global setting for forcing RTL layout, into a System Property
9222        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9223
9224        Configuration configuration = new Configuration();
9225        Settings.System.getConfiguration(resolver, configuration);
9226        if (forceRtl) {
9227            // This will take care of setting the correct layout direction flags
9228            configuration.setLayoutDirection(configuration.locale);
9229        }
9230
9231        synchronized (this) {
9232            mDebugApp = mOrigDebugApp = debugApp;
9233            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9234            mAlwaysFinishActivities = alwaysFinishActivities;
9235            // This happens before any activities are started, so we can
9236            // change mConfiguration in-place.
9237            updateConfigurationLocked(configuration, null, false, true);
9238            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9239        }
9240    }
9241
9242    public boolean testIsSystemReady() {
9243        // no need to synchronize(this) just to read & return the value
9244        return mSystemReady;
9245    }
9246
9247    private static File getCalledPreBootReceiversFile() {
9248        File dataDir = Environment.getDataDirectory();
9249        File systemDir = new File(dataDir, "system");
9250        File fname = new File(systemDir, "called_pre_boots.dat");
9251        return fname;
9252    }
9253
9254    static final int LAST_DONE_VERSION = 10000;
9255
9256    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9257        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9258        File file = getCalledPreBootReceiversFile();
9259        FileInputStream fis = null;
9260        try {
9261            fis = new FileInputStream(file);
9262            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9263            int fvers = dis.readInt();
9264            if (fvers == LAST_DONE_VERSION) {
9265                String vers = dis.readUTF();
9266                String codename = dis.readUTF();
9267                String build = dis.readUTF();
9268                if (android.os.Build.VERSION.RELEASE.equals(vers)
9269                        && android.os.Build.VERSION.CODENAME.equals(codename)
9270                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9271                    int num = dis.readInt();
9272                    while (num > 0) {
9273                        num--;
9274                        String pkg = dis.readUTF();
9275                        String cls = dis.readUTF();
9276                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9277                    }
9278                }
9279            }
9280        } catch (FileNotFoundException e) {
9281        } catch (IOException e) {
9282            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9283        } finally {
9284            if (fis != null) {
9285                try {
9286                    fis.close();
9287                } catch (IOException e) {
9288                }
9289            }
9290        }
9291        return lastDoneReceivers;
9292    }
9293
9294    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9295        File file = getCalledPreBootReceiversFile();
9296        FileOutputStream fos = null;
9297        DataOutputStream dos = null;
9298        try {
9299            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9300            fos = new FileOutputStream(file);
9301            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9302            dos.writeInt(LAST_DONE_VERSION);
9303            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9304            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9305            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9306            dos.writeInt(list.size());
9307            for (int i=0; i<list.size(); i++) {
9308                dos.writeUTF(list.get(i).getPackageName());
9309                dos.writeUTF(list.get(i).getClassName());
9310            }
9311        } catch (IOException e) {
9312            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9313            file.delete();
9314        } finally {
9315            FileUtils.sync(fos);
9316            if (dos != null) {
9317                try {
9318                    dos.close();
9319                } catch (IOException e) {
9320                    // TODO Auto-generated catch block
9321                    e.printStackTrace();
9322                }
9323            }
9324        }
9325    }
9326
9327    public void systemReady(final Runnable goingCallback) {
9328        synchronized(this) {
9329            if (mSystemReady) {
9330                if (goingCallback != null) goingCallback.run();
9331                return;
9332            }
9333
9334            // Check to see if there are any update receivers to run.
9335            if (!mDidUpdate) {
9336                if (mWaitingUpdate) {
9337                    return;
9338                }
9339                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9340                List<ResolveInfo> ris = null;
9341                try {
9342                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9343                            intent, null, 0, 0);
9344                } catch (RemoteException e) {
9345                }
9346                if (ris != null) {
9347                    for (int i=ris.size()-1; i>=0; i--) {
9348                        if ((ris.get(i).activityInfo.applicationInfo.flags
9349                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9350                            ris.remove(i);
9351                        }
9352                    }
9353                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9354
9355                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9356
9357                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9358                    for (int i=0; i<ris.size(); i++) {
9359                        ActivityInfo ai = ris.get(i).activityInfo;
9360                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9361                        if (lastDoneReceivers.contains(comp)) {
9362                            // We already did the pre boot receiver for this app with the current
9363                            // platform version, so don't do it again...
9364                            ris.remove(i);
9365                            i--;
9366                            // ...however, do keep it as one that has been done, so we don't
9367                            // forget about it when rewriting the file of last done receivers.
9368                            doneReceivers.add(comp);
9369                        }
9370                    }
9371
9372                    final int[] users = getUsersLocked();
9373                    for (int i=0; i<ris.size(); i++) {
9374                        ActivityInfo ai = ris.get(i).activityInfo;
9375                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9376                        doneReceivers.add(comp);
9377                        intent.setComponent(comp);
9378                        for (int j=0; j<users.length; j++) {
9379                            IIntentReceiver finisher = null;
9380                            if (i == ris.size()-1 && j == users.length-1) {
9381                                finisher = new IIntentReceiver.Stub() {
9382                                    public void performReceive(Intent intent, int resultCode,
9383                                            String data, Bundle extras, boolean ordered,
9384                                            boolean sticky, int sendingUser) {
9385                                        // The raw IIntentReceiver interface is called
9386                                        // with the AM lock held, so redispatch to
9387                                        // execute our code without the lock.
9388                                        mHandler.post(new Runnable() {
9389                                            public void run() {
9390                                                synchronized (ActivityManagerService.this) {
9391                                                    mDidUpdate = true;
9392                                                }
9393                                                writeLastDonePreBootReceivers(doneReceivers);
9394                                                showBootMessage(mContext.getText(
9395                                                        R.string.android_upgrading_complete),
9396                                                        false);
9397                                                systemReady(goingCallback);
9398                                            }
9399                                        });
9400                                    }
9401                                };
9402                            }
9403                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9404                                    + " for user " + users[j]);
9405                            broadcastIntentLocked(null, null, intent, null, finisher,
9406                                    0, null, null, null, AppOpsManager.OP_NONE,
9407                                    true, false, MY_PID, Process.SYSTEM_UID,
9408                                    users[j]);
9409                            if (finisher != null) {
9410                                mWaitingUpdate = true;
9411                            }
9412                        }
9413                    }
9414                }
9415                if (mWaitingUpdate) {
9416                    return;
9417                }
9418                mDidUpdate = true;
9419            }
9420
9421            mAppOpsService.systemReady();
9422            mSystemReady = true;
9423            if (!mStartRunning) {
9424                return;
9425            }
9426        }
9427
9428        ArrayList<ProcessRecord> procsToKill = null;
9429        synchronized(mPidsSelfLocked) {
9430            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9431                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9432                if (!isAllowedWhileBooting(proc.info)){
9433                    if (procsToKill == null) {
9434                        procsToKill = new ArrayList<ProcessRecord>();
9435                    }
9436                    procsToKill.add(proc);
9437                }
9438            }
9439        }
9440
9441        synchronized(this) {
9442            if (procsToKill != null) {
9443                for (int i=procsToKill.size()-1; i>=0; i--) {
9444                    ProcessRecord proc = procsToKill.get(i);
9445                    Slog.i(TAG, "Removing system update proc: " + proc);
9446                    removeProcessLocked(proc, true, false, "system update done");
9447                }
9448            }
9449
9450            // Now that we have cleaned up any update processes, we
9451            // are ready to start launching real processes and know that
9452            // we won't trample on them any more.
9453            mProcessesReady = true;
9454        }
9455
9456        Slog.i(TAG, "System now ready");
9457        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9458            SystemClock.uptimeMillis());
9459
9460        synchronized(this) {
9461            // Make sure we have no pre-ready processes sitting around.
9462
9463            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9464                ResolveInfo ri = mContext.getPackageManager()
9465                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9466                                STOCK_PM_FLAGS);
9467                CharSequence errorMsg = null;
9468                if (ri != null) {
9469                    ActivityInfo ai = ri.activityInfo;
9470                    ApplicationInfo app = ai.applicationInfo;
9471                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9472                        mTopAction = Intent.ACTION_FACTORY_TEST;
9473                        mTopData = null;
9474                        mTopComponent = new ComponentName(app.packageName,
9475                                ai.name);
9476                    } else {
9477                        errorMsg = mContext.getResources().getText(
9478                                com.android.internal.R.string.factorytest_not_system);
9479                    }
9480                } else {
9481                    errorMsg = mContext.getResources().getText(
9482                            com.android.internal.R.string.factorytest_no_action);
9483                }
9484                if (errorMsg != null) {
9485                    mTopAction = null;
9486                    mTopData = null;
9487                    mTopComponent = null;
9488                    Message msg = Message.obtain();
9489                    msg.what = SHOW_FACTORY_ERROR_MSG;
9490                    msg.getData().putCharSequence("msg", errorMsg);
9491                    mHandler.sendMessage(msg);
9492                }
9493            }
9494        }
9495
9496        retrieveSettings();
9497
9498        synchronized (this) {
9499            readGrantedUriPermissionsLocked();
9500        }
9501
9502        if (goingCallback != null) goingCallback.run();
9503
9504        synchronized (this) {
9505            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9506                try {
9507                    List apps = AppGlobals.getPackageManager().
9508                        getPersistentApplications(STOCK_PM_FLAGS);
9509                    if (apps != null) {
9510                        int N = apps.size();
9511                        int i;
9512                        for (i=0; i<N; i++) {
9513                            ApplicationInfo info
9514                                = (ApplicationInfo)apps.get(i);
9515                            if (info != null &&
9516                                    !info.packageName.equals("android")) {
9517                                addAppLocked(info, false);
9518                            }
9519                        }
9520                    }
9521                } catch (RemoteException ex) {
9522                    // pm is in same process, this will never happen.
9523                }
9524            }
9525
9526            // Start up initial activity.
9527            mBooting = true;
9528
9529            try {
9530                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9531                    Message msg = Message.obtain();
9532                    msg.what = SHOW_UID_ERROR_MSG;
9533                    mHandler.sendMessage(msg);
9534                }
9535            } catch (RemoteException e) {
9536            }
9537
9538            long ident = Binder.clearCallingIdentity();
9539            try {
9540                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9541                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9542                        | Intent.FLAG_RECEIVER_FOREGROUND);
9543                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9544                broadcastIntentLocked(null, null, intent,
9545                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9546                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9547                intent = new Intent(Intent.ACTION_USER_STARTING);
9548                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9549                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9550                broadcastIntentLocked(null, null, intent,
9551                        null, new IIntentReceiver.Stub() {
9552                            @Override
9553                            public void performReceive(Intent intent, int resultCode, String data,
9554                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9555                                    throws RemoteException {
9556                            }
9557                        }, 0, null, null,
9558                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9559                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9560            } finally {
9561                Binder.restoreCallingIdentity(ident);
9562            }
9563            mStackSupervisor.resumeTopActivitiesLocked();
9564            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9565        }
9566    }
9567
9568    private boolean makeAppCrashingLocked(ProcessRecord app,
9569            String shortMsg, String longMsg, String stackTrace) {
9570        app.crashing = true;
9571        app.crashingReport = generateProcessError(app,
9572                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9573        startAppProblemLocked(app);
9574        app.stopFreezingAllLocked();
9575        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9576    }
9577
9578    private void makeAppNotRespondingLocked(ProcessRecord app,
9579            String activity, String shortMsg, String longMsg) {
9580        app.notResponding = true;
9581        app.notRespondingReport = generateProcessError(app,
9582                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9583                activity, shortMsg, longMsg, null);
9584        startAppProblemLocked(app);
9585        app.stopFreezingAllLocked();
9586    }
9587
9588    /**
9589     * Generate a process error record, suitable for attachment to a ProcessRecord.
9590     *
9591     * @param app The ProcessRecord in which the error occurred.
9592     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9593     *                      ActivityManager.AppErrorStateInfo
9594     * @param activity The activity associated with the crash, if known.
9595     * @param shortMsg Short message describing the crash.
9596     * @param longMsg Long message describing the crash.
9597     * @param stackTrace Full crash stack trace, may be null.
9598     *
9599     * @return Returns a fully-formed AppErrorStateInfo record.
9600     */
9601    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9602            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9603        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9604
9605        report.condition = condition;
9606        report.processName = app.processName;
9607        report.pid = app.pid;
9608        report.uid = app.info.uid;
9609        report.tag = activity;
9610        report.shortMsg = shortMsg;
9611        report.longMsg = longMsg;
9612        report.stackTrace = stackTrace;
9613
9614        return report;
9615    }
9616
9617    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9618        synchronized (this) {
9619            app.crashing = false;
9620            app.crashingReport = null;
9621            app.notResponding = false;
9622            app.notRespondingReport = null;
9623            if (app.anrDialog == fromDialog) {
9624                app.anrDialog = null;
9625            }
9626            if (app.waitDialog == fromDialog) {
9627                app.waitDialog = null;
9628            }
9629            if (app.pid > 0 && app.pid != MY_PID) {
9630                handleAppCrashLocked(app, null, null, null);
9631                killUnneededProcessLocked(app, "user request after error");
9632            }
9633        }
9634    }
9635
9636    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9637            String stackTrace) {
9638        long now = SystemClock.uptimeMillis();
9639
9640        Long crashTime;
9641        if (!app.isolated) {
9642            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9643        } else {
9644            crashTime = null;
9645        }
9646        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9647            // This process loses!
9648            Slog.w(TAG, "Process " + app.info.processName
9649                    + " has crashed too many times: killing!");
9650            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9651                    app.userId, app.info.processName, app.uid);
9652            mStackSupervisor.handleAppCrashLocked(app);
9653            if (!app.persistent) {
9654                // We don't want to start this process again until the user
9655                // explicitly does so...  but for persistent process, we really
9656                // need to keep it running.  If a persistent process is actually
9657                // repeatedly crashing, then badness for everyone.
9658                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9659                        app.info.processName);
9660                if (!app.isolated) {
9661                    // XXX We don't have a way to mark isolated processes
9662                    // as bad, since they don't have a peristent identity.
9663                    mBadProcesses.put(app.info.processName, app.uid,
9664                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9665                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9666                }
9667                app.bad = true;
9668                app.removed = true;
9669                // Don't let services in this process be restarted and potentially
9670                // annoy the user repeatedly.  Unless it is persistent, since those
9671                // processes run critical code.
9672                removeProcessLocked(app, false, false, "crash");
9673                mStackSupervisor.resumeTopActivitiesLocked();
9674                return false;
9675            }
9676            mStackSupervisor.resumeTopActivitiesLocked();
9677        } else {
9678            mStackSupervisor.finishTopRunningActivityLocked(app);
9679        }
9680
9681        // Bump up the crash count of any services currently running in the proc.
9682        for (int i=app.services.size()-1; i>=0; i--) {
9683            // Any services running in the application need to be placed
9684            // back in the pending list.
9685            ServiceRecord sr = app.services.valueAt(i);
9686            sr.crashCount++;
9687        }
9688
9689        // If the crashing process is what we consider to be the "home process" and it has been
9690        // replaced by a third-party app, clear the package preferred activities from packages
9691        // with a home activity running in the process to prevent a repeatedly crashing app
9692        // from blocking the user to manually clear the list.
9693        final ArrayList<ActivityRecord> activities = app.activities;
9694        if (app == mHomeProcess && activities.size() > 0
9695                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9696            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9697                final ActivityRecord r = activities.get(activityNdx);
9698                if (r.isHomeActivity()) {
9699                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9700                    try {
9701                        ActivityThread.getPackageManager()
9702                                .clearPackagePreferredActivities(r.packageName);
9703                    } catch (RemoteException c) {
9704                        // pm is in same process, this will never happen.
9705                    }
9706                }
9707            }
9708        }
9709
9710        if (!app.isolated) {
9711            // XXX Can't keep track of crash times for isolated processes,
9712            // because they don't have a perisistent identity.
9713            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9714        }
9715
9716        return true;
9717    }
9718
9719    void startAppProblemLocked(ProcessRecord app) {
9720        if (app.userId == mCurrentUserId) {
9721            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9722                    mContext, app.info.packageName, app.info.flags);
9723        } else {
9724            // If this app is not running under the current user, then we
9725            // can't give it a report button because that would require
9726            // launching the report UI under a different user.
9727            app.errorReportReceiver = null;
9728        }
9729        skipCurrentReceiverLocked(app);
9730    }
9731
9732    void skipCurrentReceiverLocked(ProcessRecord app) {
9733        for (BroadcastQueue queue : mBroadcastQueues) {
9734            queue.skipCurrentReceiverLocked(app);
9735        }
9736    }
9737
9738    /**
9739     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9740     * The application process will exit immediately after this call returns.
9741     * @param app object of the crashing app, null for the system server
9742     * @param crashInfo describing the exception
9743     */
9744    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9745        ProcessRecord r = findAppProcess(app, "Crash");
9746        final String processName = app == null ? "system_server"
9747                : (r == null ? "unknown" : r.processName);
9748
9749        handleApplicationCrashInner("crash", r, processName, crashInfo);
9750    }
9751
9752    /* Native crash reporting uses this inner version because it needs to be somewhat
9753     * decoupled from the AM-managed cleanup lifecycle
9754     */
9755    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9756            ApplicationErrorReport.CrashInfo crashInfo) {
9757        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9758                UserHandle.getUserId(Binder.getCallingUid()), processName,
9759                r == null ? -1 : r.info.flags,
9760                crashInfo.exceptionClassName,
9761                crashInfo.exceptionMessage,
9762                crashInfo.throwFileName,
9763                crashInfo.throwLineNumber);
9764
9765        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9766
9767        crashApplication(r, crashInfo);
9768    }
9769
9770    public void handleApplicationStrictModeViolation(
9771            IBinder app,
9772            int violationMask,
9773            StrictMode.ViolationInfo info) {
9774        ProcessRecord r = findAppProcess(app, "StrictMode");
9775        if (r == null) {
9776            return;
9777        }
9778
9779        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9780            Integer stackFingerprint = info.hashCode();
9781            boolean logIt = true;
9782            synchronized (mAlreadyLoggedViolatedStacks) {
9783                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9784                    logIt = false;
9785                    // TODO: sub-sample into EventLog for these, with
9786                    // the info.durationMillis?  Then we'd get
9787                    // the relative pain numbers, without logging all
9788                    // the stack traces repeatedly.  We'd want to do
9789                    // likewise in the client code, which also does
9790                    // dup suppression, before the Binder call.
9791                } else {
9792                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9793                        mAlreadyLoggedViolatedStacks.clear();
9794                    }
9795                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9796                }
9797            }
9798            if (logIt) {
9799                logStrictModeViolationToDropBox(r, info);
9800            }
9801        }
9802
9803        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9804            AppErrorResult result = new AppErrorResult();
9805            synchronized (this) {
9806                final long origId = Binder.clearCallingIdentity();
9807
9808                Message msg = Message.obtain();
9809                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9810                HashMap<String, Object> data = new HashMap<String, Object>();
9811                data.put("result", result);
9812                data.put("app", r);
9813                data.put("violationMask", violationMask);
9814                data.put("info", info);
9815                msg.obj = data;
9816                mHandler.sendMessage(msg);
9817
9818                Binder.restoreCallingIdentity(origId);
9819            }
9820            int res = result.get();
9821            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9822        }
9823    }
9824
9825    // Depending on the policy in effect, there could be a bunch of
9826    // these in quick succession so we try to batch these together to
9827    // minimize disk writes, number of dropbox entries, and maximize
9828    // compression, by having more fewer, larger records.
9829    private void logStrictModeViolationToDropBox(
9830            ProcessRecord process,
9831            StrictMode.ViolationInfo info) {
9832        if (info == null) {
9833            return;
9834        }
9835        final boolean isSystemApp = process == null ||
9836                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9837                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9838        final String processName = process == null ? "unknown" : process.processName;
9839        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9840        final DropBoxManager dbox = (DropBoxManager)
9841                mContext.getSystemService(Context.DROPBOX_SERVICE);
9842
9843        // Exit early if the dropbox isn't configured to accept this report type.
9844        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9845
9846        boolean bufferWasEmpty;
9847        boolean needsFlush;
9848        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9849        synchronized (sb) {
9850            bufferWasEmpty = sb.length() == 0;
9851            appendDropBoxProcessHeaders(process, processName, sb);
9852            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9853            sb.append("System-App: ").append(isSystemApp).append("\n");
9854            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9855            if (info.violationNumThisLoop != 0) {
9856                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9857            }
9858            if (info.numAnimationsRunning != 0) {
9859                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9860            }
9861            if (info.broadcastIntentAction != null) {
9862                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9863            }
9864            if (info.durationMillis != -1) {
9865                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9866            }
9867            if (info.numInstances != -1) {
9868                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9869            }
9870            if (info.tags != null) {
9871                for (String tag : info.tags) {
9872                    sb.append("Span-Tag: ").append(tag).append("\n");
9873                }
9874            }
9875            sb.append("\n");
9876            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9877                sb.append(info.crashInfo.stackTrace);
9878            }
9879            sb.append("\n");
9880
9881            // Only buffer up to ~64k.  Various logging bits truncate
9882            // things at 128k.
9883            needsFlush = (sb.length() > 64 * 1024);
9884        }
9885
9886        // Flush immediately if the buffer's grown too large, or this
9887        // is a non-system app.  Non-system apps are isolated with a
9888        // different tag & policy and not batched.
9889        //
9890        // Batching is useful during internal testing with
9891        // StrictMode settings turned up high.  Without batching,
9892        // thousands of separate files could be created on boot.
9893        if (!isSystemApp || needsFlush) {
9894            new Thread("Error dump: " + dropboxTag) {
9895                @Override
9896                public void run() {
9897                    String report;
9898                    synchronized (sb) {
9899                        report = sb.toString();
9900                        sb.delete(0, sb.length());
9901                        sb.trimToSize();
9902                    }
9903                    if (report.length() != 0) {
9904                        dbox.addText(dropboxTag, report);
9905                    }
9906                }
9907            }.start();
9908            return;
9909        }
9910
9911        // System app batching:
9912        if (!bufferWasEmpty) {
9913            // An existing dropbox-writing thread is outstanding, so
9914            // we don't need to start it up.  The existing thread will
9915            // catch the buffer appends we just did.
9916            return;
9917        }
9918
9919        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9920        // (After this point, we shouldn't access AMS internal data structures.)
9921        new Thread("Error dump: " + dropboxTag) {
9922            @Override
9923            public void run() {
9924                // 5 second sleep to let stacks arrive and be batched together
9925                try {
9926                    Thread.sleep(5000);  // 5 seconds
9927                } catch (InterruptedException e) {}
9928
9929                String errorReport;
9930                synchronized (mStrictModeBuffer) {
9931                    errorReport = mStrictModeBuffer.toString();
9932                    if (errorReport.length() == 0) {
9933                        return;
9934                    }
9935                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9936                    mStrictModeBuffer.trimToSize();
9937                }
9938                dbox.addText(dropboxTag, errorReport);
9939            }
9940        }.start();
9941    }
9942
9943    /**
9944     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9945     * @param app object of the crashing app, null for the system server
9946     * @param tag reported by the caller
9947     * @param crashInfo describing the context of the error
9948     * @return true if the process should exit immediately (WTF is fatal)
9949     */
9950    public boolean handleApplicationWtf(IBinder app, String tag,
9951            ApplicationErrorReport.CrashInfo crashInfo) {
9952        ProcessRecord r = findAppProcess(app, "WTF");
9953        final String processName = app == null ? "system_server"
9954                : (r == null ? "unknown" : r.processName);
9955
9956        EventLog.writeEvent(EventLogTags.AM_WTF,
9957                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9958                processName,
9959                r == null ? -1 : r.info.flags,
9960                tag, crashInfo.exceptionMessage);
9961
9962        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9963
9964        if (r != null && r.pid != Process.myPid() &&
9965                Settings.Global.getInt(mContext.getContentResolver(),
9966                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9967            crashApplication(r, crashInfo);
9968            return true;
9969        } else {
9970            return false;
9971        }
9972    }
9973
9974    /**
9975     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9976     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9977     */
9978    private ProcessRecord findAppProcess(IBinder app, String reason) {
9979        if (app == null) {
9980            return null;
9981        }
9982
9983        synchronized (this) {
9984            final int NP = mProcessNames.getMap().size();
9985            for (int ip=0; ip<NP; ip++) {
9986                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9987                final int NA = apps.size();
9988                for (int ia=0; ia<NA; ia++) {
9989                    ProcessRecord p = apps.valueAt(ia);
9990                    if (p.thread != null && p.thread.asBinder() == app) {
9991                        return p;
9992                    }
9993                }
9994            }
9995
9996            Slog.w(TAG, "Can't find mystery application for " + reason
9997                    + " from pid=" + Binder.getCallingPid()
9998                    + " uid=" + Binder.getCallingUid() + ": " + app);
9999            return null;
10000        }
10001    }
10002
10003    /**
10004     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10005     * to append various headers to the dropbox log text.
10006     */
10007    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10008            StringBuilder sb) {
10009        // Watchdog thread ends up invoking this function (with
10010        // a null ProcessRecord) to add the stack file to dropbox.
10011        // Do not acquire a lock on this (am) in such cases, as it
10012        // could cause a potential deadlock, if and when watchdog
10013        // is invoked due to unavailability of lock on am and it
10014        // would prevent watchdog from killing system_server.
10015        if (process == null) {
10016            sb.append("Process: ").append(processName).append("\n");
10017            return;
10018        }
10019        // Note: ProcessRecord 'process' is guarded by the service
10020        // instance.  (notably process.pkgList, which could otherwise change
10021        // concurrently during execution of this method)
10022        synchronized (this) {
10023            sb.append("Process: ").append(processName).append("\n");
10024            int flags = process.info.flags;
10025            IPackageManager pm = AppGlobals.getPackageManager();
10026            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10027            for (int ip=0; ip<process.pkgList.size(); ip++) {
10028                String pkg = process.pkgList.keyAt(ip);
10029                sb.append("Package: ").append(pkg);
10030                try {
10031                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10032                    if (pi != null) {
10033                        sb.append(" v").append(pi.versionCode);
10034                        if (pi.versionName != null) {
10035                            sb.append(" (").append(pi.versionName).append(")");
10036                        }
10037                    }
10038                } catch (RemoteException e) {
10039                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10040                }
10041                sb.append("\n");
10042            }
10043        }
10044    }
10045
10046    private static String processClass(ProcessRecord process) {
10047        if (process == null || process.pid == MY_PID) {
10048            return "system_server";
10049        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10050            return "system_app";
10051        } else {
10052            return "data_app";
10053        }
10054    }
10055
10056    /**
10057     * Write a description of an error (crash, WTF, ANR) to the drop box.
10058     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10059     * @param process which caused the error, null means the system server
10060     * @param activity which triggered the error, null if unknown
10061     * @param parent activity related to the error, null if unknown
10062     * @param subject line related to the error, null if absent
10063     * @param report in long form describing the error, null if absent
10064     * @param logFile to include in the report, null if none
10065     * @param crashInfo giving an application stack trace, null if absent
10066     */
10067    public void addErrorToDropBox(String eventType,
10068            ProcessRecord process, String processName, ActivityRecord activity,
10069            ActivityRecord parent, String subject,
10070            final String report, final File logFile,
10071            final ApplicationErrorReport.CrashInfo crashInfo) {
10072        // NOTE -- this must never acquire the ActivityManagerService lock,
10073        // otherwise the watchdog may be prevented from resetting the system.
10074
10075        final String dropboxTag = processClass(process) + "_" + eventType;
10076        final DropBoxManager dbox = (DropBoxManager)
10077                mContext.getSystemService(Context.DROPBOX_SERVICE);
10078
10079        // Exit early if the dropbox isn't configured to accept this report type.
10080        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10081
10082        final StringBuilder sb = new StringBuilder(1024);
10083        appendDropBoxProcessHeaders(process, processName, sb);
10084        if (activity != null) {
10085            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10086        }
10087        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10088            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10089        }
10090        if (parent != null && parent != activity) {
10091            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10092        }
10093        if (subject != null) {
10094            sb.append("Subject: ").append(subject).append("\n");
10095        }
10096        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10097        if (Debug.isDebuggerConnected()) {
10098            sb.append("Debugger: Connected\n");
10099        }
10100        sb.append("\n");
10101
10102        // Do the rest in a worker thread to avoid blocking the caller on I/O
10103        // (After this point, we shouldn't access AMS internal data structures.)
10104        Thread worker = new Thread("Error dump: " + dropboxTag) {
10105            @Override
10106            public void run() {
10107                if (report != null) {
10108                    sb.append(report);
10109                }
10110                if (logFile != null) {
10111                    try {
10112                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10113                                    "\n\n[[TRUNCATED]]"));
10114                    } catch (IOException e) {
10115                        Slog.e(TAG, "Error reading " + logFile, e);
10116                    }
10117                }
10118                if (crashInfo != null && crashInfo.stackTrace != null) {
10119                    sb.append(crashInfo.stackTrace);
10120                }
10121
10122                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10123                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10124                if (lines > 0) {
10125                    sb.append("\n");
10126
10127                    // Merge several logcat streams, and take the last N lines
10128                    InputStreamReader input = null;
10129                    try {
10130                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10131                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10132                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10133
10134                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10135                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10136                        input = new InputStreamReader(logcat.getInputStream());
10137
10138                        int num;
10139                        char[] buf = new char[8192];
10140                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10141                    } catch (IOException e) {
10142                        Slog.e(TAG, "Error running logcat", e);
10143                    } finally {
10144                        if (input != null) try { input.close(); } catch (IOException e) {}
10145                    }
10146                }
10147
10148                dbox.addText(dropboxTag, sb.toString());
10149            }
10150        };
10151
10152        if (process == null) {
10153            // If process is null, we are being called from some internal code
10154            // and may be about to die -- run this synchronously.
10155            worker.run();
10156        } else {
10157            worker.start();
10158        }
10159    }
10160
10161    /**
10162     * Bring up the "unexpected error" dialog box for a crashing app.
10163     * Deal with edge cases (intercepts from instrumented applications,
10164     * ActivityController, error intent receivers, that sort of thing).
10165     * @param r the application crashing
10166     * @param crashInfo describing the failure
10167     */
10168    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10169        long timeMillis = System.currentTimeMillis();
10170        String shortMsg = crashInfo.exceptionClassName;
10171        String longMsg = crashInfo.exceptionMessage;
10172        String stackTrace = crashInfo.stackTrace;
10173        if (shortMsg != null && longMsg != null) {
10174            longMsg = shortMsg + ": " + longMsg;
10175        } else if (shortMsg != null) {
10176            longMsg = shortMsg;
10177        }
10178
10179        AppErrorResult result = new AppErrorResult();
10180        synchronized (this) {
10181            if (mController != null) {
10182                try {
10183                    String name = r != null ? r.processName : null;
10184                    int pid = r != null ? r.pid : Binder.getCallingPid();
10185                    if (!mController.appCrashed(name, pid,
10186                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10187                        Slog.w(TAG, "Force-killing crashed app " + name
10188                                + " at watcher's request");
10189                        Process.killProcess(pid);
10190                        return;
10191                    }
10192                } catch (RemoteException e) {
10193                    mController = null;
10194                    Watchdog.getInstance().setActivityController(null);
10195                }
10196            }
10197
10198            final long origId = Binder.clearCallingIdentity();
10199
10200            // If this process is running instrumentation, finish it.
10201            if (r != null && r.instrumentationClass != null) {
10202                Slog.w(TAG, "Error in app " + r.processName
10203                      + " running instrumentation " + r.instrumentationClass + ":");
10204                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10205                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10206                Bundle info = new Bundle();
10207                info.putString("shortMsg", shortMsg);
10208                info.putString("longMsg", longMsg);
10209                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10210                Binder.restoreCallingIdentity(origId);
10211                return;
10212            }
10213
10214            // If we can't identify the process or it's already exceeded its crash quota,
10215            // quit right away without showing a crash dialog.
10216            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10217                Binder.restoreCallingIdentity(origId);
10218                return;
10219            }
10220
10221            Message msg = Message.obtain();
10222            msg.what = SHOW_ERROR_MSG;
10223            HashMap data = new HashMap();
10224            data.put("result", result);
10225            data.put("app", r);
10226            msg.obj = data;
10227            mHandler.sendMessage(msg);
10228
10229            Binder.restoreCallingIdentity(origId);
10230        }
10231
10232        int res = result.get();
10233
10234        Intent appErrorIntent = null;
10235        synchronized (this) {
10236            if (r != null && !r.isolated) {
10237                // XXX Can't keep track of crash time for isolated processes,
10238                // since they don't have a persistent identity.
10239                mProcessCrashTimes.put(r.info.processName, r.uid,
10240                        SystemClock.uptimeMillis());
10241            }
10242            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10243                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10244            }
10245        }
10246
10247        if (appErrorIntent != null) {
10248            try {
10249                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10250            } catch (ActivityNotFoundException e) {
10251                Slog.w(TAG, "bug report receiver dissappeared", e);
10252            }
10253        }
10254    }
10255
10256    Intent createAppErrorIntentLocked(ProcessRecord r,
10257            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10258        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10259        if (report == null) {
10260            return null;
10261        }
10262        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10263        result.setComponent(r.errorReportReceiver);
10264        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10265        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10266        return result;
10267    }
10268
10269    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10270            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10271        if (r.errorReportReceiver == null) {
10272            return null;
10273        }
10274
10275        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10276            return null;
10277        }
10278
10279        ApplicationErrorReport report = new ApplicationErrorReport();
10280        report.packageName = r.info.packageName;
10281        report.installerPackageName = r.errorReportReceiver.getPackageName();
10282        report.processName = r.processName;
10283        report.time = timeMillis;
10284        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10285
10286        if (r.crashing || r.forceCrashReport) {
10287            report.type = ApplicationErrorReport.TYPE_CRASH;
10288            report.crashInfo = crashInfo;
10289        } else if (r.notResponding) {
10290            report.type = ApplicationErrorReport.TYPE_ANR;
10291            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10292
10293            report.anrInfo.activity = r.notRespondingReport.tag;
10294            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10295            report.anrInfo.info = r.notRespondingReport.longMsg;
10296        }
10297
10298        return report;
10299    }
10300
10301    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10302        enforceNotIsolatedCaller("getProcessesInErrorState");
10303        // assume our apps are happy - lazy create the list
10304        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10305
10306        final boolean allUsers = ActivityManager.checkUidPermission(
10307                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10308                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10309        int userId = UserHandle.getUserId(Binder.getCallingUid());
10310
10311        synchronized (this) {
10312
10313            // iterate across all processes
10314            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10315                ProcessRecord app = mLruProcesses.get(i);
10316                if (!allUsers && app.userId != userId) {
10317                    continue;
10318                }
10319                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10320                    // This one's in trouble, so we'll generate a report for it
10321                    // crashes are higher priority (in case there's a crash *and* an anr)
10322                    ActivityManager.ProcessErrorStateInfo report = null;
10323                    if (app.crashing) {
10324                        report = app.crashingReport;
10325                    } else if (app.notResponding) {
10326                        report = app.notRespondingReport;
10327                    }
10328
10329                    if (report != null) {
10330                        if (errList == null) {
10331                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10332                        }
10333                        errList.add(report);
10334                    } else {
10335                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10336                                " crashing = " + app.crashing +
10337                                " notResponding = " + app.notResponding);
10338                    }
10339                }
10340            }
10341        }
10342
10343        return errList;
10344    }
10345
10346    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10347        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10348            if (currApp != null) {
10349                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10350            }
10351            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10352        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10353            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10354        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10355            if (currApp != null) {
10356                currApp.lru = 0;
10357            }
10358            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10359        } else if (adj >= ProcessList.SERVICE_ADJ) {
10360            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10361        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10362            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10363        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10364            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10365        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10366            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10367        } else {
10368            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10369        }
10370    }
10371
10372    private void fillInProcMemInfo(ProcessRecord app,
10373            ActivityManager.RunningAppProcessInfo outInfo) {
10374        outInfo.pid = app.pid;
10375        outInfo.uid = app.info.uid;
10376        if (mHeavyWeightProcess == app) {
10377            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10378        }
10379        if (app.persistent) {
10380            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10381        }
10382        if (app.activities.size() > 0) {
10383            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10384        }
10385        outInfo.lastTrimLevel = app.trimMemoryLevel;
10386        int adj = app.curAdj;
10387        outInfo.importance = oomAdjToImportance(adj, outInfo);
10388        outInfo.importanceReasonCode = app.adjTypeCode;
10389    }
10390
10391    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10392        enforceNotIsolatedCaller("getRunningAppProcesses");
10393        // Lazy instantiation of list
10394        List<ActivityManager.RunningAppProcessInfo> runList = null;
10395        final boolean allUsers = ActivityManager.checkUidPermission(
10396                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10397                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10398        int userId = UserHandle.getUserId(Binder.getCallingUid());
10399        synchronized (this) {
10400            // Iterate across all processes
10401            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10402                ProcessRecord app = mLruProcesses.get(i);
10403                if (!allUsers && app.userId != userId) {
10404                    continue;
10405                }
10406                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10407                    // Generate process state info for running application
10408                    ActivityManager.RunningAppProcessInfo currApp =
10409                        new ActivityManager.RunningAppProcessInfo(app.processName,
10410                                app.pid, app.getPackageList());
10411                    fillInProcMemInfo(app, currApp);
10412                    if (app.adjSource instanceof ProcessRecord) {
10413                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10414                        currApp.importanceReasonImportance = oomAdjToImportance(
10415                                app.adjSourceOom, null);
10416                    } else if (app.adjSource instanceof ActivityRecord) {
10417                        ActivityRecord r = (ActivityRecord)app.adjSource;
10418                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10419                    }
10420                    if (app.adjTarget instanceof ComponentName) {
10421                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10422                    }
10423                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10424                    //        + " lru=" + currApp.lru);
10425                    if (runList == null) {
10426                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10427                    }
10428                    runList.add(currApp);
10429                }
10430            }
10431        }
10432        return runList;
10433    }
10434
10435    public List<ApplicationInfo> getRunningExternalApplications() {
10436        enforceNotIsolatedCaller("getRunningExternalApplications");
10437        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10438        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10439        if (runningApps != null && runningApps.size() > 0) {
10440            Set<String> extList = new HashSet<String>();
10441            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10442                if (app.pkgList != null) {
10443                    for (String pkg : app.pkgList) {
10444                        extList.add(pkg);
10445                    }
10446                }
10447            }
10448            IPackageManager pm = AppGlobals.getPackageManager();
10449            for (String pkg : extList) {
10450                try {
10451                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10452                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10453                        retList.add(info);
10454                    }
10455                } catch (RemoteException e) {
10456                }
10457            }
10458        }
10459        return retList;
10460    }
10461
10462    @Override
10463    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10464        enforceNotIsolatedCaller("getMyMemoryState");
10465        synchronized (this) {
10466            ProcessRecord proc;
10467            synchronized (mPidsSelfLocked) {
10468                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10469            }
10470            fillInProcMemInfo(proc, outInfo);
10471        }
10472    }
10473
10474    @Override
10475    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10476        if (checkCallingPermission(android.Manifest.permission.DUMP)
10477                != PackageManager.PERMISSION_GRANTED) {
10478            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10479                    + Binder.getCallingPid()
10480                    + ", uid=" + Binder.getCallingUid()
10481                    + " without permission "
10482                    + android.Manifest.permission.DUMP);
10483            return;
10484        }
10485
10486        boolean dumpAll = false;
10487        boolean dumpClient = false;
10488        String dumpPackage = null;
10489
10490        int opti = 0;
10491        while (opti < args.length) {
10492            String opt = args[opti];
10493            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10494                break;
10495            }
10496            opti++;
10497            if ("-a".equals(opt)) {
10498                dumpAll = true;
10499            } else if ("-c".equals(opt)) {
10500                dumpClient = true;
10501            } else if ("-h".equals(opt)) {
10502                pw.println("Activity manager dump options:");
10503                pw.println("  [-a] [-c] [-h] [cmd] ...");
10504                pw.println("  cmd may be one of:");
10505                pw.println("    a[ctivities]: activity stack state");
10506                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10507                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10508                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10509                pw.println("    o[om]: out of memory management");
10510                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10511                pw.println("    provider [COMP_SPEC]: provider client-side state");
10512                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10513                pw.println("    service [COMP_SPEC]: service client-side state");
10514                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10515                pw.println("    all: dump all activities");
10516                pw.println("    top: dump the top activity");
10517                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10518                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10519                pw.println("    a partial substring in a component name, a");
10520                pw.println("    hex object identifier.");
10521                pw.println("  -a: include all available server state.");
10522                pw.println("  -c: include client state.");
10523                return;
10524            } else {
10525                pw.println("Unknown argument: " + opt + "; use -h for help");
10526            }
10527        }
10528
10529        long origId = Binder.clearCallingIdentity();
10530        boolean more = false;
10531        // Is the caller requesting to dump a particular piece of data?
10532        if (opti < args.length) {
10533            String cmd = args[opti];
10534            opti++;
10535            if ("activities".equals(cmd) || "a".equals(cmd)) {
10536                synchronized (this) {
10537                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10538                }
10539            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10540                String[] newArgs;
10541                String name;
10542                if (opti >= args.length) {
10543                    name = null;
10544                    newArgs = EMPTY_STRING_ARRAY;
10545                } else {
10546                    name = args[opti];
10547                    opti++;
10548                    newArgs = new String[args.length - opti];
10549                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10550                            args.length - opti);
10551                }
10552                synchronized (this) {
10553                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10554                }
10555            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10556                String[] newArgs;
10557                String name;
10558                if (opti >= args.length) {
10559                    name = null;
10560                    newArgs = EMPTY_STRING_ARRAY;
10561                } else {
10562                    name = args[opti];
10563                    opti++;
10564                    newArgs = new String[args.length - opti];
10565                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10566                            args.length - opti);
10567                }
10568                synchronized (this) {
10569                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10570                }
10571            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10572                String[] newArgs;
10573                String name;
10574                if (opti >= args.length) {
10575                    name = null;
10576                    newArgs = EMPTY_STRING_ARRAY;
10577                } else {
10578                    name = args[opti];
10579                    opti++;
10580                    newArgs = new String[args.length - opti];
10581                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10582                            args.length - opti);
10583                }
10584                synchronized (this) {
10585                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10586                }
10587            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10588                synchronized (this) {
10589                    dumpOomLocked(fd, pw, args, opti, true);
10590                }
10591            } else if ("provider".equals(cmd)) {
10592                String[] newArgs;
10593                String name;
10594                if (opti >= args.length) {
10595                    name = null;
10596                    newArgs = EMPTY_STRING_ARRAY;
10597                } else {
10598                    name = args[opti];
10599                    opti++;
10600                    newArgs = new String[args.length - opti];
10601                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10602                }
10603                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10604                    pw.println("No providers match: " + name);
10605                    pw.println("Use -h for help.");
10606                }
10607            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10608                synchronized (this) {
10609                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10610                }
10611            } else if ("service".equals(cmd)) {
10612                String[] newArgs;
10613                String name;
10614                if (opti >= args.length) {
10615                    name = null;
10616                    newArgs = EMPTY_STRING_ARRAY;
10617                } else {
10618                    name = args[opti];
10619                    opti++;
10620                    newArgs = new String[args.length - opti];
10621                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10622                            args.length - opti);
10623                }
10624                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10625                    pw.println("No services match: " + name);
10626                    pw.println("Use -h for help.");
10627                }
10628            } else if ("package".equals(cmd)) {
10629                String[] newArgs;
10630                if (opti >= args.length) {
10631                    pw.println("package: no package name specified");
10632                    pw.println("Use -h for help.");
10633                } else {
10634                    dumpPackage = args[opti];
10635                    opti++;
10636                    newArgs = new String[args.length - opti];
10637                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10638                            args.length - opti);
10639                    args = newArgs;
10640                    opti = 0;
10641                    more = true;
10642                }
10643            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10644                synchronized (this) {
10645                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10646                }
10647            } else {
10648                // Dumping a single activity?
10649                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10650                    pw.println("Bad activity command, or no activities match: " + cmd);
10651                    pw.println("Use -h for help.");
10652                }
10653            }
10654            if (!more) {
10655                Binder.restoreCallingIdentity(origId);
10656                return;
10657            }
10658        }
10659
10660        // No piece of data specified, dump everything.
10661        synchronized (this) {
10662            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10663            pw.println();
10664            if (dumpAll) {
10665                pw.println("-------------------------------------------------------------------------------");
10666            }
10667            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10668            pw.println();
10669            if (dumpAll) {
10670                pw.println("-------------------------------------------------------------------------------");
10671            }
10672            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10673            pw.println();
10674            if (dumpAll) {
10675                pw.println("-------------------------------------------------------------------------------");
10676            }
10677            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10678            pw.println();
10679            if (dumpAll) {
10680                pw.println("-------------------------------------------------------------------------------");
10681            }
10682            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10683            pw.println();
10684            if (dumpAll) {
10685                pw.println("-------------------------------------------------------------------------------");
10686            }
10687            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10688        }
10689        Binder.restoreCallingIdentity(origId);
10690    }
10691
10692    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10693            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10694        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10695
10696        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10697                dumpPackage);
10698        boolean needSep = printedAnything;
10699
10700        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10701                dumpPackage, needSep, "  mFocusedActivity: ");
10702        if (printed) {
10703            printedAnything = true;
10704            needSep = false;
10705        }
10706
10707        if (dumpPackage == null) {
10708            if (needSep) {
10709                pw.println();
10710            }
10711            needSep = true;
10712            printedAnything = true;
10713            mStackSupervisor.dump(pw, "  ");
10714        }
10715
10716        if (mRecentTasks.size() > 0) {
10717            boolean printedHeader = false;
10718
10719            final int N = mRecentTasks.size();
10720            for (int i=0; i<N; i++) {
10721                TaskRecord tr = mRecentTasks.get(i);
10722                if (dumpPackage != null) {
10723                    if (tr.realActivity == null ||
10724                            !dumpPackage.equals(tr.realActivity)) {
10725                        continue;
10726                    }
10727                }
10728                if (!printedHeader) {
10729                    if (needSep) {
10730                        pw.println();
10731                    }
10732                    pw.println("  Recent tasks:");
10733                    printedHeader = true;
10734                    printedAnything = true;
10735                }
10736                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10737                        pw.println(tr);
10738                if (dumpAll) {
10739                    mRecentTasks.get(i).dump(pw, "    ");
10740                }
10741            }
10742        }
10743
10744        if (!printedAnything) {
10745            pw.println("  (nothing)");
10746        }
10747    }
10748
10749    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10750            int opti, boolean dumpAll, String dumpPackage) {
10751        boolean needSep = false;
10752        boolean printedAnything = false;
10753        int numPers = 0;
10754
10755        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10756
10757        if (dumpAll) {
10758            final int NP = mProcessNames.getMap().size();
10759            for (int ip=0; ip<NP; ip++) {
10760                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10761                final int NA = procs.size();
10762                for (int ia=0; ia<NA; ia++) {
10763                    ProcessRecord r = procs.valueAt(ia);
10764                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10765                        continue;
10766                    }
10767                    if (!needSep) {
10768                        pw.println("  All known processes:");
10769                        needSep = true;
10770                        printedAnything = true;
10771                    }
10772                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10773                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10774                        pw.print(" "); pw.println(r);
10775                    r.dump(pw, "    ");
10776                    if (r.persistent) {
10777                        numPers++;
10778                    }
10779                }
10780            }
10781        }
10782
10783        if (mIsolatedProcesses.size() > 0) {
10784            boolean printed = false;
10785            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10786                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10787                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10788                    continue;
10789                }
10790                if (!printed) {
10791                    if (needSep) {
10792                        pw.println();
10793                    }
10794                    pw.println("  Isolated process list (sorted by uid):");
10795                    printedAnything = true;
10796                    printed = true;
10797                    needSep = true;
10798                }
10799                pw.println(String.format("%sIsolated #%2d: %s",
10800                        "    ", i, r.toString()));
10801            }
10802        }
10803
10804        if (mLruProcesses.size() > 0) {
10805            if (needSep) {
10806                pw.println();
10807            }
10808            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10809                    pw.print(" total, non-act at ");
10810                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10811                    pw.print(", non-svc at ");
10812                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10813                    pw.println("):");
10814            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10815            needSep = true;
10816            printedAnything = true;
10817        }
10818
10819        if (dumpAll || dumpPackage != null) {
10820            synchronized (mPidsSelfLocked) {
10821                boolean printed = false;
10822                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10823                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10824                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10825                        continue;
10826                    }
10827                    if (!printed) {
10828                        if (needSep) pw.println();
10829                        needSep = true;
10830                        pw.println("  PID mappings:");
10831                        printed = true;
10832                        printedAnything = true;
10833                    }
10834                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10835                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10836                }
10837            }
10838        }
10839
10840        if (mForegroundProcesses.size() > 0) {
10841            synchronized (mPidsSelfLocked) {
10842                boolean printed = false;
10843                for (int i=0; i<mForegroundProcesses.size(); i++) {
10844                    ProcessRecord r = mPidsSelfLocked.get(
10845                            mForegroundProcesses.valueAt(i).pid);
10846                    if (dumpPackage != null && (r == null
10847                            || !r.pkgList.containsKey(dumpPackage))) {
10848                        continue;
10849                    }
10850                    if (!printed) {
10851                        if (needSep) pw.println();
10852                        needSep = true;
10853                        pw.println("  Foreground Processes:");
10854                        printed = true;
10855                        printedAnything = true;
10856                    }
10857                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10858                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10859                }
10860            }
10861        }
10862
10863        if (mPersistentStartingProcesses.size() > 0) {
10864            if (needSep) pw.println();
10865            needSep = true;
10866            printedAnything = true;
10867            pw.println("  Persisent processes that are starting:");
10868            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10869                    "Starting Norm", "Restarting PERS", dumpPackage);
10870        }
10871
10872        if (mRemovedProcesses.size() > 0) {
10873            if (needSep) pw.println();
10874            needSep = true;
10875            printedAnything = true;
10876            pw.println("  Processes that are being removed:");
10877            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10878                    "Removed Norm", "Removed PERS", dumpPackage);
10879        }
10880
10881        if (mProcessesOnHold.size() > 0) {
10882            if (needSep) pw.println();
10883            needSep = true;
10884            printedAnything = true;
10885            pw.println("  Processes that are on old until the system is ready:");
10886            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10887                    "OnHold Norm", "OnHold PERS", dumpPackage);
10888        }
10889
10890        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10891
10892        if (mProcessCrashTimes.getMap().size() > 0) {
10893            boolean printed = false;
10894            long now = SystemClock.uptimeMillis();
10895            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10896            final int NP = pmap.size();
10897            for (int ip=0; ip<NP; ip++) {
10898                String pname = pmap.keyAt(ip);
10899                SparseArray<Long> uids = pmap.valueAt(ip);
10900                final int N = uids.size();
10901                for (int i=0; i<N; i++) {
10902                    int puid = uids.keyAt(i);
10903                    ProcessRecord r = mProcessNames.get(pname, puid);
10904                    if (dumpPackage != null && (r == null
10905                            || !r.pkgList.containsKey(dumpPackage))) {
10906                        continue;
10907                    }
10908                    if (!printed) {
10909                        if (needSep) pw.println();
10910                        needSep = true;
10911                        pw.println("  Time since processes crashed:");
10912                        printed = true;
10913                        printedAnything = true;
10914                    }
10915                    pw.print("    Process "); pw.print(pname);
10916                            pw.print(" uid "); pw.print(puid);
10917                            pw.print(": last crashed ");
10918                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10919                            pw.println(" ago");
10920                }
10921            }
10922        }
10923
10924        if (mBadProcesses.getMap().size() > 0) {
10925            boolean printed = false;
10926            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10927            final int NP = pmap.size();
10928            for (int ip=0; ip<NP; ip++) {
10929                String pname = pmap.keyAt(ip);
10930                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10931                final int N = uids.size();
10932                for (int i=0; i<N; i++) {
10933                    int puid = uids.keyAt(i);
10934                    ProcessRecord r = mProcessNames.get(pname, puid);
10935                    if (dumpPackage != null && (r == null
10936                            || !r.pkgList.containsKey(dumpPackage))) {
10937                        continue;
10938                    }
10939                    if (!printed) {
10940                        if (needSep) pw.println();
10941                        needSep = true;
10942                        pw.println("  Bad processes:");
10943                        printedAnything = true;
10944                    }
10945                    BadProcessInfo info = uids.valueAt(i);
10946                    pw.print("    Bad process "); pw.print(pname);
10947                            pw.print(" uid "); pw.print(puid);
10948                            pw.print(": crashed at time "); pw.println(info.time);
10949                    if (info.shortMsg != null) {
10950                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10951                    }
10952                    if (info.longMsg != null) {
10953                        pw.print("      Long msg: "); pw.println(info.longMsg);
10954                    }
10955                    if (info.stack != null) {
10956                        pw.println("      Stack:");
10957                        int lastPos = 0;
10958                        for (int pos=0; pos<info.stack.length(); pos++) {
10959                            if (info.stack.charAt(pos) == '\n') {
10960                                pw.print("        ");
10961                                pw.write(info.stack, lastPos, pos-lastPos);
10962                                pw.println();
10963                                lastPos = pos+1;
10964                            }
10965                        }
10966                        if (lastPos < info.stack.length()) {
10967                            pw.print("        ");
10968                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10969                            pw.println();
10970                        }
10971                    }
10972                }
10973            }
10974        }
10975
10976        if (dumpPackage == null) {
10977            pw.println();
10978            needSep = false;
10979            pw.println("  mStartedUsers:");
10980            for (int i=0; i<mStartedUsers.size(); i++) {
10981                UserStartedState uss = mStartedUsers.valueAt(i);
10982                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10983                        pw.print(": "); uss.dump("", pw);
10984            }
10985            pw.print("  mStartedUserArray: [");
10986            for (int i=0; i<mStartedUserArray.length; i++) {
10987                if (i > 0) pw.print(", ");
10988                pw.print(mStartedUserArray[i]);
10989            }
10990            pw.println("]");
10991            pw.print("  mUserLru: [");
10992            for (int i=0; i<mUserLru.size(); i++) {
10993                if (i > 0) pw.print(", ");
10994                pw.print(mUserLru.get(i));
10995            }
10996            pw.println("]");
10997            if (dumpAll) {
10998                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10999            }
11000        }
11001        if (mHomeProcess != null && (dumpPackage == null
11002                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11003            if (needSep) {
11004                pw.println();
11005                needSep = false;
11006            }
11007            pw.println("  mHomeProcess: " + mHomeProcess);
11008        }
11009        if (mPreviousProcess != null && (dumpPackage == null
11010                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11011            if (needSep) {
11012                pw.println();
11013                needSep = false;
11014            }
11015            pw.println("  mPreviousProcess: " + mPreviousProcess);
11016        }
11017        if (dumpAll) {
11018            StringBuilder sb = new StringBuilder(128);
11019            sb.append("  mPreviousProcessVisibleTime: ");
11020            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11021            pw.println(sb);
11022        }
11023        if (mHeavyWeightProcess != null && (dumpPackage == null
11024                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11025            if (needSep) {
11026                pw.println();
11027                needSep = false;
11028            }
11029            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11030        }
11031        if (dumpPackage == null) {
11032            pw.println("  mConfiguration: " + mConfiguration);
11033        }
11034        if (dumpAll) {
11035            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11036            if (mCompatModePackages.getPackages().size() > 0) {
11037                boolean printed = false;
11038                for (Map.Entry<String, Integer> entry
11039                        : mCompatModePackages.getPackages().entrySet()) {
11040                    String pkg = entry.getKey();
11041                    int mode = entry.getValue();
11042                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11043                        continue;
11044                    }
11045                    if (!printed) {
11046                        pw.println("  mScreenCompatPackages:");
11047                        printed = true;
11048                    }
11049                    pw.print("    "); pw.print(pkg); pw.print(": ");
11050                            pw.print(mode); pw.println();
11051                }
11052            }
11053        }
11054        if (dumpPackage == null) {
11055            if (mSleeping || mWentToSleep || mLockScreenShown) {
11056                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11057                        + " mLockScreenShown " + mLockScreenShown);
11058            }
11059            if (mShuttingDown) {
11060                pw.println("  mShuttingDown=" + mShuttingDown);
11061            }
11062        }
11063        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11064                || mOrigWaitForDebugger) {
11065            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11066                    || dumpPackage.equals(mOrigDebugApp)) {
11067                if (needSep) {
11068                    pw.println();
11069                    needSep = false;
11070                }
11071                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11072                        + " mDebugTransient=" + mDebugTransient
11073                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11074            }
11075        }
11076        if (mOpenGlTraceApp != null) {
11077            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11078                if (needSep) {
11079                    pw.println();
11080                    needSep = false;
11081                }
11082                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11083            }
11084        }
11085        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11086                || mProfileFd != null) {
11087            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11088                if (needSep) {
11089                    pw.println();
11090                    needSep = false;
11091                }
11092                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11093                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11094                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11095                        + mAutoStopProfiler);
11096            }
11097        }
11098        if (dumpPackage == null) {
11099            if (mAlwaysFinishActivities || mController != null) {
11100                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11101                        + " mController=" + mController);
11102            }
11103            if (dumpAll) {
11104                pw.println("  Total persistent processes: " + numPers);
11105                pw.println("  mStartRunning=" + mStartRunning
11106                        + " mProcessesReady=" + mProcessesReady
11107                        + " mSystemReady=" + mSystemReady);
11108                pw.println("  mBooting=" + mBooting
11109                        + " mBooted=" + mBooted
11110                        + " mFactoryTest=" + mFactoryTest);
11111                pw.print("  mLastPowerCheckRealtime=");
11112                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11113                        pw.println("");
11114                pw.print("  mLastPowerCheckUptime=");
11115                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11116                        pw.println("");
11117                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11118                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11119                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11120                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11121                        + " (" + mLruProcesses.size() + " total)"
11122                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11123                        + " mNumServiceProcs=" + mNumServiceProcs
11124                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11125                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11126                        + " mLastMemoryLevel" + mLastMemoryLevel
11127                        + " mLastNumProcesses" + mLastNumProcesses);
11128                long now = SystemClock.uptimeMillis();
11129                pw.print("  mLastIdleTime=");
11130                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11131                        pw.print(" mLowRamSinceLastIdle=");
11132                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11133                        pw.println();
11134            }
11135        }
11136
11137        if (!printedAnything) {
11138            pw.println("  (nothing)");
11139        }
11140    }
11141
11142    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11143            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11144        if (mProcessesToGc.size() > 0) {
11145            boolean printed = false;
11146            long now = SystemClock.uptimeMillis();
11147            for (int i=0; i<mProcessesToGc.size(); i++) {
11148                ProcessRecord proc = mProcessesToGc.get(i);
11149                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11150                    continue;
11151                }
11152                if (!printed) {
11153                    if (needSep) pw.println();
11154                    needSep = true;
11155                    pw.println("  Processes that are waiting to GC:");
11156                    printed = true;
11157                }
11158                pw.print("    Process "); pw.println(proc);
11159                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11160                        pw.print(", last gced=");
11161                        pw.print(now-proc.lastRequestedGc);
11162                        pw.print(" ms ago, last lowMem=");
11163                        pw.print(now-proc.lastLowMemory);
11164                        pw.println(" ms ago");
11165
11166            }
11167        }
11168        return needSep;
11169    }
11170
11171    void printOomLevel(PrintWriter pw, String name, int adj) {
11172        pw.print("    ");
11173        if (adj >= 0) {
11174            pw.print(' ');
11175            if (adj < 10) pw.print(' ');
11176        } else {
11177            if (adj > -10) pw.print(' ');
11178        }
11179        pw.print(adj);
11180        pw.print(": ");
11181        pw.print(name);
11182        pw.print(" (");
11183        pw.print(mProcessList.getMemLevel(adj)/1024);
11184        pw.println(" kB)");
11185    }
11186
11187    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11188            int opti, boolean dumpAll) {
11189        boolean needSep = false;
11190
11191        if (mLruProcesses.size() > 0) {
11192            if (needSep) pw.println();
11193            needSep = true;
11194            pw.println("  OOM levels:");
11195            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11196            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11197            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11198            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11199            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11200            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11201            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11202            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11203            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11204            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11205            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11206            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11207            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11208
11209            if (needSep) pw.println();
11210            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11211                    pw.print(" total, non-act at ");
11212                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11213                    pw.print(", non-svc at ");
11214                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11215                    pw.println("):");
11216            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11217            needSep = true;
11218        }
11219
11220        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11221
11222        pw.println();
11223        pw.println("  mHomeProcess: " + mHomeProcess);
11224        pw.println("  mPreviousProcess: " + mPreviousProcess);
11225        if (mHeavyWeightProcess != null) {
11226            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11227        }
11228
11229        return true;
11230    }
11231
11232    /**
11233     * There are three ways to call this:
11234     *  - no provider specified: dump all the providers
11235     *  - a flattened component name that matched an existing provider was specified as the
11236     *    first arg: dump that one provider
11237     *  - the first arg isn't the flattened component name of an existing provider:
11238     *    dump all providers whose component contains the first arg as a substring
11239     */
11240    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11241            int opti, boolean dumpAll) {
11242        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11243    }
11244
11245    static class ItemMatcher {
11246        ArrayList<ComponentName> components;
11247        ArrayList<String> strings;
11248        ArrayList<Integer> objects;
11249        boolean all;
11250
11251        ItemMatcher() {
11252            all = true;
11253        }
11254
11255        void build(String name) {
11256            ComponentName componentName = ComponentName.unflattenFromString(name);
11257            if (componentName != null) {
11258                if (components == null) {
11259                    components = new ArrayList<ComponentName>();
11260                }
11261                components.add(componentName);
11262                all = false;
11263            } else {
11264                int objectId = 0;
11265                // Not a '/' separated full component name; maybe an object ID?
11266                try {
11267                    objectId = Integer.parseInt(name, 16);
11268                    if (objects == null) {
11269                        objects = new ArrayList<Integer>();
11270                    }
11271                    objects.add(objectId);
11272                    all = false;
11273                } catch (RuntimeException e) {
11274                    // Not an integer; just do string match.
11275                    if (strings == null) {
11276                        strings = new ArrayList<String>();
11277                    }
11278                    strings.add(name);
11279                    all = false;
11280                }
11281            }
11282        }
11283
11284        int build(String[] args, int opti) {
11285            for (; opti<args.length; opti++) {
11286                String name = args[opti];
11287                if ("--".equals(name)) {
11288                    return opti+1;
11289                }
11290                build(name);
11291            }
11292            return opti;
11293        }
11294
11295        boolean match(Object object, ComponentName comp) {
11296            if (all) {
11297                return true;
11298            }
11299            if (components != null) {
11300                for (int i=0; i<components.size(); i++) {
11301                    if (components.get(i).equals(comp)) {
11302                        return true;
11303                    }
11304                }
11305            }
11306            if (objects != null) {
11307                for (int i=0; i<objects.size(); i++) {
11308                    if (System.identityHashCode(object) == objects.get(i)) {
11309                        return true;
11310                    }
11311                }
11312            }
11313            if (strings != null) {
11314                String flat = comp.flattenToString();
11315                for (int i=0; i<strings.size(); i++) {
11316                    if (flat.contains(strings.get(i))) {
11317                        return true;
11318                    }
11319                }
11320            }
11321            return false;
11322        }
11323    }
11324
11325    /**
11326     * There are three things that cmd can be:
11327     *  - a flattened component name that matches an existing activity
11328     *  - the cmd arg isn't the flattened component name of an existing activity:
11329     *    dump all activity whose component contains the cmd as a substring
11330     *  - A hex number of the ActivityRecord object instance.
11331     */
11332    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11333            int opti, boolean dumpAll) {
11334        ArrayList<ActivityRecord> activities;
11335
11336        synchronized (this) {
11337            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11338        }
11339
11340        if (activities.size() <= 0) {
11341            return false;
11342        }
11343
11344        String[] newArgs = new String[args.length - opti];
11345        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11346
11347        TaskRecord lastTask = null;
11348        boolean needSep = false;
11349        for (int i=activities.size()-1; i>=0; i--) {
11350            ActivityRecord r = activities.get(i);
11351            if (needSep) {
11352                pw.println();
11353            }
11354            needSep = true;
11355            synchronized (this) {
11356                if (lastTask != r.task) {
11357                    lastTask = r.task;
11358                    pw.print("TASK "); pw.print(lastTask.affinity);
11359                            pw.print(" id="); pw.println(lastTask.taskId);
11360                    if (dumpAll) {
11361                        lastTask.dump(pw, "  ");
11362                    }
11363                }
11364            }
11365            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11366        }
11367        return true;
11368    }
11369
11370    /**
11371     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11372     * there is a thread associated with the activity.
11373     */
11374    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11375            final ActivityRecord r, String[] args, boolean dumpAll) {
11376        String innerPrefix = prefix + "  ";
11377        synchronized (this) {
11378            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11379                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11380                    pw.print(" pid=");
11381                    if (r.app != null) pw.println(r.app.pid);
11382                    else pw.println("(not running)");
11383            if (dumpAll) {
11384                r.dump(pw, innerPrefix);
11385            }
11386        }
11387        if (r.app != null && r.app.thread != null) {
11388            // flush anything that is already in the PrintWriter since the thread is going
11389            // to write to the file descriptor directly
11390            pw.flush();
11391            try {
11392                TransferPipe tp = new TransferPipe();
11393                try {
11394                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11395                            r.appToken, innerPrefix, args);
11396                    tp.go(fd);
11397                } finally {
11398                    tp.kill();
11399                }
11400            } catch (IOException e) {
11401                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11402            } catch (RemoteException e) {
11403                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11404            }
11405        }
11406    }
11407
11408    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11409            int opti, boolean dumpAll, String dumpPackage) {
11410        boolean needSep = false;
11411        boolean onlyHistory = false;
11412        boolean printedAnything = false;
11413
11414        if ("history".equals(dumpPackage)) {
11415            if (opti < args.length && "-s".equals(args[opti])) {
11416                dumpAll = false;
11417            }
11418            onlyHistory = true;
11419            dumpPackage = null;
11420        }
11421
11422        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11423        if (!onlyHistory && dumpAll) {
11424            if (mRegisteredReceivers.size() > 0) {
11425                boolean printed = false;
11426                Iterator it = mRegisteredReceivers.values().iterator();
11427                while (it.hasNext()) {
11428                    ReceiverList r = (ReceiverList)it.next();
11429                    if (dumpPackage != null && (r.app == null ||
11430                            !dumpPackage.equals(r.app.info.packageName))) {
11431                        continue;
11432                    }
11433                    if (!printed) {
11434                        pw.println("  Registered Receivers:");
11435                        needSep = true;
11436                        printed = true;
11437                        printedAnything = true;
11438                    }
11439                    pw.print("  * "); pw.println(r);
11440                    r.dump(pw, "    ");
11441                }
11442            }
11443
11444            if (mReceiverResolver.dump(pw, needSep ?
11445                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11446                    "    ", dumpPackage, false)) {
11447                needSep = true;
11448                printedAnything = true;
11449            }
11450        }
11451
11452        for (BroadcastQueue q : mBroadcastQueues) {
11453            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11454            printedAnything |= needSep;
11455        }
11456
11457        needSep = true;
11458
11459        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11460            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11461                if (needSep) {
11462                    pw.println();
11463                }
11464                needSep = true;
11465                printedAnything = true;
11466                pw.print("  Sticky broadcasts for user ");
11467                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11468                StringBuilder sb = new StringBuilder(128);
11469                for (Map.Entry<String, ArrayList<Intent>> ent
11470                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11471                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11472                    if (dumpAll) {
11473                        pw.println(":");
11474                        ArrayList<Intent> intents = ent.getValue();
11475                        final int N = intents.size();
11476                        for (int i=0; i<N; i++) {
11477                            sb.setLength(0);
11478                            sb.append("    Intent: ");
11479                            intents.get(i).toShortString(sb, false, true, false, false);
11480                            pw.println(sb.toString());
11481                            Bundle bundle = intents.get(i).getExtras();
11482                            if (bundle != null) {
11483                                pw.print("      ");
11484                                pw.println(bundle.toString());
11485                            }
11486                        }
11487                    } else {
11488                        pw.println("");
11489                    }
11490                }
11491            }
11492        }
11493
11494        if (!onlyHistory && dumpAll) {
11495            pw.println();
11496            for (BroadcastQueue queue : mBroadcastQueues) {
11497                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11498                        + queue.mBroadcastsScheduled);
11499            }
11500            pw.println("  mHandler:");
11501            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11502            needSep = true;
11503            printedAnything = true;
11504        }
11505
11506        if (!printedAnything) {
11507            pw.println("  (nothing)");
11508        }
11509    }
11510
11511    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11512            int opti, boolean dumpAll, String dumpPackage) {
11513        boolean needSep;
11514        boolean printedAnything = false;
11515
11516        ItemMatcher matcher = new ItemMatcher();
11517        matcher.build(args, opti);
11518
11519        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11520
11521        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11522        printedAnything |= needSep;
11523
11524        if (mLaunchingProviders.size() > 0) {
11525            boolean printed = false;
11526            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11527                ContentProviderRecord r = mLaunchingProviders.get(i);
11528                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11529                    continue;
11530                }
11531                if (!printed) {
11532                    if (needSep) pw.println();
11533                    needSep = true;
11534                    pw.println("  Launching content providers:");
11535                    printed = true;
11536                    printedAnything = true;
11537                }
11538                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11539                        pw.println(r);
11540            }
11541        }
11542
11543        if (mGrantedUriPermissions.size() > 0) {
11544            boolean printed = false;
11545            int dumpUid = -2;
11546            if (dumpPackage != null) {
11547                try {
11548                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11549                } catch (NameNotFoundException e) {
11550                    dumpUid = -1;
11551                }
11552            }
11553            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11554                int uid = mGrantedUriPermissions.keyAt(i);
11555                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11556                    continue;
11557                }
11558                ArrayMap<Uri, UriPermission> perms
11559                        = mGrantedUriPermissions.valueAt(i);
11560                if (!printed) {
11561                    if (needSep) pw.println();
11562                    needSep = true;
11563                    pw.println("  Granted Uri Permissions:");
11564                    printed = true;
11565                    printedAnything = true;
11566                }
11567                pw.print("  * UID "); pw.print(uid);
11568                        pw.println(" holds:");
11569                for (UriPermission perm : perms.values()) {
11570                    pw.print("    "); pw.println(perm);
11571                    if (dumpAll) {
11572                        perm.dump(pw, "      ");
11573                    }
11574                }
11575            }
11576        }
11577
11578        if (!printedAnything) {
11579            pw.println("  (nothing)");
11580        }
11581    }
11582
11583    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11584            int opti, boolean dumpAll, String dumpPackage) {
11585        boolean printed = false;
11586
11587        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11588
11589        if (mIntentSenderRecords.size() > 0) {
11590            Iterator<WeakReference<PendingIntentRecord>> it
11591                    = mIntentSenderRecords.values().iterator();
11592            while (it.hasNext()) {
11593                WeakReference<PendingIntentRecord> ref = it.next();
11594                PendingIntentRecord rec = ref != null ? ref.get(): null;
11595                if (dumpPackage != null && (rec == null
11596                        || !dumpPackage.equals(rec.key.packageName))) {
11597                    continue;
11598                }
11599                printed = true;
11600                if (rec != null) {
11601                    pw.print("  * "); pw.println(rec);
11602                    if (dumpAll) {
11603                        rec.dump(pw, "    ");
11604                    }
11605                } else {
11606                    pw.print("  * "); pw.println(ref);
11607                }
11608            }
11609        }
11610
11611        if (!printed) {
11612            pw.println("  (nothing)");
11613        }
11614    }
11615
11616    private static final int dumpProcessList(PrintWriter pw,
11617            ActivityManagerService service, List list,
11618            String prefix, String normalLabel, String persistentLabel,
11619            String dumpPackage) {
11620        int numPers = 0;
11621        final int N = list.size()-1;
11622        for (int i=N; i>=0; i--) {
11623            ProcessRecord r = (ProcessRecord)list.get(i);
11624            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11625                continue;
11626            }
11627            pw.println(String.format("%s%s #%2d: %s",
11628                    prefix, (r.persistent ? persistentLabel : normalLabel),
11629                    i, r.toString()));
11630            if (r.persistent) {
11631                numPers++;
11632            }
11633        }
11634        return numPers;
11635    }
11636
11637    private static final boolean dumpProcessOomList(PrintWriter pw,
11638            ActivityManagerService service, List<ProcessRecord> origList,
11639            String prefix, String normalLabel, String persistentLabel,
11640            boolean inclDetails, String dumpPackage) {
11641
11642        ArrayList<Pair<ProcessRecord, Integer>> list
11643                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11644        for (int i=0; i<origList.size(); i++) {
11645            ProcessRecord r = origList.get(i);
11646            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11647                continue;
11648            }
11649            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11650        }
11651
11652        if (list.size() <= 0) {
11653            return false;
11654        }
11655
11656        Comparator<Pair<ProcessRecord, Integer>> comparator
11657                = new Comparator<Pair<ProcessRecord, Integer>>() {
11658            @Override
11659            public int compare(Pair<ProcessRecord, Integer> object1,
11660                    Pair<ProcessRecord, Integer> object2) {
11661                if (object1.first.setAdj != object2.first.setAdj) {
11662                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11663                }
11664                if (object1.second.intValue() != object2.second.intValue()) {
11665                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11666                }
11667                return 0;
11668            }
11669        };
11670
11671        Collections.sort(list, comparator);
11672
11673        final long curRealtime = SystemClock.elapsedRealtime();
11674        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11675        final long curUptime = SystemClock.uptimeMillis();
11676        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11677
11678        for (int i=list.size()-1; i>=0; i--) {
11679            ProcessRecord r = list.get(i).first;
11680            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11681            char schedGroup;
11682            switch (r.setSchedGroup) {
11683                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11684                    schedGroup = 'B';
11685                    break;
11686                case Process.THREAD_GROUP_DEFAULT:
11687                    schedGroup = 'F';
11688                    break;
11689                default:
11690                    schedGroup = '?';
11691                    break;
11692            }
11693            char foreground;
11694            if (r.foregroundActivities) {
11695                foreground = 'A';
11696            } else if (r.foregroundServices) {
11697                foreground = 'S';
11698            } else {
11699                foreground = ' ';
11700            }
11701            String procState = ProcessList.makeProcStateString(r.curProcState);
11702            pw.print(prefix);
11703            pw.print(r.persistent ? persistentLabel : normalLabel);
11704            pw.print(" #");
11705            int num = (origList.size()-1)-list.get(i).second;
11706            if (num < 10) pw.print(' ');
11707            pw.print(num);
11708            pw.print(": ");
11709            pw.print(oomAdj);
11710            pw.print(' ');
11711            pw.print(schedGroup);
11712            pw.print('/');
11713            pw.print(foreground);
11714            pw.print('/');
11715            pw.print(procState);
11716            pw.print(" trm:");
11717            if (r.trimMemoryLevel < 10) pw.print(' ');
11718            pw.print(r.trimMemoryLevel);
11719            pw.print(' ');
11720            pw.print(r.toShortString());
11721            pw.print(" (");
11722            pw.print(r.adjType);
11723            pw.println(')');
11724            if (r.adjSource != null || r.adjTarget != null) {
11725                pw.print(prefix);
11726                pw.print("    ");
11727                if (r.adjTarget instanceof ComponentName) {
11728                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11729                } else if (r.adjTarget != null) {
11730                    pw.print(r.adjTarget.toString());
11731                } else {
11732                    pw.print("{null}");
11733                }
11734                pw.print("<=");
11735                if (r.adjSource instanceof ProcessRecord) {
11736                    pw.print("Proc{");
11737                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11738                    pw.println("}");
11739                } else if (r.adjSource != null) {
11740                    pw.println(r.adjSource.toString());
11741                } else {
11742                    pw.println("{null}");
11743                }
11744            }
11745            if (inclDetails) {
11746                pw.print(prefix);
11747                pw.print("    ");
11748                pw.print("oom: max="); pw.print(r.maxAdj);
11749                pw.print(" curRaw="); pw.print(r.curRawAdj);
11750                pw.print(" setRaw="); pw.print(r.setRawAdj);
11751                pw.print(" cur="); pw.print(r.curAdj);
11752                pw.print(" set="); pw.println(r.setAdj);
11753                pw.print(prefix);
11754                pw.print("    ");
11755                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11756                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11757                pw.print(" lastPss="); pw.print(r.lastPss);
11758                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11759                pw.print(prefix);
11760                pw.print("    ");
11761                pw.print("keeping="); pw.print(r.keeping);
11762                pw.print(" cached="); pw.print(r.cached);
11763                pw.print(" empty="); pw.print(r.empty);
11764                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11765
11766                if (!r.keeping) {
11767                    if (r.lastWakeTime != 0) {
11768                        long wtime;
11769                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11770                        synchronized (stats) {
11771                            wtime = stats.getProcessWakeTime(r.info.uid,
11772                                    r.pid, curRealtime);
11773                        }
11774                        long timeUsed = wtime - r.lastWakeTime;
11775                        pw.print(prefix);
11776                        pw.print("    ");
11777                        pw.print("keep awake over ");
11778                        TimeUtils.formatDuration(realtimeSince, pw);
11779                        pw.print(" used ");
11780                        TimeUtils.formatDuration(timeUsed, pw);
11781                        pw.print(" (");
11782                        pw.print((timeUsed*100)/realtimeSince);
11783                        pw.println("%)");
11784                    }
11785                    if (r.lastCpuTime != 0) {
11786                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11787                        pw.print(prefix);
11788                        pw.print("    ");
11789                        pw.print("run cpu over ");
11790                        TimeUtils.formatDuration(uptimeSince, pw);
11791                        pw.print(" used ");
11792                        TimeUtils.formatDuration(timeUsed, pw);
11793                        pw.print(" (");
11794                        pw.print((timeUsed*100)/uptimeSince);
11795                        pw.println("%)");
11796                    }
11797                }
11798            }
11799        }
11800        return true;
11801    }
11802
11803    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11804        ArrayList<ProcessRecord> procs;
11805        synchronized (this) {
11806            if (args != null && args.length > start
11807                    && args[start].charAt(0) != '-') {
11808                procs = new ArrayList<ProcessRecord>();
11809                int pid = -1;
11810                try {
11811                    pid = Integer.parseInt(args[start]);
11812                } catch (NumberFormatException e) {
11813                }
11814                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11815                    ProcessRecord proc = mLruProcesses.get(i);
11816                    if (proc.pid == pid) {
11817                        procs.add(proc);
11818                    } else if (proc.processName.equals(args[start])) {
11819                        procs.add(proc);
11820                    }
11821                }
11822                if (procs.size() <= 0) {
11823                    return null;
11824                }
11825            } else {
11826                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11827            }
11828        }
11829        return procs;
11830    }
11831
11832    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11833            PrintWriter pw, String[] args) {
11834        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11835        if (procs == null) {
11836            pw.println("No process found for: " + args[0]);
11837            return;
11838        }
11839
11840        long uptime = SystemClock.uptimeMillis();
11841        long realtime = SystemClock.elapsedRealtime();
11842        pw.println("Applications Graphics Acceleration Info:");
11843        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11844
11845        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11846            ProcessRecord r = procs.get(i);
11847            if (r.thread != null) {
11848                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11849                pw.flush();
11850                try {
11851                    TransferPipe tp = new TransferPipe();
11852                    try {
11853                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11854                        tp.go(fd);
11855                    } finally {
11856                        tp.kill();
11857                    }
11858                } catch (IOException e) {
11859                    pw.println("Failure while dumping the app: " + r);
11860                    pw.flush();
11861                } catch (RemoteException e) {
11862                    pw.println("Got a RemoteException while dumping the app " + r);
11863                    pw.flush();
11864                }
11865            }
11866        }
11867    }
11868
11869    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11870        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11871        if (procs == null) {
11872            pw.println("No process found for: " + args[0]);
11873            return;
11874        }
11875
11876        pw.println("Applications Database Info:");
11877
11878        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11879            ProcessRecord r = procs.get(i);
11880            if (r.thread != null) {
11881                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11882                pw.flush();
11883                try {
11884                    TransferPipe tp = new TransferPipe();
11885                    try {
11886                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11887                        tp.go(fd);
11888                    } finally {
11889                        tp.kill();
11890                    }
11891                } catch (IOException e) {
11892                    pw.println("Failure while dumping the app: " + r);
11893                    pw.flush();
11894                } catch (RemoteException e) {
11895                    pw.println("Got a RemoteException while dumping the app " + r);
11896                    pw.flush();
11897                }
11898            }
11899        }
11900    }
11901
11902    final static class MemItem {
11903        final boolean isProc;
11904        final String label;
11905        final String shortLabel;
11906        final long pss;
11907        final int id;
11908        final boolean hasActivities;
11909        ArrayList<MemItem> subitems;
11910
11911        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11912                boolean _hasActivities) {
11913            isProc = true;
11914            label = _label;
11915            shortLabel = _shortLabel;
11916            pss = _pss;
11917            id = _id;
11918            hasActivities = _hasActivities;
11919        }
11920
11921        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11922            isProc = false;
11923            label = _label;
11924            shortLabel = _shortLabel;
11925            pss = _pss;
11926            id = _id;
11927            hasActivities = false;
11928        }
11929    }
11930
11931    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11932            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11933        if (sort && !isCompact) {
11934            Collections.sort(items, new Comparator<MemItem>() {
11935                @Override
11936                public int compare(MemItem lhs, MemItem rhs) {
11937                    if (lhs.pss < rhs.pss) {
11938                        return 1;
11939                    } else if (lhs.pss > rhs.pss) {
11940                        return -1;
11941                    }
11942                    return 0;
11943                }
11944            });
11945        }
11946
11947        for (int i=0; i<items.size(); i++) {
11948            MemItem mi = items.get(i);
11949            if (!isCompact) {
11950                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11951            } else if (mi.isProc) {
11952                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11953                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11954                pw.println(mi.hasActivities ? ",a" : ",e");
11955            } else {
11956                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11957                pw.println(mi.pss);
11958            }
11959            if (mi.subitems != null) {
11960                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11961                        true, isCompact);
11962            }
11963        }
11964    }
11965
11966    // These are in KB.
11967    static final long[] DUMP_MEM_BUCKETS = new long[] {
11968        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11969        120*1024, 160*1024, 200*1024,
11970        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11971        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11972    };
11973
11974    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11975            boolean stackLike) {
11976        int start = label.lastIndexOf('.');
11977        if (start >= 0) start++;
11978        else start = 0;
11979        int end = label.length();
11980        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11981            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11982                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11983                out.append(bucket);
11984                out.append(stackLike ? "MB." : "MB ");
11985                out.append(label, start, end);
11986                return;
11987            }
11988        }
11989        out.append(memKB/1024);
11990        out.append(stackLike ? "MB." : "MB ");
11991        out.append(label, start, end);
11992    }
11993
11994    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11995            ProcessList.NATIVE_ADJ,
11996            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11997            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11998            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11999            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12000            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12001    };
12002    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12003            "Native",
12004            "System", "Persistent", "Foreground",
12005            "Visible", "Perceptible",
12006            "Heavy Weight", "Backup",
12007            "A Services", "Home",
12008            "Previous", "B Services", "Cached"
12009    };
12010    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12011            "native",
12012            "sys", "pers", "fore",
12013            "vis", "percept",
12014            "heavy", "backup",
12015            "servicea", "home",
12016            "prev", "serviceb", "cached"
12017    };
12018
12019    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12020            long realtime, boolean isCheckinRequest, boolean isCompact) {
12021        if (isCheckinRequest || isCompact) {
12022            // short checkin version
12023            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12024        } else {
12025            pw.println("Applications Memory Usage (kB):");
12026            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12027        }
12028    }
12029
12030    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12031            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12032        boolean dumpDetails = false;
12033        boolean dumpFullDetails = false;
12034        boolean dumpDalvik = false;
12035        boolean oomOnly = false;
12036        boolean isCompact = false;
12037        boolean localOnly = false;
12038
12039        int opti = 0;
12040        while (opti < args.length) {
12041            String opt = args[opti];
12042            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12043                break;
12044            }
12045            opti++;
12046            if ("-a".equals(opt)) {
12047                dumpDetails = true;
12048                dumpFullDetails = true;
12049                dumpDalvik = true;
12050            } else if ("-d".equals(opt)) {
12051                dumpDalvik = true;
12052            } else if ("-c".equals(opt)) {
12053                isCompact = true;
12054            } else if ("--oom".equals(opt)) {
12055                oomOnly = true;
12056            } else if ("--local".equals(opt)) {
12057                localOnly = true;
12058            } else if ("-h".equals(opt)) {
12059                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12060                pw.println("  -a: include all available information for each process.");
12061                pw.println("  -d: include dalvik details when dumping process details.");
12062                pw.println("  -c: dump in a compact machine-parseable representation.");
12063                pw.println("  --oom: only show processes organized by oom adj.");
12064                pw.println("  --local: only collect details locally, don't call process.");
12065                pw.println("If [process] is specified it can be the name or ");
12066                pw.println("pid of a specific process to dump.");
12067                return;
12068            } else {
12069                pw.println("Unknown argument: " + opt + "; use -h for help");
12070            }
12071        }
12072
12073        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12074        long uptime = SystemClock.uptimeMillis();
12075        long realtime = SystemClock.elapsedRealtime();
12076        final long[] tmpLong = new long[1];
12077
12078        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12079        if (procs == null) {
12080            // No Java processes.  Maybe they want to print a native process.
12081            if (args != null && args.length > opti
12082                    && args[opti].charAt(0) != '-') {
12083                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12084                        = new ArrayList<ProcessCpuTracker.Stats>();
12085                updateCpuStatsNow();
12086                int findPid = -1;
12087                try {
12088                    findPid = Integer.parseInt(args[opti]);
12089                } catch (NumberFormatException e) {
12090                }
12091                synchronized (mProcessCpuThread) {
12092                    final int N = mProcessCpuTracker.countStats();
12093                    for (int i=0; i<N; i++) {
12094                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12095                        if (st.pid == findPid || (st.baseName != null
12096                                && st.baseName.equals(args[opti]))) {
12097                            nativeProcs.add(st);
12098                        }
12099                    }
12100                }
12101                if (nativeProcs.size() > 0) {
12102                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12103                            isCompact);
12104                    Debug.MemoryInfo mi = null;
12105                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12106                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12107                        final int pid = r.pid;
12108                        if (!isCheckinRequest && dumpDetails) {
12109                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12110                        }
12111                        if (mi == null) {
12112                            mi = new Debug.MemoryInfo();
12113                        }
12114                        if (dumpDetails || (!brief && !oomOnly)) {
12115                            Debug.getMemoryInfo(pid, mi);
12116                        } else {
12117                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12118                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12119                        }
12120                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12121                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12122                        if (isCheckinRequest) {
12123                            pw.println();
12124                        }
12125                    }
12126                    return;
12127                }
12128            }
12129            pw.println("No process found for: " + args[opti]);
12130            return;
12131        }
12132
12133        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12134            dumpDetails = true;
12135        }
12136
12137        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12138
12139        String[] innerArgs = new String[args.length-opti];
12140        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12141
12142        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12143        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12144        long nativePss=0, dalvikPss=0, otherPss=0;
12145        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12146
12147        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12148        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12149                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12150
12151        long totalPss = 0;
12152        long cachedPss = 0;
12153
12154        Debug.MemoryInfo mi = null;
12155        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12156            final ProcessRecord r = procs.get(i);
12157            final IApplicationThread thread;
12158            final int pid;
12159            final int oomAdj;
12160            final boolean hasActivities;
12161            synchronized (this) {
12162                thread = r.thread;
12163                pid = r.pid;
12164                oomAdj = r.getSetAdjWithServices();
12165                hasActivities = r.activities.size() > 0;
12166            }
12167            if (thread != null) {
12168                if (!isCheckinRequest && dumpDetails) {
12169                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12170                }
12171                if (mi == null) {
12172                    mi = new Debug.MemoryInfo();
12173                }
12174                if (dumpDetails || (!brief && !oomOnly)) {
12175                    Debug.getMemoryInfo(pid, mi);
12176                } else {
12177                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12178                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12179                }
12180                if (dumpDetails) {
12181                    if (localOnly) {
12182                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12183                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12184                        if (isCheckinRequest) {
12185                            pw.println();
12186                        }
12187                    } else {
12188                        try {
12189                            pw.flush();
12190                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12191                                    dumpDalvik, innerArgs);
12192                        } catch (RemoteException e) {
12193                            if (!isCheckinRequest) {
12194                                pw.println("Got RemoteException!");
12195                                pw.flush();
12196                            }
12197                        }
12198                    }
12199                }
12200
12201                final long myTotalPss = mi.getTotalPss();
12202                final long myTotalUss = mi.getTotalUss();
12203
12204                synchronized (this) {
12205                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12206                        // Record this for posterity if the process has been stable.
12207                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12208                    }
12209                }
12210
12211                if (!isCheckinRequest && mi != null) {
12212                    totalPss += myTotalPss;
12213                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12214                            (hasActivities ? " / activities)" : ")"),
12215                            r.processName, myTotalPss, pid, hasActivities);
12216                    procMems.add(pssItem);
12217                    procMemsMap.put(pid, pssItem);
12218
12219                    nativePss += mi.nativePss;
12220                    dalvikPss += mi.dalvikPss;
12221                    otherPss += mi.otherPss;
12222                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12223                        long mem = mi.getOtherPss(j);
12224                        miscPss[j] += mem;
12225                        otherPss -= mem;
12226                    }
12227
12228                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12229                        cachedPss += myTotalPss;
12230                    }
12231
12232                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12233                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12234                                || oomIndex == (oomPss.length-1)) {
12235                            oomPss[oomIndex] += myTotalPss;
12236                            if (oomProcs[oomIndex] == null) {
12237                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12238                            }
12239                            oomProcs[oomIndex].add(pssItem);
12240                            break;
12241                        }
12242                    }
12243                }
12244            }
12245        }
12246
12247        if (!isCheckinRequest && procs.size() > 1) {
12248            // If we are showing aggregations, also look for native processes to
12249            // include so that our aggregations are more accurate.
12250            updateCpuStatsNow();
12251            synchronized (mProcessCpuThread) {
12252                final int N = mProcessCpuTracker.countStats();
12253                for (int i=0; i<N; i++) {
12254                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12255                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12256                        if (mi == null) {
12257                            mi = new Debug.MemoryInfo();
12258                        }
12259                        if (!brief && !oomOnly) {
12260                            Debug.getMemoryInfo(st.pid, mi);
12261                        } else {
12262                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12263                            mi.nativePrivateDirty = (int)tmpLong[0];
12264                        }
12265
12266                        final long myTotalPss = mi.getTotalPss();
12267                        totalPss += myTotalPss;
12268
12269                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12270                                st.name, myTotalPss, st.pid, false);
12271                        procMems.add(pssItem);
12272
12273                        nativePss += mi.nativePss;
12274                        dalvikPss += mi.dalvikPss;
12275                        otherPss += mi.otherPss;
12276                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12277                            long mem = mi.getOtherPss(j);
12278                            miscPss[j] += mem;
12279                            otherPss -= mem;
12280                        }
12281                        oomPss[0] += myTotalPss;
12282                        if (oomProcs[0] == null) {
12283                            oomProcs[0] = new ArrayList<MemItem>();
12284                        }
12285                        oomProcs[0].add(pssItem);
12286                    }
12287                }
12288            }
12289
12290            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12291
12292            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12293            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12294            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12295            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12296                String label = Debug.MemoryInfo.getOtherLabel(j);
12297                catMems.add(new MemItem(label, label, miscPss[j], j));
12298            }
12299
12300            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12301            for (int j=0; j<oomPss.length; j++) {
12302                if (oomPss[j] != 0) {
12303                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12304                            : DUMP_MEM_OOM_LABEL[j];
12305                    MemItem item = new MemItem(label, label, oomPss[j],
12306                            DUMP_MEM_OOM_ADJ[j]);
12307                    item.subitems = oomProcs[j];
12308                    oomMems.add(item);
12309                }
12310            }
12311
12312            if (!brief && !oomOnly && !isCompact) {
12313                pw.println();
12314                pw.println("Total PSS by process:");
12315                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12316                pw.println();
12317            }
12318            if (!isCompact) {
12319                pw.println("Total PSS by OOM adjustment:");
12320            }
12321            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12322            if (!brief && !oomOnly) {
12323                PrintWriter out = categoryPw != null ? categoryPw : pw;
12324                if (!isCompact) {
12325                    out.println();
12326                    out.println("Total PSS by category:");
12327                }
12328                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12329            }
12330            if (!isCompact) {
12331                pw.println();
12332            }
12333            MemInfoReader memInfo = new MemInfoReader();
12334            memInfo.readMemInfo();
12335            if (!brief) {
12336                if (!isCompact) {
12337                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12338                    pw.print(" kB (status ");
12339                    switch (mLastMemoryLevel) {
12340                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12341                            pw.println("normal)");
12342                            break;
12343                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12344                            pw.println("moderate)");
12345                            break;
12346                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12347                            pw.println("low)");
12348                            break;
12349                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12350                            pw.println("critical)");
12351                            break;
12352                        default:
12353                            pw.print(mLastMemoryLevel);
12354                            pw.println(")");
12355                            break;
12356                    }
12357                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12358                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12359                            pw.print(cachedPss); pw.print(" cached pss + ");
12360                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12361                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12362                } else {
12363                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12364                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12365                            + memInfo.getFreeSizeKb()); pw.print(",");
12366                    pw.println(totalPss - cachedPss);
12367                }
12368            }
12369            if (!isCompact) {
12370                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12371                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12372                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12373                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12374                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12375                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12376                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12377                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12378                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12379                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12380                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12381            }
12382            if (!brief) {
12383                if (memInfo.getZramTotalSizeKb() != 0) {
12384                    if (!isCompact) {
12385                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12386                                pw.print(" kB physical used for ");
12387                                pw.print(memInfo.getSwapTotalSizeKb()
12388                                        - memInfo.getSwapFreeSizeKb());
12389                                pw.print(" kB in swap (");
12390                                pw.print(memInfo.getSwapTotalSizeKb());
12391                                pw.println(" kB total swap)");
12392                    } else {
12393                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12394                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12395                                pw.println(memInfo.getSwapFreeSizeKb());
12396                    }
12397                }
12398                final int[] SINGLE_LONG_FORMAT = new int[] {
12399                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12400                };
12401                long[] longOut = new long[1];
12402                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12403                        SINGLE_LONG_FORMAT, null, longOut, null);
12404                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12405                longOut[0] = 0;
12406                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12407                        SINGLE_LONG_FORMAT, null, longOut, null);
12408                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12409                longOut[0] = 0;
12410                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12411                        SINGLE_LONG_FORMAT, null, longOut, null);
12412                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12413                longOut[0] = 0;
12414                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12415                        SINGLE_LONG_FORMAT, null, longOut, null);
12416                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12417                if (!isCompact) {
12418                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12419                        pw.print("      KSM: "); pw.print(sharing);
12420                                pw.print(" kB saved from shared ");
12421                                pw.print(shared); pw.println(" kB");
12422                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12423                                pw.print(voltile); pw.println(" kB volatile");
12424                    }
12425                    pw.print("   Tuning: ");
12426                    pw.print(ActivityManager.staticGetMemoryClass());
12427                    pw.print(" (large ");
12428                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12429                    pw.print("), oom ");
12430                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12431                    pw.print(" kB");
12432                    pw.print(", restore limit ");
12433                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12434                    pw.print(" kB");
12435                    if (ActivityManager.isLowRamDeviceStatic()) {
12436                        pw.print(" (low-ram)");
12437                    }
12438                    if (ActivityManager.isHighEndGfx()) {
12439                        pw.print(" (high-end-gfx)");
12440                    }
12441                    pw.println();
12442                } else {
12443                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12444                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12445                    pw.println(voltile);
12446                    pw.print("tuning,");
12447                    pw.print(ActivityManager.staticGetMemoryClass());
12448                    pw.print(',');
12449                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12450                    pw.print(',');
12451                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12452                    if (ActivityManager.isLowRamDeviceStatic()) {
12453                        pw.print(",low-ram");
12454                    }
12455                    if (ActivityManager.isHighEndGfx()) {
12456                        pw.print(",high-end-gfx");
12457                    }
12458                    pw.println();
12459                }
12460            }
12461        }
12462    }
12463
12464    /**
12465     * Searches array of arguments for the specified string
12466     * @param args array of argument strings
12467     * @param value value to search for
12468     * @return true if the value is contained in the array
12469     */
12470    private static boolean scanArgs(String[] args, String value) {
12471        if (args != null) {
12472            for (String arg : args) {
12473                if (value.equals(arg)) {
12474                    return true;
12475                }
12476            }
12477        }
12478        return false;
12479    }
12480
12481    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12482            ContentProviderRecord cpr, boolean always) {
12483        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12484
12485        if (!inLaunching || always) {
12486            synchronized (cpr) {
12487                cpr.launchingApp = null;
12488                cpr.notifyAll();
12489            }
12490            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12491            String names[] = cpr.info.authority.split(";");
12492            for (int j = 0; j < names.length; j++) {
12493                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12494            }
12495        }
12496
12497        for (int i=0; i<cpr.connections.size(); i++) {
12498            ContentProviderConnection conn = cpr.connections.get(i);
12499            if (conn.waiting) {
12500                // If this connection is waiting for the provider, then we don't
12501                // need to mess with its process unless we are always removing
12502                // or for some reason the provider is not currently launching.
12503                if (inLaunching && !always) {
12504                    continue;
12505                }
12506            }
12507            ProcessRecord capp = conn.client;
12508            conn.dead = true;
12509            if (conn.stableCount > 0) {
12510                if (!capp.persistent && capp.thread != null
12511                        && capp.pid != 0
12512                        && capp.pid != MY_PID) {
12513                    killUnneededProcessLocked(capp, "depends on provider "
12514                            + cpr.name.flattenToShortString()
12515                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12516                }
12517            } else if (capp.thread != null && conn.provider.provider != null) {
12518                try {
12519                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12520                } catch (RemoteException e) {
12521                }
12522                // In the protocol here, we don't expect the client to correctly
12523                // clean up this connection, we'll just remove it.
12524                cpr.connections.remove(i);
12525                conn.client.conProviders.remove(conn);
12526            }
12527        }
12528
12529        if (inLaunching && always) {
12530            mLaunchingProviders.remove(cpr);
12531        }
12532        return inLaunching;
12533    }
12534
12535    /**
12536     * Main code for cleaning up a process when it has gone away.  This is
12537     * called both as a result of the process dying, or directly when stopping
12538     * a process when running in single process mode.
12539     */
12540    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12541            boolean restarting, boolean allowRestart, int index) {
12542        if (index >= 0) {
12543            removeLruProcessLocked(app);
12544            ProcessList.remove(app.pid);
12545        }
12546
12547        mProcessesToGc.remove(app);
12548        mPendingPssProcesses.remove(app);
12549
12550        // Dismiss any open dialogs.
12551        if (app.crashDialog != null && !app.forceCrashReport) {
12552            app.crashDialog.dismiss();
12553            app.crashDialog = null;
12554        }
12555        if (app.anrDialog != null) {
12556            app.anrDialog.dismiss();
12557            app.anrDialog = null;
12558        }
12559        if (app.waitDialog != null) {
12560            app.waitDialog.dismiss();
12561            app.waitDialog = null;
12562        }
12563
12564        app.crashing = false;
12565        app.notResponding = false;
12566
12567        app.resetPackageList(mProcessStats);
12568        app.unlinkDeathRecipient();
12569        app.makeInactive(mProcessStats);
12570        app.forcingToForeground = null;
12571        updateProcessForegroundLocked(app, false, false);
12572        app.foregroundActivities = false;
12573        app.hasShownUi = false;
12574        app.hasAboveClient = false;
12575
12576        mServices.killServicesLocked(app, allowRestart);
12577
12578        boolean restart = false;
12579
12580        // Remove published content providers.
12581        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12582            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12583            final boolean always = app.bad || !allowRestart;
12584            if (removeDyingProviderLocked(app, cpr, always) || always) {
12585                // We left the provider in the launching list, need to
12586                // restart it.
12587                restart = true;
12588            }
12589
12590            cpr.provider = null;
12591            cpr.proc = null;
12592        }
12593        app.pubProviders.clear();
12594
12595        // Take care of any launching providers waiting for this process.
12596        if (checkAppInLaunchingProvidersLocked(app, false)) {
12597            restart = true;
12598        }
12599
12600        // Unregister from connected content providers.
12601        if (!app.conProviders.isEmpty()) {
12602            for (int i=0; i<app.conProviders.size(); i++) {
12603                ContentProviderConnection conn = app.conProviders.get(i);
12604                conn.provider.connections.remove(conn);
12605            }
12606            app.conProviders.clear();
12607        }
12608
12609        // At this point there may be remaining entries in mLaunchingProviders
12610        // where we were the only one waiting, so they are no longer of use.
12611        // Look for these and clean up if found.
12612        // XXX Commented out for now.  Trying to figure out a way to reproduce
12613        // the actual situation to identify what is actually going on.
12614        if (false) {
12615            for (int i=0; i<mLaunchingProviders.size(); i++) {
12616                ContentProviderRecord cpr = (ContentProviderRecord)
12617                        mLaunchingProviders.get(i);
12618                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12619                    synchronized (cpr) {
12620                        cpr.launchingApp = null;
12621                        cpr.notifyAll();
12622                    }
12623                }
12624            }
12625        }
12626
12627        skipCurrentReceiverLocked(app);
12628
12629        // Unregister any receivers.
12630        for (int i=app.receivers.size()-1; i>=0; i--) {
12631            removeReceiverLocked(app.receivers.valueAt(i));
12632        }
12633        app.receivers.clear();
12634
12635        // If the app is undergoing backup, tell the backup manager about it
12636        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12637            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12638                    + mBackupTarget.appInfo + " died during backup");
12639            try {
12640                IBackupManager bm = IBackupManager.Stub.asInterface(
12641                        ServiceManager.getService(Context.BACKUP_SERVICE));
12642                bm.agentDisconnected(app.info.packageName);
12643            } catch (RemoteException e) {
12644                // can't happen; backup manager is local
12645            }
12646        }
12647
12648        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12649            ProcessChangeItem item = mPendingProcessChanges.get(i);
12650            if (item.pid == app.pid) {
12651                mPendingProcessChanges.remove(i);
12652                mAvailProcessChanges.add(item);
12653            }
12654        }
12655        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12656
12657        // If the caller is restarting this app, then leave it in its
12658        // current lists and let the caller take care of it.
12659        if (restarting) {
12660            return;
12661        }
12662
12663        if (!app.persistent || app.isolated) {
12664            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12665                    "Removing non-persistent process during cleanup: " + app);
12666            mProcessNames.remove(app.processName, app.uid);
12667            mIsolatedProcesses.remove(app.uid);
12668            if (mHeavyWeightProcess == app) {
12669                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12670                        mHeavyWeightProcess.userId, 0));
12671                mHeavyWeightProcess = null;
12672            }
12673        } else if (!app.removed) {
12674            // This app is persistent, so we need to keep its record around.
12675            // If it is not already on the pending app list, add it there
12676            // and start a new process for it.
12677            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12678                mPersistentStartingProcesses.add(app);
12679                restart = true;
12680            }
12681        }
12682        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12683                "Clean-up removing on hold: " + app);
12684        mProcessesOnHold.remove(app);
12685
12686        if (app == mHomeProcess) {
12687            mHomeProcess = null;
12688        }
12689        if (app == mPreviousProcess) {
12690            mPreviousProcess = null;
12691        }
12692
12693        if (restart && !app.isolated) {
12694            // We have components that still need to be running in the
12695            // process, so re-launch it.
12696            mProcessNames.put(app.processName, app.uid, app);
12697            startProcessLocked(app, "restart", app.processName);
12698        } else if (app.pid > 0 && app.pid != MY_PID) {
12699            // Goodbye!
12700            boolean removed;
12701            synchronized (mPidsSelfLocked) {
12702                mPidsSelfLocked.remove(app.pid);
12703                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12704            }
12705            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12706                    app.processName, app.info.uid);
12707            if (app.isolated) {
12708                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12709            }
12710            app.setPid(0);
12711        }
12712    }
12713
12714    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12715        // Look through the content providers we are waiting to have launched,
12716        // and if any run in this process then either schedule a restart of
12717        // the process or kill the client waiting for it if this process has
12718        // gone bad.
12719        int NL = mLaunchingProviders.size();
12720        boolean restart = false;
12721        for (int i=0; i<NL; i++) {
12722            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12723            if (cpr.launchingApp == app) {
12724                if (!alwaysBad && !app.bad) {
12725                    restart = true;
12726                } else {
12727                    removeDyingProviderLocked(app, cpr, true);
12728                    // cpr should have been removed from mLaunchingProviders
12729                    NL = mLaunchingProviders.size();
12730                    i--;
12731                }
12732            }
12733        }
12734        return restart;
12735    }
12736
12737    // =========================================================
12738    // SERVICES
12739    // =========================================================
12740
12741    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12742            int flags) {
12743        enforceNotIsolatedCaller("getServices");
12744        synchronized (this) {
12745            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12746        }
12747    }
12748
12749    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12750        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12751        synchronized (this) {
12752            return mServices.getRunningServiceControlPanelLocked(name);
12753        }
12754    }
12755
12756    public ComponentName startService(IApplicationThread caller, Intent service,
12757            String resolvedType, int userId) {
12758        enforceNotIsolatedCaller("startService");
12759        // Refuse possible leaked file descriptors
12760        if (service != null && service.hasFileDescriptors() == true) {
12761            throw new IllegalArgumentException("File descriptors passed in Intent");
12762        }
12763
12764        if (DEBUG_SERVICE)
12765            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12766        synchronized(this) {
12767            final int callingPid = Binder.getCallingPid();
12768            final int callingUid = Binder.getCallingUid();
12769            final long origId = Binder.clearCallingIdentity();
12770            ComponentName res = mServices.startServiceLocked(caller, service,
12771                    resolvedType, callingPid, callingUid, userId);
12772            Binder.restoreCallingIdentity(origId);
12773            return res;
12774        }
12775    }
12776
12777    ComponentName startServiceInPackage(int uid,
12778            Intent service, String resolvedType, int userId) {
12779        synchronized(this) {
12780            if (DEBUG_SERVICE)
12781                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12782            final long origId = Binder.clearCallingIdentity();
12783            ComponentName res = mServices.startServiceLocked(null, service,
12784                    resolvedType, -1, uid, userId);
12785            Binder.restoreCallingIdentity(origId);
12786            return res;
12787        }
12788    }
12789
12790    public int stopService(IApplicationThread caller, Intent service,
12791            String resolvedType, int userId) {
12792        enforceNotIsolatedCaller("stopService");
12793        // Refuse possible leaked file descriptors
12794        if (service != null && service.hasFileDescriptors() == true) {
12795            throw new IllegalArgumentException("File descriptors passed in Intent");
12796        }
12797
12798        synchronized(this) {
12799            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12800        }
12801    }
12802
12803    public IBinder peekService(Intent service, String resolvedType) {
12804        enforceNotIsolatedCaller("peekService");
12805        // Refuse possible leaked file descriptors
12806        if (service != null && service.hasFileDescriptors() == true) {
12807            throw new IllegalArgumentException("File descriptors passed in Intent");
12808        }
12809        synchronized(this) {
12810            return mServices.peekServiceLocked(service, resolvedType);
12811        }
12812    }
12813
12814    public boolean stopServiceToken(ComponentName className, IBinder token,
12815            int startId) {
12816        synchronized(this) {
12817            return mServices.stopServiceTokenLocked(className, token, startId);
12818        }
12819    }
12820
12821    public void setServiceForeground(ComponentName className, IBinder token,
12822            int id, Notification notification, boolean removeNotification) {
12823        synchronized(this) {
12824            mServices.setServiceForegroundLocked(className, token, id, notification,
12825                    removeNotification);
12826        }
12827    }
12828
12829    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12830            boolean requireFull, String name, String callerPackage) {
12831        final int callingUserId = UserHandle.getUserId(callingUid);
12832        if (callingUserId != userId) {
12833            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12834                if ((requireFull || checkComponentPermission(
12835                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12836                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12837                        && checkComponentPermission(
12838                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12839                                callingPid, callingUid, -1, true)
12840                                != PackageManager.PERMISSION_GRANTED) {
12841                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12842                        // In this case, they would like to just execute as their
12843                        // owner user instead of failing.
12844                        userId = callingUserId;
12845                    } else {
12846                        StringBuilder builder = new StringBuilder(128);
12847                        builder.append("Permission Denial: ");
12848                        builder.append(name);
12849                        if (callerPackage != null) {
12850                            builder.append(" from ");
12851                            builder.append(callerPackage);
12852                        }
12853                        builder.append(" asks to run as user ");
12854                        builder.append(userId);
12855                        builder.append(" but is calling from user ");
12856                        builder.append(UserHandle.getUserId(callingUid));
12857                        builder.append("; this requires ");
12858                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12859                        if (!requireFull) {
12860                            builder.append(" or ");
12861                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12862                        }
12863                        String msg = builder.toString();
12864                        Slog.w(TAG, msg);
12865                        throw new SecurityException(msg);
12866                    }
12867                }
12868            }
12869            if (userId == UserHandle.USER_CURRENT
12870                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12871                // Note that we may be accessing this outside of a lock...
12872                // shouldn't be a big deal, if this is being called outside
12873                // of a locked context there is intrinsically a race with
12874                // the value the caller will receive and someone else changing it.
12875                userId = mCurrentUserId;
12876            }
12877            if (!allowAll && userId < 0) {
12878                throw new IllegalArgumentException(
12879                        "Call does not support special user #" + userId);
12880            }
12881        }
12882        return userId;
12883    }
12884
12885    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12886            String className, int flags) {
12887        boolean result = false;
12888        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12889            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12890                if (ActivityManager.checkUidPermission(
12891                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12892                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12893                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12894                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12895                            + " requests FLAG_SINGLE_USER, but app does not hold "
12896                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12897                    Slog.w(TAG, msg);
12898                    throw new SecurityException(msg);
12899                }
12900                result = true;
12901            }
12902        } else if (componentProcessName == aInfo.packageName) {
12903            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12904        } else if ("system".equals(componentProcessName)) {
12905            result = true;
12906        }
12907        if (DEBUG_MU) {
12908            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12909                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12910        }
12911        return result;
12912    }
12913
12914    public int bindService(IApplicationThread caller, IBinder token,
12915            Intent service, String resolvedType,
12916            IServiceConnection connection, int flags, int userId) {
12917        enforceNotIsolatedCaller("bindService");
12918        // Refuse possible leaked file descriptors
12919        if (service != null && service.hasFileDescriptors() == true) {
12920            throw new IllegalArgumentException("File descriptors passed in Intent");
12921        }
12922
12923        synchronized(this) {
12924            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12925                    connection, flags, userId);
12926        }
12927    }
12928
12929    public boolean unbindService(IServiceConnection connection) {
12930        synchronized (this) {
12931            return mServices.unbindServiceLocked(connection);
12932        }
12933    }
12934
12935    public void publishService(IBinder token, Intent intent, IBinder service) {
12936        // Refuse possible leaked file descriptors
12937        if (intent != null && intent.hasFileDescriptors() == true) {
12938            throw new IllegalArgumentException("File descriptors passed in Intent");
12939        }
12940
12941        synchronized(this) {
12942            if (!(token instanceof ServiceRecord)) {
12943                throw new IllegalArgumentException("Invalid service token");
12944            }
12945            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12946        }
12947    }
12948
12949    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12950        // Refuse possible leaked file descriptors
12951        if (intent != null && intent.hasFileDescriptors() == true) {
12952            throw new IllegalArgumentException("File descriptors passed in Intent");
12953        }
12954
12955        synchronized(this) {
12956            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12957        }
12958    }
12959
12960    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12961        synchronized(this) {
12962            if (!(token instanceof ServiceRecord)) {
12963                throw new IllegalArgumentException("Invalid service token");
12964            }
12965            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12966        }
12967    }
12968
12969    // =========================================================
12970    // BACKUP AND RESTORE
12971    // =========================================================
12972
12973    // Cause the target app to be launched if necessary and its backup agent
12974    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12975    // activity manager to announce its creation.
12976    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12977        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12978        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12979
12980        synchronized(this) {
12981            // !!! TODO: currently no check here that we're already bound
12982            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12983            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12984            synchronized (stats) {
12985                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12986            }
12987
12988            // Backup agent is now in use, its package can't be stopped.
12989            try {
12990                AppGlobals.getPackageManager().setPackageStoppedState(
12991                        app.packageName, false, UserHandle.getUserId(app.uid));
12992            } catch (RemoteException e) {
12993            } catch (IllegalArgumentException e) {
12994                Slog.w(TAG, "Failed trying to unstop package "
12995                        + app.packageName + ": " + e);
12996            }
12997
12998            BackupRecord r = new BackupRecord(ss, app, backupMode);
12999            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13000                    ? new ComponentName(app.packageName, app.backupAgentName)
13001                    : new ComponentName("android", "FullBackupAgent");
13002            // startProcessLocked() returns existing proc's record if it's already running
13003            ProcessRecord proc = startProcessLocked(app.processName, app,
13004                    false, 0, "backup", hostingName, false, false, false);
13005            if (proc == null) {
13006                Slog.e(TAG, "Unable to start backup agent process " + r);
13007                return false;
13008            }
13009
13010            r.app = proc;
13011            mBackupTarget = r;
13012            mBackupAppName = app.packageName;
13013
13014            // Try not to kill the process during backup
13015            updateOomAdjLocked(proc);
13016
13017            // If the process is already attached, schedule the creation of the backup agent now.
13018            // If it is not yet live, this will be done when it attaches to the framework.
13019            if (proc.thread != null) {
13020                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13021                try {
13022                    proc.thread.scheduleCreateBackupAgent(app,
13023                            compatibilityInfoForPackageLocked(app), backupMode);
13024                } catch (RemoteException e) {
13025                    // Will time out on the backup manager side
13026                }
13027            } else {
13028                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13029            }
13030            // Invariants: at this point, the target app process exists and the application
13031            // is either already running or in the process of coming up.  mBackupTarget and
13032            // mBackupAppName describe the app, so that when it binds back to the AM we
13033            // know that it's scheduled for a backup-agent operation.
13034        }
13035
13036        return true;
13037    }
13038
13039    @Override
13040    public void clearPendingBackup() {
13041        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13042        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13043
13044        synchronized (this) {
13045            mBackupTarget = null;
13046            mBackupAppName = null;
13047        }
13048    }
13049
13050    // A backup agent has just come up
13051    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13052        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13053                + " = " + agent);
13054
13055        synchronized(this) {
13056            if (!agentPackageName.equals(mBackupAppName)) {
13057                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13058                return;
13059            }
13060        }
13061
13062        long oldIdent = Binder.clearCallingIdentity();
13063        try {
13064            IBackupManager bm = IBackupManager.Stub.asInterface(
13065                    ServiceManager.getService(Context.BACKUP_SERVICE));
13066            bm.agentConnected(agentPackageName, agent);
13067        } catch (RemoteException e) {
13068            // can't happen; the backup manager service is local
13069        } catch (Exception e) {
13070            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13071            e.printStackTrace();
13072        } finally {
13073            Binder.restoreCallingIdentity(oldIdent);
13074        }
13075    }
13076
13077    // done with this agent
13078    public void unbindBackupAgent(ApplicationInfo appInfo) {
13079        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13080        if (appInfo == null) {
13081            Slog.w(TAG, "unbind backup agent for null app");
13082            return;
13083        }
13084
13085        synchronized(this) {
13086            try {
13087                if (mBackupAppName == null) {
13088                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13089                    return;
13090                }
13091
13092                if (!mBackupAppName.equals(appInfo.packageName)) {
13093                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13094                    return;
13095                }
13096
13097                // Not backing this app up any more; reset its OOM adjustment
13098                final ProcessRecord proc = mBackupTarget.app;
13099                updateOomAdjLocked(proc);
13100
13101                // If the app crashed during backup, 'thread' will be null here
13102                if (proc.thread != null) {
13103                    try {
13104                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13105                                compatibilityInfoForPackageLocked(appInfo));
13106                    } catch (Exception e) {
13107                        Slog.e(TAG, "Exception when unbinding backup agent:");
13108                        e.printStackTrace();
13109                    }
13110                }
13111            } finally {
13112                mBackupTarget = null;
13113                mBackupAppName = null;
13114            }
13115        }
13116    }
13117    // =========================================================
13118    // BROADCASTS
13119    // =========================================================
13120
13121    private final List getStickiesLocked(String action, IntentFilter filter,
13122            List cur, int userId) {
13123        final ContentResolver resolver = mContext.getContentResolver();
13124        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13125        if (stickies == null) {
13126            return cur;
13127        }
13128        final ArrayList<Intent> list = stickies.get(action);
13129        if (list == null) {
13130            return cur;
13131        }
13132        int N = list.size();
13133        for (int i=0; i<N; i++) {
13134            Intent intent = list.get(i);
13135            if (filter.match(resolver, intent, true, TAG) >= 0) {
13136                if (cur == null) {
13137                    cur = new ArrayList<Intent>();
13138                }
13139                cur.add(intent);
13140            }
13141        }
13142        return cur;
13143    }
13144
13145    boolean isPendingBroadcastProcessLocked(int pid) {
13146        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13147                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13148    }
13149
13150    void skipPendingBroadcastLocked(int pid) {
13151            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13152            for (BroadcastQueue queue : mBroadcastQueues) {
13153                queue.skipPendingBroadcastLocked(pid);
13154            }
13155    }
13156
13157    // The app just attached; send any pending broadcasts that it should receive
13158    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13159        boolean didSomething = false;
13160        for (BroadcastQueue queue : mBroadcastQueues) {
13161            didSomething |= queue.sendPendingBroadcastsLocked(app);
13162        }
13163        return didSomething;
13164    }
13165
13166    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13167            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13168        enforceNotIsolatedCaller("registerReceiver");
13169        int callingUid;
13170        int callingPid;
13171        synchronized(this) {
13172            ProcessRecord callerApp = null;
13173            if (caller != null) {
13174                callerApp = getRecordForAppLocked(caller);
13175                if (callerApp == null) {
13176                    throw new SecurityException(
13177                            "Unable to find app for caller " + caller
13178                            + " (pid=" + Binder.getCallingPid()
13179                            + ") when registering receiver " + receiver);
13180                }
13181                if (callerApp.info.uid != Process.SYSTEM_UID &&
13182                        !callerApp.pkgList.containsKey(callerPackage) &&
13183                        !"android".equals(callerPackage)) {
13184                    throw new SecurityException("Given caller package " + callerPackage
13185                            + " is not running in process " + callerApp);
13186                }
13187                callingUid = callerApp.info.uid;
13188                callingPid = callerApp.pid;
13189            } else {
13190                callerPackage = null;
13191                callingUid = Binder.getCallingUid();
13192                callingPid = Binder.getCallingPid();
13193            }
13194
13195            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13196                    true, true, "registerReceiver", callerPackage);
13197
13198            List allSticky = null;
13199
13200            // Look for any matching sticky broadcasts...
13201            Iterator actions = filter.actionsIterator();
13202            if (actions != null) {
13203                while (actions.hasNext()) {
13204                    String action = (String)actions.next();
13205                    allSticky = getStickiesLocked(action, filter, allSticky,
13206                            UserHandle.USER_ALL);
13207                    allSticky = getStickiesLocked(action, filter, allSticky,
13208                            UserHandle.getUserId(callingUid));
13209                }
13210            } else {
13211                allSticky = getStickiesLocked(null, filter, allSticky,
13212                        UserHandle.USER_ALL);
13213                allSticky = getStickiesLocked(null, filter, allSticky,
13214                        UserHandle.getUserId(callingUid));
13215            }
13216
13217            // The first sticky in the list is returned directly back to
13218            // the client.
13219            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13220
13221            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13222                    + ": " + sticky);
13223
13224            if (receiver == null) {
13225                return sticky;
13226            }
13227
13228            ReceiverList rl
13229                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13230            if (rl == null) {
13231                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13232                        userId, receiver);
13233                if (rl.app != null) {
13234                    rl.app.receivers.add(rl);
13235                } else {
13236                    try {
13237                        receiver.asBinder().linkToDeath(rl, 0);
13238                    } catch (RemoteException e) {
13239                        return sticky;
13240                    }
13241                    rl.linkedToDeath = true;
13242                }
13243                mRegisteredReceivers.put(receiver.asBinder(), rl);
13244            } else if (rl.uid != callingUid) {
13245                throw new IllegalArgumentException(
13246                        "Receiver requested to register for uid " + callingUid
13247                        + " was previously registered for uid " + rl.uid);
13248            } else if (rl.pid != callingPid) {
13249                throw new IllegalArgumentException(
13250                        "Receiver requested to register for pid " + callingPid
13251                        + " was previously registered for pid " + rl.pid);
13252            } else if (rl.userId != userId) {
13253                throw new IllegalArgumentException(
13254                        "Receiver requested to register for user " + userId
13255                        + " was previously registered for user " + rl.userId);
13256            }
13257            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13258                    permission, callingUid, userId);
13259            rl.add(bf);
13260            if (!bf.debugCheck()) {
13261                Slog.w(TAG, "==> For Dynamic broadast");
13262            }
13263            mReceiverResolver.addFilter(bf);
13264
13265            // Enqueue broadcasts for all existing stickies that match
13266            // this filter.
13267            if (allSticky != null) {
13268                ArrayList receivers = new ArrayList();
13269                receivers.add(bf);
13270
13271                int N = allSticky.size();
13272                for (int i=0; i<N; i++) {
13273                    Intent intent = (Intent)allSticky.get(i);
13274                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13275                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13276                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13277                            null, null, false, true, true, -1);
13278                    queue.enqueueParallelBroadcastLocked(r);
13279                    queue.scheduleBroadcastsLocked();
13280                }
13281            }
13282
13283            return sticky;
13284        }
13285    }
13286
13287    public void unregisterReceiver(IIntentReceiver receiver) {
13288        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13289
13290        final long origId = Binder.clearCallingIdentity();
13291        try {
13292            boolean doTrim = false;
13293
13294            synchronized(this) {
13295                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13296                if (rl != null) {
13297                    if (rl.curBroadcast != null) {
13298                        BroadcastRecord r = rl.curBroadcast;
13299                        final boolean doNext = finishReceiverLocked(
13300                                receiver.asBinder(), r.resultCode, r.resultData,
13301                                r.resultExtras, r.resultAbort);
13302                        if (doNext) {
13303                            doTrim = true;
13304                            r.queue.processNextBroadcast(false);
13305                        }
13306                    }
13307
13308                    if (rl.app != null) {
13309                        rl.app.receivers.remove(rl);
13310                    }
13311                    removeReceiverLocked(rl);
13312                    if (rl.linkedToDeath) {
13313                        rl.linkedToDeath = false;
13314                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13315                    }
13316                }
13317            }
13318
13319            // If we actually concluded any broadcasts, we might now be able
13320            // to trim the recipients' apps from our working set
13321            if (doTrim) {
13322                trimApplications();
13323                return;
13324            }
13325
13326        } finally {
13327            Binder.restoreCallingIdentity(origId);
13328        }
13329    }
13330
13331    void removeReceiverLocked(ReceiverList rl) {
13332        mRegisteredReceivers.remove(rl.receiver.asBinder());
13333        int N = rl.size();
13334        for (int i=0; i<N; i++) {
13335            mReceiverResolver.removeFilter(rl.get(i));
13336        }
13337    }
13338
13339    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13340        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13341            ProcessRecord r = mLruProcesses.get(i);
13342            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13343                try {
13344                    r.thread.dispatchPackageBroadcast(cmd, packages);
13345                } catch (RemoteException ex) {
13346                }
13347            }
13348        }
13349    }
13350
13351    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13352            int[] users) {
13353        List<ResolveInfo> receivers = null;
13354        try {
13355            HashSet<ComponentName> singleUserReceivers = null;
13356            boolean scannedFirstReceivers = false;
13357            for (int user : users) {
13358                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13359                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13360                if (user != 0 && newReceivers != null) {
13361                    // If this is not the primary user, we need to check for
13362                    // any receivers that should be filtered out.
13363                    for (int i=0; i<newReceivers.size(); i++) {
13364                        ResolveInfo ri = newReceivers.get(i);
13365                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13366                            newReceivers.remove(i);
13367                            i--;
13368                        }
13369                    }
13370                }
13371                if (newReceivers != null && newReceivers.size() == 0) {
13372                    newReceivers = null;
13373                }
13374                if (receivers == null) {
13375                    receivers = newReceivers;
13376                } else if (newReceivers != null) {
13377                    // We need to concatenate the additional receivers
13378                    // found with what we have do far.  This would be easy,
13379                    // but we also need to de-dup any receivers that are
13380                    // singleUser.
13381                    if (!scannedFirstReceivers) {
13382                        // Collect any single user receivers we had already retrieved.
13383                        scannedFirstReceivers = true;
13384                        for (int i=0; i<receivers.size(); i++) {
13385                            ResolveInfo ri = receivers.get(i);
13386                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13387                                ComponentName cn = new ComponentName(
13388                                        ri.activityInfo.packageName, ri.activityInfo.name);
13389                                if (singleUserReceivers == null) {
13390                                    singleUserReceivers = new HashSet<ComponentName>();
13391                                }
13392                                singleUserReceivers.add(cn);
13393                            }
13394                        }
13395                    }
13396                    // Add the new results to the existing results, tracking
13397                    // and de-dupping single user receivers.
13398                    for (int i=0; i<newReceivers.size(); i++) {
13399                        ResolveInfo ri = newReceivers.get(i);
13400                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13401                            ComponentName cn = new ComponentName(
13402                                    ri.activityInfo.packageName, ri.activityInfo.name);
13403                            if (singleUserReceivers == null) {
13404                                singleUserReceivers = new HashSet<ComponentName>();
13405                            }
13406                            if (!singleUserReceivers.contains(cn)) {
13407                                singleUserReceivers.add(cn);
13408                                receivers.add(ri);
13409                            }
13410                        } else {
13411                            receivers.add(ri);
13412                        }
13413                    }
13414                }
13415            }
13416        } catch (RemoteException ex) {
13417            // pm is in same process, this will never happen.
13418        }
13419        return receivers;
13420    }
13421
13422    private final int broadcastIntentLocked(ProcessRecord callerApp,
13423            String callerPackage, Intent intent, String resolvedType,
13424            IIntentReceiver resultTo, int resultCode, String resultData,
13425            Bundle map, String requiredPermission, int appOp,
13426            boolean ordered, boolean sticky, int callingPid, int callingUid,
13427            int userId) {
13428        intent = new Intent(intent);
13429
13430        // By default broadcasts do not go to stopped apps.
13431        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13432
13433        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13434            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13435            + " ordered=" + ordered + " userid=" + userId);
13436        if ((resultTo != null) && !ordered) {
13437            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13438        }
13439
13440        userId = handleIncomingUser(callingPid, callingUid, userId,
13441                true, false, "broadcast", callerPackage);
13442
13443        // Make sure that the user who is receiving this broadcast is started.
13444        // If not, we will just skip it.
13445        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13446            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13447                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13448                Slog.w(TAG, "Skipping broadcast of " + intent
13449                        + ": user " + userId + " is stopped");
13450                return ActivityManager.BROADCAST_SUCCESS;
13451            }
13452        }
13453
13454        /*
13455         * Prevent non-system code (defined here to be non-persistent
13456         * processes) from sending protected broadcasts.
13457         */
13458        int callingAppId = UserHandle.getAppId(callingUid);
13459        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13460            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13461            callingUid == 0) {
13462            // Always okay.
13463        } else if (callerApp == null || !callerApp.persistent) {
13464            try {
13465                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13466                        intent.getAction())) {
13467                    String msg = "Permission Denial: not allowed to send broadcast "
13468                            + intent.getAction() + " from pid="
13469                            + callingPid + ", uid=" + callingUid;
13470                    Slog.w(TAG, msg);
13471                    throw new SecurityException(msg);
13472                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13473                    // Special case for compatibility: we don't want apps to send this,
13474                    // but historically it has not been protected and apps may be using it
13475                    // to poke their own app widget.  So, instead of making it protected,
13476                    // just limit it to the caller.
13477                    if (callerApp == null) {
13478                        String msg = "Permission Denial: not allowed to send broadcast "
13479                                + intent.getAction() + " from unknown caller.";
13480                        Slog.w(TAG, msg);
13481                        throw new SecurityException(msg);
13482                    } else if (intent.getComponent() != null) {
13483                        // They are good enough to send to an explicit component...  verify
13484                        // it is being sent to the calling app.
13485                        if (!intent.getComponent().getPackageName().equals(
13486                                callerApp.info.packageName)) {
13487                            String msg = "Permission Denial: not allowed to send broadcast "
13488                                    + intent.getAction() + " to "
13489                                    + intent.getComponent().getPackageName() + " from "
13490                                    + callerApp.info.packageName;
13491                            Slog.w(TAG, msg);
13492                            throw new SecurityException(msg);
13493                        }
13494                    } else {
13495                        // Limit broadcast to their own package.
13496                        intent.setPackage(callerApp.info.packageName);
13497                    }
13498                }
13499            } catch (RemoteException e) {
13500                Slog.w(TAG, "Remote exception", e);
13501                return ActivityManager.BROADCAST_SUCCESS;
13502            }
13503        }
13504
13505        // Handle special intents: if this broadcast is from the package
13506        // manager about a package being removed, we need to remove all of
13507        // its activities from the history stack.
13508        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13509                intent.getAction());
13510        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13511                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13512                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13513                || uidRemoved) {
13514            if (checkComponentPermission(
13515                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13516                    callingPid, callingUid, -1, true)
13517                    == PackageManager.PERMISSION_GRANTED) {
13518                if (uidRemoved) {
13519                    final Bundle intentExtras = intent.getExtras();
13520                    final int uid = intentExtras != null
13521                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13522                    if (uid >= 0) {
13523                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13524                        synchronized (bs) {
13525                            bs.removeUidStatsLocked(uid);
13526                        }
13527                        mAppOpsService.uidRemoved(uid);
13528                    }
13529                } else {
13530                    // If resources are unavailable just force stop all
13531                    // those packages and flush the attribute cache as well.
13532                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13533                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13534                        if (list != null && (list.length > 0)) {
13535                            for (String pkg : list) {
13536                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13537                                        "storage unmount");
13538                            }
13539                            sendPackageBroadcastLocked(
13540                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13541                        }
13542                    } else {
13543                        Uri data = intent.getData();
13544                        String ssp;
13545                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13546                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13547                                    intent.getAction());
13548                            boolean fullUninstall = removed &&
13549                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13550                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13551                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13552                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13553                                        false, fullUninstall, userId,
13554                                        removed ? "pkg removed" : "pkg changed");
13555                            }
13556                            if (removed) {
13557                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13558                                        new String[] {ssp}, userId);
13559                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13560                                    mAppOpsService.packageRemoved(
13561                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13562
13563                                    // Remove all permissions granted from/to this package
13564                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13565                                }
13566                            }
13567                        }
13568                    }
13569                }
13570            } else {
13571                String msg = "Permission Denial: " + intent.getAction()
13572                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13573                        + ", uid=" + callingUid + ")"
13574                        + " requires "
13575                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13576                Slog.w(TAG, msg);
13577                throw new SecurityException(msg);
13578            }
13579
13580        // Special case for adding a package: by default turn on compatibility
13581        // mode.
13582        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13583            Uri data = intent.getData();
13584            String ssp;
13585            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13586                mCompatModePackages.handlePackageAddedLocked(ssp,
13587                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13588            }
13589        }
13590
13591        /*
13592         * If this is the time zone changed action, queue up a message that will reset the timezone
13593         * of all currently running processes. This message will get queued up before the broadcast
13594         * happens.
13595         */
13596        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13597            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13598        }
13599
13600        /*
13601         * If the user set the time, let all running processes know.
13602         */
13603        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13604            final int is24Hour = intent.getBooleanExtra(
13605                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13606            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13607        }
13608
13609        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13610            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13611        }
13612
13613        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13614            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13615            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13616        }
13617
13618        // Add to the sticky list if requested.
13619        if (sticky) {
13620            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13621                    callingPid, callingUid)
13622                    != PackageManager.PERMISSION_GRANTED) {
13623                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13624                        + callingPid + ", uid=" + callingUid
13625                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13626                Slog.w(TAG, msg);
13627                throw new SecurityException(msg);
13628            }
13629            if (requiredPermission != null) {
13630                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13631                        + " and enforce permission " + requiredPermission);
13632                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13633            }
13634            if (intent.getComponent() != null) {
13635                throw new SecurityException(
13636                        "Sticky broadcasts can't target a specific component");
13637            }
13638            // We use userId directly here, since the "all" target is maintained
13639            // as a separate set of sticky broadcasts.
13640            if (userId != UserHandle.USER_ALL) {
13641                // But first, if this is not a broadcast to all users, then
13642                // make sure it doesn't conflict with an existing broadcast to
13643                // all users.
13644                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13645                        UserHandle.USER_ALL);
13646                if (stickies != null) {
13647                    ArrayList<Intent> list = stickies.get(intent.getAction());
13648                    if (list != null) {
13649                        int N = list.size();
13650                        int i;
13651                        for (i=0; i<N; i++) {
13652                            if (intent.filterEquals(list.get(i))) {
13653                                throw new IllegalArgumentException(
13654                                        "Sticky broadcast " + intent + " for user "
13655                                        + userId + " conflicts with existing global broadcast");
13656                            }
13657                        }
13658                    }
13659                }
13660            }
13661            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13662            if (stickies == null) {
13663                stickies = new ArrayMap<String, ArrayList<Intent>>();
13664                mStickyBroadcasts.put(userId, stickies);
13665            }
13666            ArrayList<Intent> list = stickies.get(intent.getAction());
13667            if (list == null) {
13668                list = new ArrayList<Intent>();
13669                stickies.put(intent.getAction(), list);
13670            }
13671            int N = list.size();
13672            int i;
13673            for (i=0; i<N; i++) {
13674                if (intent.filterEquals(list.get(i))) {
13675                    // This sticky already exists, replace it.
13676                    list.set(i, new Intent(intent));
13677                    break;
13678                }
13679            }
13680            if (i >= N) {
13681                list.add(new Intent(intent));
13682            }
13683        }
13684
13685        int[] users;
13686        if (userId == UserHandle.USER_ALL) {
13687            // Caller wants broadcast to go to all started users.
13688            users = mStartedUserArray;
13689        } else {
13690            // Caller wants broadcast to go to one specific user.
13691            users = new int[] {userId};
13692        }
13693
13694        // Figure out who all will receive this broadcast.
13695        List receivers = null;
13696        List<BroadcastFilter> registeredReceivers = null;
13697        // Need to resolve the intent to interested receivers...
13698        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13699                 == 0) {
13700            receivers = collectReceiverComponents(intent, resolvedType, users);
13701        }
13702        if (intent.getComponent() == null) {
13703            registeredReceivers = mReceiverResolver.queryIntent(intent,
13704                    resolvedType, false, userId);
13705        }
13706
13707        final boolean replacePending =
13708                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13709
13710        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13711                + " replacePending=" + replacePending);
13712
13713        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13714        if (!ordered && NR > 0) {
13715            // If we are not serializing this broadcast, then send the
13716            // registered receivers separately so they don't wait for the
13717            // components to be launched.
13718            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13719            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13720                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13721                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13722                    ordered, sticky, false, userId);
13723            if (DEBUG_BROADCAST) Slog.v(
13724                    TAG, "Enqueueing parallel broadcast " + r);
13725            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13726            if (!replaced) {
13727                queue.enqueueParallelBroadcastLocked(r);
13728                queue.scheduleBroadcastsLocked();
13729            }
13730            registeredReceivers = null;
13731            NR = 0;
13732        }
13733
13734        // Merge into one list.
13735        int ir = 0;
13736        if (receivers != null) {
13737            // A special case for PACKAGE_ADDED: do not allow the package
13738            // being added to see this broadcast.  This prevents them from
13739            // using this as a back door to get run as soon as they are
13740            // installed.  Maybe in the future we want to have a special install
13741            // broadcast or such for apps, but we'd like to deliberately make
13742            // this decision.
13743            String skipPackages[] = null;
13744            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13745                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13746                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13747                Uri data = intent.getData();
13748                if (data != null) {
13749                    String pkgName = data.getSchemeSpecificPart();
13750                    if (pkgName != null) {
13751                        skipPackages = new String[] { pkgName };
13752                    }
13753                }
13754            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13755                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13756            }
13757            if (skipPackages != null && (skipPackages.length > 0)) {
13758                for (String skipPackage : skipPackages) {
13759                    if (skipPackage != null) {
13760                        int NT = receivers.size();
13761                        for (int it=0; it<NT; it++) {
13762                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13763                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13764                                receivers.remove(it);
13765                                it--;
13766                                NT--;
13767                            }
13768                        }
13769                    }
13770                }
13771            }
13772
13773            int NT = receivers != null ? receivers.size() : 0;
13774            int it = 0;
13775            ResolveInfo curt = null;
13776            BroadcastFilter curr = null;
13777            while (it < NT && ir < NR) {
13778                if (curt == null) {
13779                    curt = (ResolveInfo)receivers.get(it);
13780                }
13781                if (curr == null) {
13782                    curr = registeredReceivers.get(ir);
13783                }
13784                if (curr.getPriority() >= curt.priority) {
13785                    // Insert this broadcast record into the final list.
13786                    receivers.add(it, curr);
13787                    ir++;
13788                    curr = null;
13789                    it++;
13790                    NT++;
13791                } else {
13792                    // Skip to the next ResolveInfo in the final list.
13793                    it++;
13794                    curt = null;
13795                }
13796            }
13797        }
13798        while (ir < NR) {
13799            if (receivers == null) {
13800                receivers = new ArrayList();
13801            }
13802            receivers.add(registeredReceivers.get(ir));
13803            ir++;
13804        }
13805
13806        if ((receivers != null && receivers.size() > 0)
13807                || resultTo != null) {
13808            BroadcastQueue queue = broadcastQueueForIntent(intent);
13809            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13810                    callerPackage, callingPid, callingUid, resolvedType,
13811                    requiredPermission, appOp, receivers, resultTo, resultCode,
13812                    resultData, map, ordered, sticky, false, userId);
13813            if (DEBUG_BROADCAST) Slog.v(
13814                    TAG, "Enqueueing ordered broadcast " + r
13815                    + ": prev had " + queue.mOrderedBroadcasts.size());
13816            if (DEBUG_BROADCAST) {
13817                int seq = r.intent.getIntExtra("seq", -1);
13818                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13819            }
13820            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13821            if (!replaced) {
13822                queue.enqueueOrderedBroadcastLocked(r);
13823                queue.scheduleBroadcastsLocked();
13824            }
13825        }
13826
13827        return ActivityManager.BROADCAST_SUCCESS;
13828    }
13829
13830    final Intent verifyBroadcastLocked(Intent intent) {
13831        // Refuse possible leaked file descriptors
13832        if (intent != null && intent.hasFileDescriptors() == true) {
13833            throw new IllegalArgumentException("File descriptors passed in Intent");
13834        }
13835
13836        int flags = intent.getFlags();
13837
13838        if (!mProcessesReady) {
13839            // if the caller really truly claims to know what they're doing, go
13840            // ahead and allow the broadcast without launching any receivers
13841            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13842                intent = new Intent(intent);
13843                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13844            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13845                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13846                        + " before boot completion");
13847                throw new IllegalStateException("Cannot broadcast before boot completed");
13848            }
13849        }
13850
13851        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13852            throw new IllegalArgumentException(
13853                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13854        }
13855
13856        return intent;
13857    }
13858
13859    public final int broadcastIntent(IApplicationThread caller,
13860            Intent intent, String resolvedType, IIntentReceiver resultTo,
13861            int resultCode, String resultData, Bundle map,
13862            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13863        enforceNotIsolatedCaller("broadcastIntent");
13864        synchronized(this) {
13865            intent = verifyBroadcastLocked(intent);
13866
13867            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13868            final int callingPid = Binder.getCallingPid();
13869            final int callingUid = Binder.getCallingUid();
13870            final long origId = Binder.clearCallingIdentity();
13871            int res = broadcastIntentLocked(callerApp,
13872                    callerApp != null ? callerApp.info.packageName : null,
13873                    intent, resolvedType, resultTo,
13874                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13875                    callingPid, callingUid, userId);
13876            Binder.restoreCallingIdentity(origId);
13877            return res;
13878        }
13879    }
13880
13881    int broadcastIntentInPackage(String packageName, int uid,
13882            Intent intent, String resolvedType, IIntentReceiver resultTo,
13883            int resultCode, String resultData, Bundle map,
13884            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13885        synchronized(this) {
13886            intent = verifyBroadcastLocked(intent);
13887
13888            final long origId = Binder.clearCallingIdentity();
13889            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13890                    resultTo, resultCode, resultData, map, requiredPermission,
13891                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13892            Binder.restoreCallingIdentity(origId);
13893            return res;
13894        }
13895    }
13896
13897    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13898        // Refuse possible leaked file descriptors
13899        if (intent != null && intent.hasFileDescriptors() == true) {
13900            throw new IllegalArgumentException("File descriptors passed in Intent");
13901        }
13902
13903        userId = handleIncomingUser(Binder.getCallingPid(),
13904                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13905
13906        synchronized(this) {
13907            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13908                    != PackageManager.PERMISSION_GRANTED) {
13909                String msg = "Permission Denial: unbroadcastIntent() from pid="
13910                        + Binder.getCallingPid()
13911                        + ", uid=" + Binder.getCallingUid()
13912                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13913                Slog.w(TAG, msg);
13914                throw new SecurityException(msg);
13915            }
13916            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13917            if (stickies != null) {
13918                ArrayList<Intent> list = stickies.get(intent.getAction());
13919                if (list != null) {
13920                    int N = list.size();
13921                    int i;
13922                    for (i=0; i<N; i++) {
13923                        if (intent.filterEquals(list.get(i))) {
13924                            list.remove(i);
13925                            break;
13926                        }
13927                    }
13928                    if (list.size() <= 0) {
13929                        stickies.remove(intent.getAction());
13930                    }
13931                }
13932                if (stickies.size() <= 0) {
13933                    mStickyBroadcasts.remove(userId);
13934                }
13935            }
13936        }
13937    }
13938
13939    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13940            String resultData, Bundle resultExtras, boolean resultAbort) {
13941        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13942        if (r == null) {
13943            Slog.w(TAG, "finishReceiver called but not found on queue");
13944            return false;
13945        }
13946
13947        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13948    }
13949
13950    void backgroundServicesFinishedLocked(int userId) {
13951        for (BroadcastQueue queue : mBroadcastQueues) {
13952            queue.backgroundServicesFinishedLocked(userId);
13953        }
13954    }
13955
13956    public void finishReceiver(IBinder who, int resultCode, String resultData,
13957            Bundle resultExtras, boolean resultAbort) {
13958        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13959
13960        // Refuse possible leaked file descriptors
13961        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13962            throw new IllegalArgumentException("File descriptors passed in Bundle");
13963        }
13964
13965        final long origId = Binder.clearCallingIdentity();
13966        try {
13967            boolean doNext = false;
13968            BroadcastRecord r;
13969
13970            synchronized(this) {
13971                r = broadcastRecordForReceiverLocked(who);
13972                if (r != null) {
13973                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13974                        resultData, resultExtras, resultAbort, true);
13975                }
13976            }
13977
13978            if (doNext) {
13979                r.queue.processNextBroadcast(false);
13980            }
13981            trimApplications();
13982        } finally {
13983            Binder.restoreCallingIdentity(origId);
13984        }
13985    }
13986
13987    // =========================================================
13988    // INSTRUMENTATION
13989    // =========================================================
13990
13991    public boolean startInstrumentation(ComponentName className,
13992            String profileFile, int flags, Bundle arguments,
13993            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13994            int userId) {
13995        enforceNotIsolatedCaller("startInstrumentation");
13996        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13997                userId, false, true, "startInstrumentation", null);
13998        // Refuse possible leaked file descriptors
13999        if (arguments != null && arguments.hasFileDescriptors()) {
14000            throw new IllegalArgumentException("File descriptors passed in Bundle");
14001        }
14002
14003        synchronized(this) {
14004            InstrumentationInfo ii = null;
14005            ApplicationInfo ai = null;
14006            try {
14007                ii = mContext.getPackageManager().getInstrumentationInfo(
14008                    className, STOCK_PM_FLAGS);
14009                ai = AppGlobals.getPackageManager().getApplicationInfo(
14010                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14011            } catch (PackageManager.NameNotFoundException e) {
14012            } catch (RemoteException e) {
14013            }
14014            if (ii == null) {
14015                reportStartInstrumentationFailure(watcher, className,
14016                        "Unable to find instrumentation info for: " + className);
14017                return false;
14018            }
14019            if (ai == null) {
14020                reportStartInstrumentationFailure(watcher, className,
14021                        "Unable to find instrumentation target package: " + ii.targetPackage);
14022                return false;
14023            }
14024
14025            int match = mContext.getPackageManager().checkSignatures(
14026                    ii.targetPackage, ii.packageName);
14027            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14028                String msg = "Permission Denial: starting instrumentation "
14029                        + className + " from pid="
14030                        + Binder.getCallingPid()
14031                        + ", uid=" + Binder.getCallingPid()
14032                        + " not allowed because package " + ii.packageName
14033                        + " does not have a signature matching the target "
14034                        + ii.targetPackage;
14035                reportStartInstrumentationFailure(watcher, className, msg);
14036                throw new SecurityException(msg);
14037            }
14038
14039            final long origId = Binder.clearCallingIdentity();
14040            // Instrumentation can kill and relaunch even persistent processes
14041            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14042                    "start instr");
14043            ProcessRecord app = addAppLocked(ai, false);
14044            app.instrumentationClass = className;
14045            app.instrumentationInfo = ai;
14046            app.instrumentationProfileFile = profileFile;
14047            app.instrumentationArguments = arguments;
14048            app.instrumentationWatcher = watcher;
14049            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14050            app.instrumentationResultClass = className;
14051            Binder.restoreCallingIdentity(origId);
14052        }
14053
14054        return true;
14055    }
14056
14057    /**
14058     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14059     * error to the logs, but if somebody is watching, send the report there too.  This enables
14060     * the "am" command to report errors with more information.
14061     *
14062     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14063     * @param cn The component name of the instrumentation.
14064     * @param report The error report.
14065     */
14066    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14067            ComponentName cn, String report) {
14068        Slog.w(TAG, report);
14069        try {
14070            if (watcher != null) {
14071                Bundle results = new Bundle();
14072                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14073                results.putString("Error", report);
14074                watcher.instrumentationStatus(cn, -1, results);
14075            }
14076        } catch (RemoteException e) {
14077            Slog.w(TAG, e);
14078        }
14079    }
14080
14081    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14082        if (app.instrumentationWatcher != null) {
14083            try {
14084                // NOTE:  IInstrumentationWatcher *must* be oneway here
14085                app.instrumentationWatcher.instrumentationFinished(
14086                    app.instrumentationClass,
14087                    resultCode,
14088                    results);
14089            } catch (RemoteException e) {
14090            }
14091        }
14092        if (app.instrumentationUiAutomationConnection != null) {
14093            try {
14094                app.instrumentationUiAutomationConnection.shutdown();
14095            } catch (RemoteException re) {
14096                /* ignore */
14097            }
14098            // Only a UiAutomation can set this flag and now that
14099            // it is finished we make sure it is reset to its default.
14100            mUserIsMonkey = false;
14101        }
14102        app.instrumentationWatcher = null;
14103        app.instrumentationUiAutomationConnection = null;
14104        app.instrumentationClass = null;
14105        app.instrumentationInfo = null;
14106        app.instrumentationProfileFile = null;
14107        app.instrumentationArguments = null;
14108
14109        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14110                "finished inst");
14111    }
14112
14113    public void finishInstrumentation(IApplicationThread target,
14114            int resultCode, Bundle results) {
14115        int userId = UserHandle.getCallingUserId();
14116        // Refuse possible leaked file descriptors
14117        if (results != null && results.hasFileDescriptors()) {
14118            throw new IllegalArgumentException("File descriptors passed in Intent");
14119        }
14120
14121        synchronized(this) {
14122            ProcessRecord app = getRecordForAppLocked(target);
14123            if (app == null) {
14124                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14125                return;
14126            }
14127            final long origId = Binder.clearCallingIdentity();
14128            finishInstrumentationLocked(app, resultCode, results);
14129            Binder.restoreCallingIdentity(origId);
14130        }
14131    }
14132
14133    // =========================================================
14134    // CONFIGURATION
14135    // =========================================================
14136
14137    public ConfigurationInfo getDeviceConfigurationInfo() {
14138        ConfigurationInfo config = new ConfigurationInfo();
14139        synchronized (this) {
14140            config.reqTouchScreen = mConfiguration.touchscreen;
14141            config.reqKeyboardType = mConfiguration.keyboard;
14142            config.reqNavigation = mConfiguration.navigation;
14143            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14144                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14145                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14146            }
14147            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14148                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14149                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14150            }
14151            config.reqGlEsVersion = GL_ES_VERSION;
14152        }
14153        return config;
14154    }
14155
14156    ActivityStack getFocusedStack() {
14157        return mStackSupervisor.getFocusedStack();
14158    }
14159
14160    public Configuration getConfiguration() {
14161        Configuration ci;
14162        synchronized(this) {
14163            ci = new Configuration(mConfiguration);
14164        }
14165        return ci;
14166    }
14167
14168    public void updatePersistentConfiguration(Configuration values) {
14169        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14170                "updateConfiguration()");
14171        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14172                "updateConfiguration()");
14173        if (values == null) {
14174            throw new NullPointerException("Configuration must not be null");
14175        }
14176
14177        synchronized(this) {
14178            final long origId = Binder.clearCallingIdentity();
14179            updateConfigurationLocked(values, null, true, false);
14180            Binder.restoreCallingIdentity(origId);
14181        }
14182    }
14183
14184    public void updateConfiguration(Configuration values) {
14185        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14186                "updateConfiguration()");
14187
14188        synchronized(this) {
14189            if (values == null && mWindowManager != null) {
14190                // sentinel: fetch the current configuration from the window manager
14191                values = mWindowManager.computeNewConfiguration();
14192            }
14193
14194            if (mWindowManager != null) {
14195                mProcessList.applyDisplaySize(mWindowManager);
14196            }
14197
14198            final long origId = Binder.clearCallingIdentity();
14199            if (values != null) {
14200                Settings.System.clearConfiguration(values);
14201            }
14202            updateConfigurationLocked(values, null, false, false);
14203            Binder.restoreCallingIdentity(origId);
14204        }
14205    }
14206
14207    /**
14208     * Do either or both things: (1) change the current configuration, and (2)
14209     * make sure the given activity is running with the (now) current
14210     * configuration.  Returns true if the activity has been left running, or
14211     * false if <var>starting</var> is being destroyed to match the new
14212     * configuration.
14213     * @param persistent TODO
14214     */
14215    boolean updateConfigurationLocked(Configuration values,
14216            ActivityRecord starting, boolean persistent, boolean initLocale) {
14217        int changes = 0;
14218
14219        if (values != null) {
14220            Configuration newConfig = new Configuration(mConfiguration);
14221            changes = newConfig.updateFrom(values);
14222            if (changes != 0) {
14223                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14224                    Slog.i(TAG, "Updating configuration to: " + values);
14225                }
14226
14227                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14228
14229                if (values.locale != null && !initLocale) {
14230                    saveLocaleLocked(values.locale,
14231                                     !values.locale.equals(mConfiguration.locale),
14232                                     values.userSetLocale);
14233                }
14234
14235                mConfigurationSeq++;
14236                if (mConfigurationSeq <= 0) {
14237                    mConfigurationSeq = 1;
14238                }
14239                newConfig.seq = mConfigurationSeq;
14240                mConfiguration = newConfig;
14241                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14242
14243                final Configuration configCopy = new Configuration(mConfiguration);
14244
14245                // TODO: If our config changes, should we auto dismiss any currently
14246                // showing dialogs?
14247                mShowDialogs = shouldShowDialogs(newConfig);
14248
14249                AttributeCache ac = AttributeCache.instance();
14250                if (ac != null) {
14251                    ac.updateConfiguration(configCopy);
14252                }
14253
14254                // Make sure all resources in our process are updated
14255                // right now, so that anyone who is going to retrieve
14256                // resource values after we return will be sure to get
14257                // the new ones.  This is especially important during
14258                // boot, where the first config change needs to guarantee
14259                // all resources have that config before following boot
14260                // code is executed.
14261                mSystemThread.applyConfigurationToResources(configCopy);
14262
14263                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14264                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14265                    msg.obj = new Configuration(configCopy);
14266                    mHandler.sendMessage(msg);
14267                }
14268
14269                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14270                    ProcessRecord app = mLruProcesses.get(i);
14271                    try {
14272                        if (app.thread != null) {
14273                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14274                                    + app.processName + " new config " + mConfiguration);
14275                            app.thread.scheduleConfigurationChanged(configCopy);
14276                        }
14277                    } catch (Exception e) {
14278                    }
14279                }
14280                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14281                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14282                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14283                        | Intent.FLAG_RECEIVER_FOREGROUND);
14284                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14285                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14286                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14287                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14288                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14289                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14290                    broadcastIntentLocked(null, null, intent,
14291                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14292                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14293                }
14294            }
14295        }
14296
14297        boolean kept = true;
14298        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14299        // mainStack is null during startup.
14300        if (mainStack != null) {
14301            if (changes != 0 && starting == null) {
14302                // If the configuration changed, and the caller is not already
14303                // in the process of starting an activity, then find the top
14304                // activity to check if its configuration needs to change.
14305                starting = mainStack.topRunningActivityLocked(null);
14306            }
14307
14308            if (starting != null) {
14309                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14310                // And we need to make sure at this point that all other activities
14311                // are made visible with the correct configuration.
14312                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14313            }
14314        }
14315
14316        if (values != null && mWindowManager != null) {
14317            mWindowManager.setNewConfiguration(mConfiguration);
14318        }
14319
14320        return kept;
14321    }
14322
14323    /**
14324     * Decide based on the configuration whether we should shouw the ANR,
14325     * crash, etc dialogs.  The idea is that if there is no affordnace to
14326     * press the on-screen buttons, we shouldn't show the dialog.
14327     *
14328     * A thought: SystemUI might also want to get told about this, the Power
14329     * dialog / global actions also might want different behaviors.
14330     */
14331    private static final boolean shouldShowDialogs(Configuration config) {
14332        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14333                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14334    }
14335
14336    /**
14337     * Save the locale.  You must be inside a synchronized (this) block.
14338     */
14339    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14340        if(isDiff) {
14341            SystemProperties.set("user.language", l.getLanguage());
14342            SystemProperties.set("user.region", l.getCountry());
14343        }
14344
14345        if(isPersist) {
14346            SystemProperties.set("persist.sys.language", l.getLanguage());
14347            SystemProperties.set("persist.sys.country", l.getCountry());
14348            SystemProperties.set("persist.sys.localevar", l.getVariant());
14349        }
14350    }
14351
14352    @Override
14353    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14354        ActivityRecord srec = ActivityRecord.forToken(token);
14355        return srec != null && srec.task.affinity != null &&
14356                srec.task.affinity.equals(destAffinity);
14357    }
14358
14359    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14360            Intent resultData) {
14361
14362        synchronized (this) {
14363            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14364            if (stack != null) {
14365                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14366            }
14367            return false;
14368        }
14369    }
14370
14371    public int getLaunchedFromUid(IBinder activityToken) {
14372        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14373        if (srec == null) {
14374            return -1;
14375        }
14376        return srec.launchedFromUid;
14377    }
14378
14379    public String getLaunchedFromPackage(IBinder activityToken) {
14380        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14381        if (srec == null) {
14382            return null;
14383        }
14384        return srec.launchedFromPackage;
14385    }
14386
14387    // =========================================================
14388    // LIFETIME MANAGEMENT
14389    // =========================================================
14390
14391    // Returns which broadcast queue the app is the current [or imminent] receiver
14392    // on, or 'null' if the app is not an active broadcast recipient.
14393    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14394        BroadcastRecord r = app.curReceiver;
14395        if (r != null) {
14396            return r.queue;
14397        }
14398
14399        // It's not the current receiver, but it might be starting up to become one
14400        synchronized (this) {
14401            for (BroadcastQueue queue : mBroadcastQueues) {
14402                r = queue.mPendingBroadcast;
14403                if (r != null && r.curApp == app) {
14404                    // found it; report which queue it's in
14405                    return queue;
14406                }
14407            }
14408        }
14409
14410        return null;
14411    }
14412
14413    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14414            boolean doingAll, long now) {
14415        if (mAdjSeq == app.adjSeq) {
14416            // This adjustment has already been computed.
14417            return app.curRawAdj;
14418        }
14419
14420        if (app.thread == null) {
14421            app.adjSeq = mAdjSeq;
14422            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14423            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14424            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14425        }
14426
14427        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14428        app.adjSource = null;
14429        app.adjTarget = null;
14430        app.empty = false;
14431        app.cached = false;
14432
14433        final int activitiesSize = app.activities.size();
14434
14435        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14436            // The max adjustment doesn't allow this app to be anything
14437            // below foreground, so it is not worth doing work for it.
14438            app.adjType = "fixed";
14439            app.adjSeq = mAdjSeq;
14440            app.curRawAdj = app.maxAdj;
14441            app.foregroundActivities = false;
14442            app.keeping = true;
14443            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14444            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14445            // System process can do UI, and when they do we want to have
14446            // them trim their memory after the user leaves the UI.  To
14447            // facilitate this, here we need to determine whether or not it
14448            // is currently showing UI.
14449            app.systemNoUi = true;
14450            if (app == TOP_APP) {
14451                app.systemNoUi = false;
14452            } else if (activitiesSize > 0) {
14453                for (int j = 0; j < activitiesSize; j++) {
14454                    final ActivityRecord r = app.activities.get(j);
14455                    if (r.visible) {
14456                        app.systemNoUi = false;
14457                    }
14458                }
14459            }
14460            if (!app.systemNoUi) {
14461                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14462            }
14463            return (app.curAdj=app.maxAdj);
14464        }
14465
14466        app.keeping = false;
14467        app.systemNoUi = false;
14468
14469        // Determine the importance of the process, starting with most
14470        // important to least, and assign an appropriate OOM adjustment.
14471        int adj;
14472        int schedGroup;
14473        int procState;
14474        boolean foregroundActivities = false;
14475        boolean interesting = false;
14476        BroadcastQueue queue;
14477        if (app == TOP_APP) {
14478            // The last app on the list is the foreground app.
14479            adj = ProcessList.FOREGROUND_APP_ADJ;
14480            schedGroup = Process.THREAD_GROUP_DEFAULT;
14481            app.adjType = "top-activity";
14482            foregroundActivities = true;
14483            interesting = true;
14484            procState = ActivityManager.PROCESS_STATE_TOP;
14485        } else if (app.instrumentationClass != null) {
14486            // Don't want to kill running instrumentation.
14487            adj = ProcessList.FOREGROUND_APP_ADJ;
14488            schedGroup = Process.THREAD_GROUP_DEFAULT;
14489            app.adjType = "instrumentation";
14490            interesting = true;
14491            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14492        } else if ((queue = isReceivingBroadcast(app)) != null) {
14493            // An app that is currently receiving a broadcast also
14494            // counts as being in the foreground for OOM killer purposes.
14495            // It's placed in a sched group based on the nature of the
14496            // broadcast as reflected by which queue it's active in.
14497            adj = ProcessList.FOREGROUND_APP_ADJ;
14498            schedGroup = (queue == mFgBroadcastQueue)
14499                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14500            app.adjType = "broadcast";
14501            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14502        } else if (app.executingServices.size() > 0) {
14503            // An app that is currently executing a service callback also
14504            // counts as being in the foreground.
14505            adj = ProcessList.FOREGROUND_APP_ADJ;
14506            schedGroup = app.execServicesFg ?
14507                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14508            app.adjType = "exec-service";
14509            procState = ActivityManager.PROCESS_STATE_SERVICE;
14510            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14511        } else {
14512            // As far as we know the process is empty.  We may change our mind later.
14513            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14514            // At this point we don't actually know the adjustment.  Use the cached adj
14515            // value that the caller wants us to.
14516            adj = cachedAdj;
14517            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14518            app.cached = true;
14519            app.empty = true;
14520            app.adjType = "cch-empty";
14521        }
14522
14523        // Examine all activities if not already foreground.
14524        if (!foregroundActivities && activitiesSize > 0) {
14525            for (int j = 0; j < activitiesSize; j++) {
14526                final ActivityRecord r = app.activities.get(j);
14527                if (r.app != app) {
14528                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14529                            + app + "?!?");
14530                    continue;
14531                }
14532                if (r.visible) {
14533                    // App has a visible activity; only upgrade adjustment.
14534                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14535                        adj = ProcessList.VISIBLE_APP_ADJ;
14536                        app.adjType = "visible";
14537                    }
14538                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14539                        procState = ActivityManager.PROCESS_STATE_TOP;
14540                    }
14541                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14542                    app.cached = false;
14543                    app.empty = false;
14544                    foregroundActivities = true;
14545                    break;
14546                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14547                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14548                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14549                        app.adjType = "pausing";
14550                    }
14551                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14552                        procState = ActivityManager.PROCESS_STATE_TOP;
14553                    }
14554                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14555                    app.cached = false;
14556                    app.empty = false;
14557                    foregroundActivities = true;
14558                } else if (r.state == ActivityState.STOPPING) {
14559                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14560                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14561                        app.adjType = "stopping";
14562                    }
14563                    // For the process state, we will at this point consider the
14564                    // process to be cached.  It will be cached either as an activity
14565                    // or empty depending on whether the activity is finishing.  We do
14566                    // this so that we can treat the process as cached for purposes of
14567                    // memory trimming (determing current memory level, trim command to
14568                    // send to process) since there can be an arbitrary number of stopping
14569                    // processes and they should soon all go into the cached state.
14570                    if (!r.finishing) {
14571                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14572                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14573                        }
14574                    }
14575                    app.cached = false;
14576                    app.empty = false;
14577                    foregroundActivities = true;
14578                } else {
14579                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14580                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14581                        app.adjType = "cch-act";
14582                    }
14583                }
14584            }
14585        }
14586
14587        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14588            if (app.foregroundServices) {
14589                // The user is aware of this app, so make it visible.
14590                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14591                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14592                app.cached = false;
14593                app.adjType = "fg-service";
14594                schedGroup = Process.THREAD_GROUP_DEFAULT;
14595            } else if (app.forcingToForeground != null) {
14596                // The user is aware of this app, so make it visible.
14597                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14598                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14599                app.cached = false;
14600                app.adjType = "force-fg";
14601                app.adjSource = app.forcingToForeground;
14602                schedGroup = Process.THREAD_GROUP_DEFAULT;
14603            }
14604        }
14605
14606        if (app.foregroundServices) {
14607            interesting = true;
14608        }
14609
14610        if (app == mHeavyWeightProcess) {
14611            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14612                // We don't want to kill the current heavy-weight process.
14613                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14614                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14615                app.cached = false;
14616                app.adjType = "heavy";
14617            }
14618            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14619                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14620            }
14621        }
14622
14623        if (app == mHomeProcess) {
14624            if (adj > ProcessList.HOME_APP_ADJ) {
14625                // This process is hosting what we currently consider to be the
14626                // home app, so we don't want to let it go into the background.
14627                adj = ProcessList.HOME_APP_ADJ;
14628                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14629                app.cached = false;
14630                app.adjType = "home";
14631            }
14632            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14633                procState = ActivityManager.PROCESS_STATE_HOME;
14634            }
14635        }
14636
14637        if (app == mPreviousProcess && app.activities.size() > 0) {
14638            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14639                // This was the previous process that showed UI to the user.
14640                // We want to try to keep it around more aggressively, to give
14641                // a good experience around switching between two apps.
14642                adj = ProcessList.PREVIOUS_APP_ADJ;
14643                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14644                app.cached = false;
14645                app.adjType = "previous";
14646            }
14647            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14648                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14649            }
14650        }
14651
14652        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14653                + " reason=" + app.adjType);
14654
14655        // By default, we use the computed adjustment.  It may be changed if
14656        // there are applications dependent on our services or providers, but
14657        // this gives us a baseline and makes sure we don't get into an
14658        // infinite recursion.
14659        app.adjSeq = mAdjSeq;
14660        app.curRawAdj = adj;
14661        app.hasStartedServices = false;
14662
14663        if (mBackupTarget != null && app == mBackupTarget.app) {
14664            // If possible we want to avoid killing apps while they're being backed up
14665            if (adj > ProcessList.BACKUP_APP_ADJ) {
14666                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14667                adj = ProcessList.BACKUP_APP_ADJ;
14668                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14669                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14670                }
14671                app.adjType = "backup";
14672                app.cached = false;
14673            }
14674            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14675                procState = ActivityManager.PROCESS_STATE_BACKUP;
14676            }
14677        }
14678
14679        boolean mayBeTop = false;
14680
14681        for (int is = app.services.size()-1;
14682                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14683                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14684                        || procState > ActivityManager.PROCESS_STATE_TOP);
14685                is--) {
14686            ServiceRecord s = app.services.valueAt(is);
14687            if (s.startRequested) {
14688                app.hasStartedServices = true;
14689                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14690                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14691                }
14692                if (app.hasShownUi && app != mHomeProcess) {
14693                    // If this process has shown some UI, let it immediately
14694                    // go to the LRU list because it may be pretty heavy with
14695                    // UI stuff.  We'll tag it with a label just to help
14696                    // debug and understand what is going on.
14697                    if (adj > ProcessList.SERVICE_ADJ) {
14698                        app.adjType = "cch-started-ui-services";
14699                    }
14700                } else {
14701                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14702                        // This service has seen some activity within
14703                        // recent memory, so we will keep its process ahead
14704                        // of the background processes.
14705                        if (adj > ProcessList.SERVICE_ADJ) {
14706                            adj = ProcessList.SERVICE_ADJ;
14707                            app.adjType = "started-services";
14708                            app.cached = false;
14709                        }
14710                    }
14711                    // If we have let the service slide into the background
14712                    // state, still have some text describing what it is doing
14713                    // even though the service no longer has an impact.
14714                    if (adj > ProcessList.SERVICE_ADJ) {
14715                        app.adjType = "cch-started-services";
14716                    }
14717                }
14718                // Don't kill this process because it is doing work; it
14719                // has said it is doing work.
14720                app.keeping = true;
14721            }
14722            for (int conni = s.connections.size()-1;
14723                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14724                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14725                            || procState > ActivityManager.PROCESS_STATE_TOP);
14726                    conni--) {
14727                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14728                for (int i = 0;
14729                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14730                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14731                                || procState > ActivityManager.PROCESS_STATE_TOP);
14732                        i++) {
14733                    // XXX should compute this based on the max of
14734                    // all connected clients.
14735                    ConnectionRecord cr = clist.get(i);
14736                    if (cr.binding.client == app) {
14737                        // Binding to ourself is not interesting.
14738                        continue;
14739                    }
14740                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14741                        ProcessRecord client = cr.binding.client;
14742                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14743                                TOP_APP, doingAll, now);
14744                        int clientProcState = client.curProcState;
14745                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14746                            // If the other app is cached for any reason, for purposes here
14747                            // we are going to consider it empty.  The specific cached state
14748                            // doesn't propagate except under certain conditions.
14749                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14750                        }
14751                        String adjType = null;
14752                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14753                            // Not doing bind OOM management, so treat
14754                            // this guy more like a started service.
14755                            if (app.hasShownUi && app != mHomeProcess) {
14756                                // If this process has shown some UI, let it immediately
14757                                // go to the LRU list because it may be pretty heavy with
14758                                // UI stuff.  We'll tag it with a label just to help
14759                                // debug and understand what is going on.
14760                                if (adj > clientAdj) {
14761                                    adjType = "cch-bound-ui-services";
14762                                }
14763                                app.cached = false;
14764                                clientAdj = adj;
14765                                clientProcState = procState;
14766                            } else {
14767                                if (now >= (s.lastActivity
14768                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14769                                    // This service has not seen activity within
14770                                    // recent memory, so allow it to drop to the
14771                                    // LRU list if there is no other reason to keep
14772                                    // it around.  We'll also tag it with a label just
14773                                    // to help debug and undertand what is going on.
14774                                    if (adj > clientAdj) {
14775                                        adjType = "cch-bound-services";
14776                                    }
14777                                    clientAdj = adj;
14778                                }
14779                            }
14780                        }
14781                        if (adj > clientAdj) {
14782                            // If this process has recently shown UI, and
14783                            // the process that is binding to it is less
14784                            // important than being visible, then we don't
14785                            // care about the binding as much as we care
14786                            // about letting this process get into the LRU
14787                            // list to be killed and restarted if needed for
14788                            // memory.
14789                            if (app.hasShownUi && app != mHomeProcess
14790                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14791                                adjType = "cch-bound-ui-services";
14792                            } else {
14793                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14794                                        |Context.BIND_IMPORTANT)) != 0) {
14795                                    adj = clientAdj;
14796                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14797                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14798                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14799                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14800                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14801                                    adj = clientAdj;
14802                                } else {
14803                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14804                                        adj = ProcessList.VISIBLE_APP_ADJ;
14805                                    }
14806                                }
14807                                if (!client.cached) {
14808                                    app.cached = false;
14809                                }
14810                                if (client.keeping) {
14811                                    app.keeping = true;
14812                                }
14813                                adjType = "service";
14814                            }
14815                        }
14816                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14817                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14818                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14819                            }
14820                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14821                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14822                                    // Special handling of clients who are in the top state.
14823                                    // We *may* want to consider this process to be in the
14824                                    // top state as well, but only if there is not another
14825                                    // reason for it to be running.  Being on the top is a
14826                                    // special state, meaning you are specifically running
14827                                    // for the current top app.  If the process is already
14828                                    // running in the background for some other reason, it
14829                                    // is more important to continue considering it to be
14830                                    // in the background state.
14831                                    mayBeTop = true;
14832                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14833                                } else {
14834                                    // Special handling for above-top states (persistent
14835                                    // processes).  These should not bring the current process
14836                                    // into the top state, since they are not on top.  Instead
14837                                    // give them the best state after that.
14838                                    clientProcState =
14839                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14840                                }
14841                            }
14842                        } else {
14843                            if (clientProcState <
14844                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14845                                clientProcState =
14846                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14847                            }
14848                        }
14849                        if (procState > clientProcState) {
14850                            procState = clientProcState;
14851                        }
14852                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14853                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14854                            app.pendingUiClean = true;
14855                        }
14856                        if (adjType != null) {
14857                            app.adjType = adjType;
14858                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14859                                    .REASON_SERVICE_IN_USE;
14860                            app.adjSource = cr.binding.client;
14861                            app.adjSourceOom = clientAdj;
14862                            app.adjTarget = s.name;
14863                        }
14864                    }
14865                    final ActivityRecord a = cr.activity;
14866                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14867                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14868                                (a.visible || a.state == ActivityState.RESUMED
14869                                 || a.state == ActivityState.PAUSING)) {
14870                            adj = ProcessList.FOREGROUND_APP_ADJ;
14871                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14872                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14873                            }
14874                            app.cached = false;
14875                            app.adjType = "service";
14876                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14877                                    .REASON_SERVICE_IN_USE;
14878                            app.adjSource = a;
14879                            app.adjSourceOom = adj;
14880                            app.adjTarget = s.name;
14881                        }
14882                    }
14883                }
14884            }
14885        }
14886
14887        for (int provi = app.pubProviders.size()-1;
14888                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14889                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14890                        || procState > ActivityManager.PROCESS_STATE_TOP);
14891                provi--) {
14892            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14893            for (int i = cpr.connections.size()-1;
14894                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14895                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14896                            || procState > ActivityManager.PROCESS_STATE_TOP);
14897                    i--) {
14898                ContentProviderConnection conn = cpr.connections.get(i);
14899                ProcessRecord client = conn.client;
14900                if (client == app) {
14901                    // Being our own client is not interesting.
14902                    continue;
14903                }
14904                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14905                int clientProcState = client.curProcState;
14906                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14907                    // If the other app is cached for any reason, for purposes here
14908                    // we are going to consider it empty.
14909                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14910                }
14911                if (adj > clientAdj) {
14912                    if (app.hasShownUi && app != mHomeProcess
14913                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14914                        app.adjType = "cch-ui-provider";
14915                    } else {
14916                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14917                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14918                        app.adjType = "provider";
14919                    }
14920                    app.cached &= client.cached;
14921                    app.keeping |= client.keeping;
14922                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14923                            .REASON_PROVIDER_IN_USE;
14924                    app.adjSource = client;
14925                    app.adjSourceOom = clientAdj;
14926                    app.adjTarget = cpr.name;
14927                }
14928                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14929                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14930                        // Special handling of clients who are in the top state.
14931                        // We *may* want to consider this process to be in the
14932                        // top state as well, but only if there is not another
14933                        // reason for it to be running.  Being on the top is a
14934                        // special state, meaning you are specifically running
14935                        // for the current top app.  If the process is already
14936                        // running in the background for some other reason, it
14937                        // is more important to continue considering it to be
14938                        // in the background state.
14939                        mayBeTop = true;
14940                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14941                    } else {
14942                        // Special handling for above-top states (persistent
14943                        // processes).  These should not bring the current process
14944                        // into the top state, since they are not on top.  Instead
14945                        // give them the best state after that.
14946                        clientProcState =
14947                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14948                    }
14949                }
14950                if (procState > clientProcState) {
14951                    procState = clientProcState;
14952                }
14953                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14954                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14955                }
14956            }
14957            // If the provider has external (non-framework) process
14958            // dependencies, ensure that its adjustment is at least
14959            // FOREGROUND_APP_ADJ.
14960            if (cpr.hasExternalProcessHandles()) {
14961                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14962                    adj = ProcessList.FOREGROUND_APP_ADJ;
14963                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14964                    app.cached = false;
14965                    app.keeping = true;
14966                    app.adjType = "provider";
14967                    app.adjTarget = cpr.name;
14968                }
14969                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14970                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14971                }
14972            }
14973        }
14974
14975        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14976            // A client of one of our services or providers is in the top state.  We
14977            // *may* want to be in the top state, but not if we are already running in
14978            // the background for some other reason.  For the decision here, we are going
14979            // to pick out a few specific states that we want to remain in when a client
14980            // is top (states that tend to be longer-term) and otherwise allow it to go
14981            // to the top state.
14982            switch (procState) {
14983                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14984                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14985                case ActivityManager.PROCESS_STATE_SERVICE:
14986                    // These all are longer-term states, so pull them up to the top
14987                    // of the background states, but not all the way to the top state.
14988                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14989                    break;
14990                default:
14991                    // Otherwise, top is a better choice, so take it.
14992                    procState = ActivityManager.PROCESS_STATE_TOP;
14993                    break;
14994            }
14995        }
14996
14997        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14998            // This is a cached process, but with client activities.  Mark it so.
14999            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15000            app.adjType = "cch-client-act";
15001        }
15002
15003        if (adj == ProcessList.SERVICE_ADJ) {
15004            if (doingAll) {
15005                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15006                mNewNumServiceProcs++;
15007                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15008                if (!app.serviceb) {
15009                    // This service isn't far enough down on the LRU list to
15010                    // normally be a B service, but if we are low on RAM and it
15011                    // is large we want to force it down since we would prefer to
15012                    // keep launcher over it.
15013                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15014                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15015                        app.serviceHighRam = true;
15016                        app.serviceb = true;
15017                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15018                    } else {
15019                        mNewNumAServiceProcs++;
15020                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15021                    }
15022                } else {
15023                    app.serviceHighRam = false;
15024                }
15025            }
15026            if (app.serviceb) {
15027                adj = ProcessList.SERVICE_B_ADJ;
15028            }
15029        }
15030
15031        app.curRawAdj = adj;
15032
15033        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15034        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15035        if (adj > app.maxAdj) {
15036            adj = app.maxAdj;
15037            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15038                schedGroup = Process.THREAD_GROUP_DEFAULT;
15039            }
15040        }
15041        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15042            app.keeping = true;
15043        }
15044
15045        // Do final modification to adj.  Everything we do between here and applying
15046        // the final setAdj must be done in this function, because we will also use
15047        // it when computing the final cached adj later.  Note that we don't need to
15048        // worry about this for max adj above, since max adj will always be used to
15049        // keep it out of the cached vaues.
15050        adj = app.modifyRawOomAdj(adj);
15051
15052        app.curProcState = procState;
15053
15054        int importance = app.memImportance;
15055        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15056            app.curAdj = adj;
15057            app.curSchedGroup = schedGroup;
15058            if (!interesting) {
15059                // For this reporting, if there is not something explicitly
15060                // interesting in this process then we will push it to the
15061                // background importance.
15062                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15063            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15064                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15065            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15066                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15067            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15068                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15069            } else if (adj >= ProcessList.SERVICE_ADJ) {
15070                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15071            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15072                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15073            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15074                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15075            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15076                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15077            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15078                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15079            } else {
15080                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15081            }
15082        }
15083
15084        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15085        if (foregroundActivities != app.foregroundActivities) {
15086            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15087        }
15088        if (changes != 0) {
15089            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15090            app.memImportance = importance;
15091            app.foregroundActivities = foregroundActivities;
15092            int i = mPendingProcessChanges.size()-1;
15093            ProcessChangeItem item = null;
15094            while (i >= 0) {
15095                item = mPendingProcessChanges.get(i);
15096                if (item.pid == app.pid) {
15097                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15098                    break;
15099                }
15100                i--;
15101            }
15102            if (i < 0) {
15103                // No existing item in pending changes; need a new one.
15104                final int NA = mAvailProcessChanges.size();
15105                if (NA > 0) {
15106                    item = mAvailProcessChanges.remove(NA-1);
15107                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15108                } else {
15109                    item = new ProcessChangeItem();
15110                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15111                }
15112                item.changes = 0;
15113                item.pid = app.pid;
15114                item.uid = app.info.uid;
15115                if (mPendingProcessChanges.size() == 0) {
15116                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15117                            "*** Enqueueing dispatch processes changed!");
15118                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15119                }
15120                mPendingProcessChanges.add(item);
15121            }
15122            item.changes |= changes;
15123            item.importance = importance;
15124            item.foregroundActivities = foregroundActivities;
15125            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15126                    + Integer.toHexString(System.identityHashCode(item))
15127                    + " " + app.toShortString() + ": changes=" + item.changes
15128                    + " importance=" + item.importance
15129                    + " foreground=" + item.foregroundActivities
15130                    + " type=" + app.adjType + " source=" + app.adjSource
15131                    + " target=" + app.adjTarget);
15132        }
15133
15134        return app.curRawAdj;
15135    }
15136
15137    /**
15138     * Schedule PSS collection of a process.
15139     */
15140    void requestPssLocked(ProcessRecord proc, int procState) {
15141        if (mPendingPssProcesses.contains(proc)) {
15142            return;
15143        }
15144        if (mPendingPssProcesses.size() == 0) {
15145            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15146        }
15147        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15148        proc.pssProcState = procState;
15149        mPendingPssProcesses.add(proc);
15150    }
15151
15152    /**
15153     * Schedule PSS collection of all processes.
15154     */
15155    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15156        if (!always) {
15157            if (now < (mLastFullPssTime +
15158                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15159                return;
15160            }
15161        }
15162        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15163        mLastFullPssTime = now;
15164        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15165        mPendingPssProcesses.clear();
15166        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15167            ProcessRecord app = mLruProcesses.get(i);
15168            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15169                app.pssProcState = app.setProcState;
15170                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15171                        mSleeping, now);
15172                mPendingPssProcesses.add(app);
15173            }
15174        }
15175        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15176    }
15177
15178    /**
15179     * Ask a given process to GC right now.
15180     */
15181    final void performAppGcLocked(ProcessRecord app) {
15182        try {
15183            app.lastRequestedGc = SystemClock.uptimeMillis();
15184            if (app.thread != null) {
15185                if (app.reportLowMemory) {
15186                    app.reportLowMemory = false;
15187                    app.thread.scheduleLowMemory();
15188                } else {
15189                    app.thread.processInBackground();
15190                }
15191            }
15192        } catch (Exception e) {
15193            // whatever.
15194        }
15195    }
15196
15197    /**
15198     * Returns true if things are idle enough to perform GCs.
15199     */
15200    private final boolean canGcNowLocked() {
15201        boolean processingBroadcasts = false;
15202        for (BroadcastQueue q : mBroadcastQueues) {
15203            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15204                processingBroadcasts = true;
15205            }
15206        }
15207        return !processingBroadcasts
15208                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15209    }
15210
15211    /**
15212     * Perform GCs on all processes that are waiting for it, but only
15213     * if things are idle.
15214     */
15215    final void performAppGcsLocked() {
15216        final int N = mProcessesToGc.size();
15217        if (N <= 0) {
15218            return;
15219        }
15220        if (canGcNowLocked()) {
15221            while (mProcessesToGc.size() > 0) {
15222                ProcessRecord proc = mProcessesToGc.remove(0);
15223                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15224                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15225                            <= SystemClock.uptimeMillis()) {
15226                        // To avoid spamming the system, we will GC processes one
15227                        // at a time, waiting a few seconds between each.
15228                        performAppGcLocked(proc);
15229                        scheduleAppGcsLocked();
15230                        return;
15231                    } else {
15232                        // It hasn't been long enough since we last GCed this
15233                        // process...  put it in the list to wait for its time.
15234                        addProcessToGcListLocked(proc);
15235                        break;
15236                    }
15237                }
15238            }
15239
15240            scheduleAppGcsLocked();
15241        }
15242    }
15243
15244    /**
15245     * If all looks good, perform GCs on all processes waiting for them.
15246     */
15247    final void performAppGcsIfAppropriateLocked() {
15248        if (canGcNowLocked()) {
15249            performAppGcsLocked();
15250            return;
15251        }
15252        // Still not idle, wait some more.
15253        scheduleAppGcsLocked();
15254    }
15255
15256    /**
15257     * Schedule the execution of all pending app GCs.
15258     */
15259    final void scheduleAppGcsLocked() {
15260        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15261
15262        if (mProcessesToGc.size() > 0) {
15263            // Schedule a GC for the time to the next process.
15264            ProcessRecord proc = mProcessesToGc.get(0);
15265            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15266
15267            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15268            long now = SystemClock.uptimeMillis();
15269            if (when < (now+GC_TIMEOUT)) {
15270                when = now + GC_TIMEOUT;
15271            }
15272            mHandler.sendMessageAtTime(msg, when);
15273        }
15274    }
15275
15276    /**
15277     * Add a process to the array of processes waiting to be GCed.  Keeps the
15278     * list in sorted order by the last GC time.  The process can't already be
15279     * on the list.
15280     */
15281    final void addProcessToGcListLocked(ProcessRecord proc) {
15282        boolean added = false;
15283        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15284            if (mProcessesToGc.get(i).lastRequestedGc <
15285                    proc.lastRequestedGc) {
15286                added = true;
15287                mProcessesToGc.add(i+1, proc);
15288                break;
15289            }
15290        }
15291        if (!added) {
15292            mProcessesToGc.add(0, proc);
15293        }
15294    }
15295
15296    /**
15297     * Set up to ask a process to GC itself.  This will either do it
15298     * immediately, or put it on the list of processes to gc the next
15299     * time things are idle.
15300     */
15301    final void scheduleAppGcLocked(ProcessRecord app) {
15302        long now = SystemClock.uptimeMillis();
15303        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15304            return;
15305        }
15306        if (!mProcessesToGc.contains(app)) {
15307            addProcessToGcListLocked(app);
15308            scheduleAppGcsLocked();
15309        }
15310    }
15311
15312    final void checkExcessivePowerUsageLocked(boolean doKills) {
15313        updateCpuStatsNow();
15314
15315        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15316        boolean doWakeKills = doKills;
15317        boolean doCpuKills = doKills;
15318        if (mLastPowerCheckRealtime == 0) {
15319            doWakeKills = false;
15320        }
15321        if (mLastPowerCheckUptime == 0) {
15322            doCpuKills = false;
15323        }
15324        if (stats.isScreenOn()) {
15325            doWakeKills = false;
15326        }
15327        final long curRealtime = SystemClock.elapsedRealtime();
15328        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15329        final long curUptime = SystemClock.uptimeMillis();
15330        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15331        mLastPowerCheckRealtime = curRealtime;
15332        mLastPowerCheckUptime = curUptime;
15333        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15334            doWakeKills = false;
15335        }
15336        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15337            doCpuKills = false;
15338        }
15339        int i = mLruProcesses.size();
15340        while (i > 0) {
15341            i--;
15342            ProcessRecord app = mLruProcesses.get(i);
15343            if (!app.keeping) {
15344                long wtime;
15345                synchronized (stats) {
15346                    wtime = stats.getProcessWakeTime(app.info.uid,
15347                            app.pid, curRealtime);
15348                }
15349                long wtimeUsed = wtime - app.lastWakeTime;
15350                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15351                if (DEBUG_POWER) {
15352                    StringBuilder sb = new StringBuilder(128);
15353                    sb.append("Wake for ");
15354                    app.toShortString(sb);
15355                    sb.append(": over ");
15356                    TimeUtils.formatDuration(realtimeSince, sb);
15357                    sb.append(" used ");
15358                    TimeUtils.formatDuration(wtimeUsed, sb);
15359                    sb.append(" (");
15360                    sb.append((wtimeUsed*100)/realtimeSince);
15361                    sb.append("%)");
15362                    Slog.i(TAG, sb.toString());
15363                    sb.setLength(0);
15364                    sb.append("CPU for ");
15365                    app.toShortString(sb);
15366                    sb.append(": over ");
15367                    TimeUtils.formatDuration(uptimeSince, sb);
15368                    sb.append(" used ");
15369                    TimeUtils.formatDuration(cputimeUsed, sb);
15370                    sb.append(" (");
15371                    sb.append((cputimeUsed*100)/uptimeSince);
15372                    sb.append("%)");
15373                    Slog.i(TAG, sb.toString());
15374                }
15375                // If a process has held a wake lock for more
15376                // than 50% of the time during this period,
15377                // that sounds bad.  Kill!
15378                if (doWakeKills && realtimeSince > 0
15379                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15380                    synchronized (stats) {
15381                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15382                                realtimeSince, wtimeUsed);
15383                    }
15384                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15385                            + " during " + realtimeSince);
15386                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15387                } else if (doCpuKills && uptimeSince > 0
15388                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15389                    synchronized (stats) {
15390                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15391                                uptimeSince, cputimeUsed);
15392                    }
15393                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15394                            + " during " + uptimeSince);
15395                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15396                } else {
15397                    app.lastWakeTime = wtime;
15398                    app.lastCpuTime = app.curCpuTime;
15399                }
15400            }
15401        }
15402    }
15403
15404    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15405            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15406        boolean success = true;
15407
15408        if (app.curRawAdj != app.setRawAdj) {
15409            if (wasKeeping && !app.keeping) {
15410                // This app is no longer something we want to keep.  Note
15411                // its current wake lock time to later know to kill it if
15412                // it is not behaving well.
15413                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15414                synchronized (stats) {
15415                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15416                            app.pid, SystemClock.elapsedRealtime());
15417                }
15418                app.lastCpuTime = app.curCpuTime;
15419            }
15420
15421            app.setRawAdj = app.curRawAdj;
15422        }
15423
15424        if (app.curAdj != app.setAdj) {
15425            ProcessList.setOomAdj(app.pid, app.curAdj);
15426            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15427                TAG, "Set " + app.pid + " " + app.processName +
15428                " adj " + app.curAdj + ": " + app.adjType);
15429            app.setAdj = app.curAdj;
15430        }
15431
15432        if (app.setSchedGroup != app.curSchedGroup) {
15433            app.setSchedGroup = app.curSchedGroup;
15434            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15435                    "Setting process group of " + app.processName
15436                    + " to " + app.curSchedGroup);
15437            if (app.waitingToKill != null &&
15438                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15439                killUnneededProcessLocked(app, app.waitingToKill);
15440                success = false;
15441            } else {
15442                if (true) {
15443                    long oldId = Binder.clearCallingIdentity();
15444                    try {
15445                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15446                    } catch (Exception e) {
15447                        Slog.w(TAG, "Failed setting process group of " + app.pid
15448                                + " to " + app.curSchedGroup);
15449                        e.printStackTrace();
15450                    } finally {
15451                        Binder.restoreCallingIdentity(oldId);
15452                    }
15453                } else {
15454                    if (app.thread != null) {
15455                        try {
15456                            app.thread.setSchedulingGroup(app.curSchedGroup);
15457                        } catch (RemoteException e) {
15458                        }
15459                    }
15460                }
15461                Process.setSwappiness(app.pid,
15462                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15463            }
15464        }
15465        if (app.repProcState != app.curProcState) {
15466            app.repProcState = app.curProcState;
15467            if (!reportingProcessState && app.thread != null) {
15468                try {
15469                    if (false) {
15470                        //RuntimeException h = new RuntimeException("here");
15471                        Slog.i(TAG, "Sending new process state " + app.repProcState
15472                                + " to " + app /*, h*/);
15473                    }
15474                    app.thread.setProcessState(app.repProcState);
15475                } catch (RemoteException e) {
15476                }
15477            }
15478        }
15479        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15480                app.setProcState)) {
15481            app.lastStateTime = now;
15482            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15483                    mSleeping, now);
15484            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15485                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15486                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15487                    + (app.nextPssTime-now) + ": " + app);
15488        } else {
15489            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15490                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15491                requestPssLocked(app, app.setProcState);
15492                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15493                        mSleeping, now);
15494            } else if (false && DEBUG_PSS) {
15495                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15496            }
15497        }
15498        if (app.setProcState != app.curProcState) {
15499            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15500                    "Proc state change of " + app.processName
15501                    + " to " + app.curProcState);
15502            app.setProcState = app.curProcState;
15503            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15504                app.notCachedSinceIdle = false;
15505            }
15506            if (!doingAll) {
15507                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15508            } else {
15509                app.procStateChanged = true;
15510            }
15511        }
15512        return success;
15513    }
15514
15515    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15516        if (proc.thread != null && proc.baseProcessTracker != null) {
15517            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15518        }
15519    }
15520
15521    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15522            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15523        if (app.thread == null) {
15524            return false;
15525        }
15526
15527        final boolean wasKeeping = app.keeping;
15528
15529        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15530
15531        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15532                reportingProcessState, now);
15533    }
15534
15535    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15536            boolean oomAdj) {
15537        if (isForeground != proc.foregroundServices) {
15538            proc.foregroundServices = isForeground;
15539            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15540                    proc.info.uid);
15541            if (isForeground) {
15542                if (curProcs == null) {
15543                    curProcs = new ArrayList<ProcessRecord>();
15544                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15545                }
15546                if (!curProcs.contains(proc)) {
15547                    curProcs.add(proc);
15548                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15549                            proc.info.packageName, proc.info.uid);
15550                }
15551            } else {
15552                if (curProcs != null) {
15553                    if (curProcs.remove(proc)) {
15554                        mBatteryStatsService.noteEvent(
15555                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15556                                proc.info.packageName, proc.info.uid);
15557                        if (curProcs.size() <= 0) {
15558                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15559                        }
15560                    }
15561                }
15562            }
15563            if (oomAdj) {
15564                updateOomAdjLocked();
15565            }
15566        }
15567    }
15568
15569    private final ActivityRecord resumedAppLocked() {
15570        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15571        String pkg;
15572        int uid;
15573        if (act != null) {
15574            pkg = act.packageName;
15575            uid = act.info.applicationInfo.uid;
15576        } else {
15577            pkg = null;
15578            uid = -1;
15579        }
15580        // Has the UID or resumed package name changed?
15581        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15582                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15583            if (mCurResumedPackage != null) {
15584                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15585                        mCurResumedPackage, mCurResumedUid);
15586            }
15587            mCurResumedPackage = pkg;
15588            mCurResumedUid = uid;
15589            if (mCurResumedPackage != null) {
15590                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15591                        mCurResumedPackage, mCurResumedUid);
15592            }
15593        }
15594        return act;
15595    }
15596
15597    final boolean updateOomAdjLocked(ProcessRecord app) {
15598        return updateOomAdjLocked(app, false);
15599    }
15600
15601    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15602        final ActivityRecord TOP_ACT = resumedAppLocked();
15603        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15604        final boolean wasCached = app.cached;
15605
15606        mAdjSeq++;
15607
15608        // This is the desired cached adjusment we want to tell it to use.
15609        // If our app is currently cached, we know it, and that is it.  Otherwise,
15610        // we don't know it yet, and it needs to now be cached we will then
15611        // need to do a complete oom adj.
15612        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15613                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15614        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15615                SystemClock.uptimeMillis());
15616        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15617            // Changed to/from cached state, so apps after it in the LRU
15618            // list may also be changed.
15619            updateOomAdjLocked();
15620        }
15621        return success;
15622    }
15623
15624    final void updateOomAdjLocked() {
15625        final ActivityRecord TOP_ACT = resumedAppLocked();
15626        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15627        final long now = SystemClock.uptimeMillis();
15628        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15629        final int N = mLruProcesses.size();
15630
15631        if (false) {
15632            RuntimeException e = new RuntimeException();
15633            e.fillInStackTrace();
15634            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15635        }
15636
15637        mAdjSeq++;
15638        mNewNumServiceProcs = 0;
15639        mNewNumAServiceProcs = 0;
15640
15641        final int emptyProcessLimit;
15642        final int cachedProcessLimit;
15643        if (mProcessLimit <= 0) {
15644            emptyProcessLimit = cachedProcessLimit = 0;
15645        } else if (mProcessLimit == 1) {
15646            emptyProcessLimit = 1;
15647            cachedProcessLimit = 0;
15648        } else {
15649            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15650            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15651        }
15652
15653        // Let's determine how many processes we have running vs.
15654        // how many slots we have for background processes; we may want
15655        // to put multiple processes in a slot of there are enough of
15656        // them.
15657        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15658                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15659        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15660        if (numEmptyProcs > cachedProcessLimit) {
15661            // If there are more empty processes than our limit on cached
15662            // processes, then use the cached process limit for the factor.
15663            // This ensures that the really old empty processes get pushed
15664            // down to the bottom, so if we are running low on memory we will
15665            // have a better chance at keeping around more cached processes
15666            // instead of a gazillion empty processes.
15667            numEmptyProcs = cachedProcessLimit;
15668        }
15669        int emptyFactor = numEmptyProcs/numSlots;
15670        if (emptyFactor < 1) emptyFactor = 1;
15671        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15672        if (cachedFactor < 1) cachedFactor = 1;
15673        int stepCached = 0;
15674        int stepEmpty = 0;
15675        int numCached = 0;
15676        int numEmpty = 0;
15677        int numTrimming = 0;
15678
15679        mNumNonCachedProcs = 0;
15680        mNumCachedHiddenProcs = 0;
15681
15682        // First update the OOM adjustment for each of the
15683        // application processes based on their current state.
15684        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15685        int nextCachedAdj = curCachedAdj+1;
15686        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15687        int nextEmptyAdj = curEmptyAdj+2;
15688        for (int i=N-1; i>=0; i--) {
15689            ProcessRecord app = mLruProcesses.get(i);
15690            if (!app.killedByAm && app.thread != null) {
15691                app.procStateChanged = false;
15692                final boolean wasKeeping = app.keeping;
15693                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15694
15695                // If we haven't yet assigned the final cached adj
15696                // to the process, do that now.
15697                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15698                    switch (app.curProcState) {
15699                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15700                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15701                            // This process is a cached process holding activities...
15702                            // assign it the next cached value for that type, and then
15703                            // step that cached level.
15704                            app.curRawAdj = curCachedAdj;
15705                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15706                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15707                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15708                                    + ")");
15709                            if (curCachedAdj != nextCachedAdj) {
15710                                stepCached++;
15711                                if (stepCached >= cachedFactor) {
15712                                    stepCached = 0;
15713                                    curCachedAdj = nextCachedAdj;
15714                                    nextCachedAdj += 2;
15715                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15716                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15717                                    }
15718                                }
15719                            }
15720                            break;
15721                        default:
15722                            // For everything else, assign next empty cached process
15723                            // level and bump that up.  Note that this means that
15724                            // long-running services that have dropped down to the
15725                            // cached level will be treated as empty (since their process
15726                            // state is still as a service), which is what we want.
15727                            app.curRawAdj = curEmptyAdj;
15728                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15729                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15730                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15731                                    + ")");
15732                            if (curEmptyAdj != nextEmptyAdj) {
15733                                stepEmpty++;
15734                                if (stepEmpty >= emptyFactor) {
15735                                    stepEmpty = 0;
15736                                    curEmptyAdj = nextEmptyAdj;
15737                                    nextEmptyAdj += 2;
15738                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15739                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15740                                    }
15741                                }
15742                            }
15743                            break;
15744                    }
15745                }
15746
15747                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15748
15749                // Count the number of process types.
15750                switch (app.curProcState) {
15751                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15752                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15753                        mNumCachedHiddenProcs++;
15754                        numCached++;
15755                        if (numCached > cachedProcessLimit) {
15756                            killUnneededProcessLocked(app, "cached #" + numCached);
15757                        }
15758                        break;
15759                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15760                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15761                                && app.lastActivityTime < oldTime) {
15762                            killUnneededProcessLocked(app, "empty for "
15763                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15764                                    / 1000) + "s");
15765                        } else {
15766                            numEmpty++;
15767                            if (numEmpty > emptyProcessLimit) {
15768                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15769                            }
15770                        }
15771                        break;
15772                    default:
15773                        mNumNonCachedProcs++;
15774                        break;
15775                }
15776
15777                if (app.isolated && app.services.size() <= 0) {
15778                    // If this is an isolated process, and there are no
15779                    // services running in it, then the process is no longer
15780                    // needed.  We agressively kill these because we can by
15781                    // definition not re-use the same process again, and it is
15782                    // good to avoid having whatever code was running in them
15783                    // left sitting around after no longer needed.
15784                    killUnneededProcessLocked(app, "isolated not needed");
15785                }
15786
15787                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15788                        && !app.killedByAm) {
15789                    numTrimming++;
15790                }
15791            }
15792        }
15793
15794        mNumServiceProcs = mNewNumServiceProcs;
15795
15796        // Now determine the memory trimming level of background processes.
15797        // Unfortunately we need to start at the back of the list to do this
15798        // properly.  We only do this if the number of background apps we
15799        // are managing to keep around is less than half the maximum we desire;
15800        // if we are keeping a good number around, we'll let them use whatever
15801        // memory they want.
15802        final int numCachedAndEmpty = numCached + numEmpty;
15803        int memFactor;
15804        if (numCached <= ProcessList.TRIM_CACHED_APPS
15805                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15806            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15807                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15808            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15809                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15810            } else {
15811                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15812            }
15813        } else {
15814            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15815        }
15816        // We always allow the memory level to go up (better).  We only allow it to go
15817        // down if we are in a state where that is allowed, *and* the total number of processes
15818        // has gone down since last time.
15819        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15820                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15821                + " last=" + mLastNumProcesses);
15822        if (memFactor > mLastMemoryLevel) {
15823            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15824                memFactor = mLastMemoryLevel;
15825                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15826            }
15827        }
15828        mLastMemoryLevel = memFactor;
15829        mLastNumProcesses = mLruProcesses.size();
15830        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15831        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15832        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15833            if (mLowRamStartTime == 0) {
15834                mLowRamStartTime = now;
15835            }
15836            int step = 0;
15837            int fgTrimLevel;
15838            switch (memFactor) {
15839                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15840                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15841                    break;
15842                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15843                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15844                    break;
15845                default:
15846                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15847                    break;
15848            }
15849            int factor = numTrimming/3;
15850            int minFactor = 2;
15851            if (mHomeProcess != null) minFactor++;
15852            if (mPreviousProcess != null) minFactor++;
15853            if (factor < minFactor) factor = minFactor;
15854            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15855            for (int i=N-1; i>=0; i--) {
15856                ProcessRecord app = mLruProcesses.get(i);
15857                if (allChanged || app.procStateChanged) {
15858                    setProcessTrackerState(app, trackerMemFactor, now);
15859                    app.procStateChanged = false;
15860                }
15861                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15862                        && !app.killedByAm) {
15863                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15864                        try {
15865                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15866                                    "Trimming memory of " + app.processName
15867                                    + " to " + curLevel);
15868                            app.thread.scheduleTrimMemory(curLevel);
15869                        } catch (RemoteException e) {
15870                        }
15871                        if (false) {
15872                            // For now we won't do this; our memory trimming seems
15873                            // to be good enough at this point that destroying
15874                            // activities causes more harm than good.
15875                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15876                                    && app != mHomeProcess && app != mPreviousProcess) {
15877                                // Need to do this on its own message because the stack may not
15878                                // be in a consistent state at this point.
15879                                // For these apps we will also finish their activities
15880                                // to help them free memory.
15881                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15882                            }
15883                        }
15884                    }
15885                    app.trimMemoryLevel = curLevel;
15886                    step++;
15887                    if (step >= factor) {
15888                        step = 0;
15889                        switch (curLevel) {
15890                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15891                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15892                                break;
15893                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15894                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15895                                break;
15896                        }
15897                    }
15898                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15899                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15900                            && app.thread != null) {
15901                        try {
15902                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15903                                    "Trimming memory of heavy-weight " + app.processName
15904                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15905                            app.thread.scheduleTrimMemory(
15906                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15907                        } catch (RemoteException e) {
15908                        }
15909                    }
15910                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15911                } else {
15912                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15913                            || app.systemNoUi) && app.pendingUiClean) {
15914                        // If this application is now in the background and it
15915                        // had done UI, then give it the special trim level to
15916                        // have it free UI resources.
15917                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15918                        if (app.trimMemoryLevel < level && app.thread != null) {
15919                            try {
15920                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15921                                        "Trimming memory of bg-ui " + app.processName
15922                                        + " to " + level);
15923                                app.thread.scheduleTrimMemory(level);
15924                            } catch (RemoteException e) {
15925                            }
15926                        }
15927                        app.pendingUiClean = false;
15928                    }
15929                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15930                        try {
15931                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15932                                    "Trimming memory of fg " + app.processName
15933                                    + " to " + fgTrimLevel);
15934                            app.thread.scheduleTrimMemory(fgTrimLevel);
15935                        } catch (RemoteException e) {
15936                        }
15937                    }
15938                    app.trimMemoryLevel = fgTrimLevel;
15939                }
15940            }
15941        } else {
15942            if (mLowRamStartTime != 0) {
15943                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15944                mLowRamStartTime = 0;
15945            }
15946            for (int i=N-1; i>=0; i--) {
15947                ProcessRecord app = mLruProcesses.get(i);
15948                if (allChanged || app.procStateChanged) {
15949                    setProcessTrackerState(app, trackerMemFactor, now);
15950                    app.procStateChanged = false;
15951                }
15952                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15953                        || app.systemNoUi) && app.pendingUiClean) {
15954                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15955                            && app.thread != null) {
15956                        try {
15957                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15958                                    "Trimming memory of ui hidden " + app.processName
15959                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15960                            app.thread.scheduleTrimMemory(
15961                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15962                        } catch (RemoteException e) {
15963                        }
15964                    }
15965                    app.pendingUiClean = false;
15966                }
15967                app.trimMemoryLevel = 0;
15968            }
15969        }
15970
15971        if (mAlwaysFinishActivities) {
15972            // Need to do this on its own message because the stack may not
15973            // be in a consistent state at this point.
15974            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15975        }
15976
15977        if (allChanged) {
15978            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15979        }
15980
15981        if (mProcessStats.shouldWriteNowLocked(now)) {
15982            mHandler.post(new Runnable() {
15983                @Override public void run() {
15984                    synchronized (ActivityManagerService.this) {
15985                        mProcessStats.writeStateAsyncLocked();
15986                    }
15987                }
15988            });
15989        }
15990
15991        if (DEBUG_OOM_ADJ) {
15992            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15993        }
15994    }
15995
15996    final void trimApplications() {
15997        synchronized (this) {
15998            int i;
15999
16000            // First remove any unused application processes whose package
16001            // has been removed.
16002            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16003                final ProcessRecord app = mRemovedProcesses.get(i);
16004                if (app.activities.size() == 0
16005                        && app.curReceiver == null && app.services.size() == 0) {
16006                    Slog.i(
16007                        TAG, "Exiting empty application process "
16008                        + app.processName + " ("
16009                        + (app.thread != null ? app.thread.asBinder() : null)
16010                        + ")\n");
16011                    if (app.pid > 0 && app.pid != MY_PID) {
16012                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16013                                app.processName, app.setAdj, "empty");
16014                        app.killedByAm = true;
16015                        Process.killProcessQuiet(app.pid);
16016                    } else {
16017                        try {
16018                            app.thread.scheduleExit();
16019                        } catch (Exception e) {
16020                            // Ignore exceptions.
16021                        }
16022                    }
16023                    cleanUpApplicationRecordLocked(app, false, true, -1);
16024                    mRemovedProcesses.remove(i);
16025
16026                    if (app.persistent) {
16027                        if (app.persistent) {
16028                            addAppLocked(app.info, false);
16029                        }
16030                    }
16031                }
16032            }
16033
16034            // Now update the oom adj for all processes.
16035            updateOomAdjLocked();
16036        }
16037    }
16038
16039    /** This method sends the specified signal to each of the persistent apps */
16040    public void signalPersistentProcesses(int sig) throws RemoteException {
16041        if (sig != Process.SIGNAL_USR1) {
16042            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16043        }
16044
16045        synchronized (this) {
16046            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16047                    != PackageManager.PERMISSION_GRANTED) {
16048                throw new SecurityException("Requires permission "
16049                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16050            }
16051
16052            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16053                ProcessRecord r = mLruProcesses.get(i);
16054                if (r.thread != null && r.persistent) {
16055                    Process.sendSignal(r.pid, sig);
16056                }
16057            }
16058        }
16059    }
16060
16061    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16062        if (proc == null || proc == mProfileProc) {
16063            proc = mProfileProc;
16064            path = mProfileFile;
16065            profileType = mProfileType;
16066            clearProfilerLocked();
16067        }
16068        if (proc == null) {
16069            return;
16070        }
16071        try {
16072            proc.thread.profilerControl(false, path, null, profileType);
16073        } catch (RemoteException e) {
16074            throw new IllegalStateException("Process disappeared");
16075        }
16076    }
16077
16078    private void clearProfilerLocked() {
16079        if (mProfileFd != null) {
16080            try {
16081                mProfileFd.close();
16082            } catch (IOException e) {
16083            }
16084        }
16085        mProfileApp = null;
16086        mProfileProc = null;
16087        mProfileFile = null;
16088        mProfileType = 0;
16089        mAutoStopProfiler = false;
16090    }
16091
16092    public boolean profileControl(String process, int userId, boolean start,
16093            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16094
16095        try {
16096            synchronized (this) {
16097                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16098                // its own permission.
16099                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16100                        != PackageManager.PERMISSION_GRANTED) {
16101                    throw new SecurityException("Requires permission "
16102                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16103                }
16104
16105                if (start && fd == null) {
16106                    throw new IllegalArgumentException("null fd");
16107                }
16108
16109                ProcessRecord proc = null;
16110                if (process != null) {
16111                    proc = findProcessLocked(process, userId, "profileControl");
16112                }
16113
16114                if (start && (proc == null || proc.thread == null)) {
16115                    throw new IllegalArgumentException("Unknown process: " + process);
16116                }
16117
16118                if (start) {
16119                    stopProfilerLocked(null, null, 0);
16120                    setProfileApp(proc.info, proc.processName, path, fd, false);
16121                    mProfileProc = proc;
16122                    mProfileType = profileType;
16123                    try {
16124                        fd = fd.dup();
16125                    } catch (IOException e) {
16126                        fd = null;
16127                    }
16128                    proc.thread.profilerControl(start, path, fd, profileType);
16129                    fd = null;
16130                    mProfileFd = null;
16131                } else {
16132                    stopProfilerLocked(proc, path, profileType);
16133                    if (fd != null) {
16134                        try {
16135                            fd.close();
16136                        } catch (IOException e) {
16137                        }
16138                    }
16139                }
16140
16141                return true;
16142            }
16143        } catch (RemoteException e) {
16144            throw new IllegalStateException("Process disappeared");
16145        } finally {
16146            if (fd != null) {
16147                try {
16148                    fd.close();
16149                } catch (IOException e) {
16150                }
16151            }
16152        }
16153    }
16154
16155    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16156        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16157                userId, true, true, callName, null);
16158        ProcessRecord proc = null;
16159        try {
16160            int pid = Integer.parseInt(process);
16161            synchronized (mPidsSelfLocked) {
16162                proc = mPidsSelfLocked.get(pid);
16163            }
16164        } catch (NumberFormatException e) {
16165        }
16166
16167        if (proc == null) {
16168            ArrayMap<String, SparseArray<ProcessRecord>> all
16169                    = mProcessNames.getMap();
16170            SparseArray<ProcessRecord> procs = all.get(process);
16171            if (procs != null && procs.size() > 0) {
16172                proc = procs.valueAt(0);
16173                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16174                    for (int i=1; i<procs.size(); i++) {
16175                        ProcessRecord thisProc = procs.valueAt(i);
16176                        if (thisProc.userId == userId) {
16177                            proc = thisProc;
16178                            break;
16179                        }
16180                    }
16181                }
16182            }
16183        }
16184
16185        return proc;
16186    }
16187
16188    public boolean dumpHeap(String process, int userId, boolean managed,
16189            String path, ParcelFileDescriptor fd) throws RemoteException {
16190
16191        try {
16192            synchronized (this) {
16193                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16194                // its own permission (same as profileControl).
16195                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16196                        != PackageManager.PERMISSION_GRANTED) {
16197                    throw new SecurityException("Requires permission "
16198                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16199                }
16200
16201                if (fd == null) {
16202                    throw new IllegalArgumentException("null fd");
16203                }
16204
16205                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16206                if (proc == null || proc.thread == null) {
16207                    throw new IllegalArgumentException("Unknown process: " + process);
16208                }
16209
16210                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16211                if (!isDebuggable) {
16212                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16213                        throw new SecurityException("Process not debuggable: " + proc);
16214                    }
16215                }
16216
16217                proc.thread.dumpHeap(managed, path, fd);
16218                fd = null;
16219                return true;
16220            }
16221        } catch (RemoteException e) {
16222            throw new IllegalStateException("Process disappeared");
16223        } finally {
16224            if (fd != null) {
16225                try {
16226                    fd.close();
16227                } catch (IOException e) {
16228                }
16229            }
16230        }
16231    }
16232
16233    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16234    public void monitor() {
16235        synchronized (this) { }
16236    }
16237
16238    void onCoreSettingsChange(Bundle settings) {
16239        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16240            ProcessRecord processRecord = mLruProcesses.get(i);
16241            try {
16242                if (processRecord.thread != null) {
16243                    processRecord.thread.setCoreSettings(settings);
16244                }
16245            } catch (RemoteException re) {
16246                /* ignore */
16247            }
16248        }
16249    }
16250
16251    // Multi-user methods
16252
16253    /**
16254     * Start user, if its not already running, but don't bring it to foreground.
16255     */
16256    @Override
16257    public boolean startUserInBackground(final int userId) {
16258        return startUser(userId, /* foreground */ false);
16259    }
16260
16261    /**
16262     * Refreshes the list of users related to the current user when either a
16263     * user switch happens or when a new related user is started in the
16264     * background.
16265     */
16266    private void updateRelatedUserIdsLocked() {
16267        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16268        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16269        for (int i = 0; i < relatedUserIds.length; i++) {
16270            relatedUserIds[i] = relatedUsers.get(i).id;
16271        }
16272        mRelatedUserIds = relatedUserIds;
16273    }
16274
16275    private Set getRelatedUsersLocked(int userId) {
16276        Set userIds = new HashSet<Integer>();
16277        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId);
16278        for (UserInfo user : relatedUsers) {
16279            userIds.add(Integer.valueOf(user.id));
16280        }
16281        return userIds;
16282    }
16283
16284    @Override
16285    public boolean switchUser(final int userId) {
16286        return startUser(userId, /* foregound */ true);
16287    }
16288
16289    private boolean startUser(final int userId, boolean foreground) {
16290        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16291                != PackageManager.PERMISSION_GRANTED) {
16292            String msg = "Permission Denial: switchUser() from pid="
16293                    + Binder.getCallingPid()
16294                    + ", uid=" + Binder.getCallingUid()
16295                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16296            Slog.w(TAG, msg);
16297            throw new SecurityException(msg);
16298        }
16299
16300        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16301
16302        final long ident = Binder.clearCallingIdentity();
16303        try {
16304            synchronized (this) {
16305                final int oldUserId = mCurrentUserId;
16306                if (oldUserId == userId) {
16307                    return true;
16308                }
16309
16310                mStackSupervisor.setLockTaskModeLocked(null);
16311
16312                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16313                if (userInfo == null) {
16314                    Slog.w(TAG, "No user info for user #" + userId);
16315                    return false;
16316                }
16317
16318                if (foreground) {
16319                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16320                            R.anim.screen_user_enter);
16321                }
16322
16323                boolean needStart = false;
16324
16325                // If the user we are switching to is not currently started, then
16326                // we need to start it now.
16327                if (mStartedUsers.get(userId) == null) {
16328                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16329                    updateStartedUserArrayLocked();
16330                    needStart = true;
16331                }
16332
16333                final Integer userIdInt = Integer.valueOf(userId);
16334                mUserLru.remove(userIdInt);
16335                mUserLru.add(userIdInt);
16336
16337                if (foreground) {
16338                    mCurrentUserId = userId;
16339                    updateRelatedUserIdsLocked();
16340                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16341                    // Once the internal notion of the active user has switched, we lock the device
16342                    // with the option to show the user switcher on the keyguard.
16343                    mWindowManager.lockNow(null);
16344                } else {
16345                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16346                    updateRelatedUserIdsLocked();
16347                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16348                    mUserLru.remove(currentUserIdInt);
16349                    mUserLru.add(currentUserIdInt);
16350                }
16351
16352                final UserStartedState uss = mStartedUsers.get(userId);
16353
16354                // Make sure user is in the started state.  If it is currently
16355                // stopping, we need to knock that off.
16356                if (uss.mState == UserStartedState.STATE_STOPPING) {
16357                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16358                    // so we can just fairly silently bring the user back from
16359                    // the almost-dead.
16360                    uss.mState = UserStartedState.STATE_RUNNING;
16361                    updateStartedUserArrayLocked();
16362                    needStart = true;
16363                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16364                    // This means ACTION_SHUTDOWN has been sent, so we will
16365                    // need to treat this as a new boot of the user.
16366                    uss.mState = UserStartedState.STATE_BOOTING;
16367                    updateStartedUserArrayLocked();
16368                    needStart = true;
16369                }
16370
16371                if (foreground) {
16372                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16373                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16374                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16375                            oldUserId, userId, uss));
16376                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16377                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16378                }
16379
16380                if (needStart) {
16381                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16382                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16383                            | Intent.FLAG_RECEIVER_FOREGROUND);
16384                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16385                    broadcastIntentLocked(null, null, intent,
16386                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16387                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16388                }
16389
16390                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16391                    if (userId != 0) {
16392                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16393                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16394                        broadcastIntentLocked(null, null, intent, null,
16395                                new IIntentReceiver.Stub() {
16396                                    public void performReceive(Intent intent, int resultCode,
16397                                            String data, Bundle extras, boolean ordered,
16398                                            boolean sticky, int sendingUser) {
16399                                        userInitialized(uss, userId);
16400                                    }
16401                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16402                                true, false, MY_PID, Process.SYSTEM_UID,
16403                                userId);
16404                        uss.initializing = true;
16405                    } else {
16406                        getUserManagerLocked().makeInitialized(userInfo.id);
16407                    }
16408                }
16409
16410                if (foreground) {
16411                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16412                    if (homeInFront) {
16413                        startHomeActivityLocked(userId);
16414                    } else {
16415                        mStackSupervisor.resumeTopActivitiesLocked();
16416                    }
16417                    EventLogTags.writeAmSwitchUser(userId);
16418                    getUserManagerLocked().userForeground(userId);
16419                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16420                }
16421
16422                if (needStart) {
16423                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16424                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16425                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16426                    broadcastIntentLocked(null, null, intent,
16427                            null, new IIntentReceiver.Stub() {
16428                                @Override
16429                                public void performReceive(Intent intent, int resultCode, String data,
16430                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16431                                        throws RemoteException {
16432                                }
16433                            }, 0, null, null,
16434                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16435                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16436                }
16437            }
16438        } finally {
16439            Binder.restoreCallingIdentity(ident);
16440        }
16441
16442        return true;
16443    }
16444
16445    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16446        long ident = Binder.clearCallingIdentity();
16447        try {
16448            Intent intent;
16449            if (oldUserId >= 0) {
16450                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16451                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16452                        | Intent.FLAG_RECEIVER_FOREGROUND);
16453                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16454                broadcastIntentLocked(null, null, intent,
16455                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16456                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16457            }
16458            if (newUserId >= 0) {
16459                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16460                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16461                        | Intent.FLAG_RECEIVER_FOREGROUND);
16462                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16463                broadcastIntentLocked(null, null, intent,
16464                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16465                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16466                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16467                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16468                        | Intent.FLAG_RECEIVER_FOREGROUND);
16469                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16470                broadcastIntentLocked(null, null, intent,
16471                        null, null, 0, null, null,
16472                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16473                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16474            }
16475        } finally {
16476            Binder.restoreCallingIdentity(ident);
16477        }
16478    }
16479
16480    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16481            final int newUserId) {
16482        final int N = mUserSwitchObservers.beginBroadcast();
16483        if (N > 0) {
16484            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16485                int mCount = 0;
16486                @Override
16487                public void sendResult(Bundle data) throws RemoteException {
16488                    synchronized (ActivityManagerService.this) {
16489                        if (mCurUserSwitchCallback == this) {
16490                            mCount++;
16491                            if (mCount == N) {
16492                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16493                            }
16494                        }
16495                    }
16496                }
16497            };
16498            synchronized (this) {
16499                uss.switching = true;
16500                mCurUserSwitchCallback = callback;
16501            }
16502            for (int i=0; i<N; i++) {
16503                try {
16504                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16505                            newUserId, callback);
16506                } catch (RemoteException e) {
16507                }
16508            }
16509        } else {
16510            synchronized (this) {
16511                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16512            }
16513        }
16514        mUserSwitchObservers.finishBroadcast();
16515    }
16516
16517    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16518        synchronized (this) {
16519            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16520            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16521        }
16522    }
16523
16524    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16525        mCurUserSwitchCallback = null;
16526        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16527        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16528                oldUserId, newUserId, uss));
16529    }
16530
16531    void userInitialized(UserStartedState uss, int newUserId) {
16532        completeSwitchAndInitalize(uss, newUserId, true, false);
16533    }
16534
16535    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16536        completeSwitchAndInitalize(uss, newUserId, false, true);
16537    }
16538
16539    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16540            boolean clearInitializing, boolean clearSwitching) {
16541        boolean unfrozen = false;
16542        synchronized (this) {
16543            if (clearInitializing) {
16544                uss.initializing = false;
16545                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16546            }
16547            if (clearSwitching) {
16548                uss.switching = false;
16549            }
16550            if (!uss.switching && !uss.initializing) {
16551                mWindowManager.stopFreezingScreen();
16552                unfrozen = true;
16553            }
16554        }
16555        if (unfrozen) {
16556            final int N = mUserSwitchObservers.beginBroadcast();
16557            for (int i=0; i<N; i++) {
16558                try {
16559                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16560                } catch (RemoteException e) {
16561                }
16562            }
16563            mUserSwitchObservers.finishBroadcast();
16564        }
16565    }
16566
16567    void scheduleStartRelatedUsersLocked() {
16568        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16569            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16570                    DateUtils.SECOND_IN_MILLIS);
16571        }
16572    }
16573
16574    void startRelatedUsersLocked() {
16575        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16576        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16577        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16578        for (UserInfo relatedUser : relatedUsers) {
16579            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16580                toStart.add(relatedUser);
16581            }
16582        }
16583        final int n = toStart.size();
16584        int i = 0;
16585        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16586            startUserInBackground(toStart.get(i).id);
16587        }
16588        if (i < n) {
16589            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16590        }
16591    }
16592
16593    void finishUserSwitch(UserStartedState uss) {
16594        synchronized (this) {
16595            if (uss.mState == UserStartedState.STATE_BOOTING
16596                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16597                uss.mState = UserStartedState.STATE_RUNNING;
16598                final int userId = uss.mHandle.getIdentifier();
16599                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16600                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16601                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16602                broadcastIntentLocked(null, null, intent,
16603                        null, null, 0, null, null,
16604                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16605                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16606            }
16607
16608            startRelatedUsersLocked();
16609
16610            int num = mUserLru.size();
16611            int i = 0;
16612            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16613                Integer oldUserId = mUserLru.get(i);
16614                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16615                if (oldUss == null) {
16616                    // Shouldn't happen, but be sane if it does.
16617                    mUserLru.remove(i);
16618                    num--;
16619                    continue;
16620                }
16621                if (oldUss.mState == UserStartedState.STATE_STOPPING
16622                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16623                    // This user is already stopping, doesn't count.
16624                    num--;
16625                    i++;
16626                    continue;
16627                }
16628                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16629                    // Owner and current can't be stopped, but count as running.
16630                    i++;
16631                    continue;
16632                }
16633                // This is a user to be stopped.
16634                stopUserLocked(oldUserId, null);
16635                num--;
16636                i++;
16637            }
16638        }
16639    }
16640
16641    @Override
16642    public int stopUser(final int userId, final IStopUserCallback callback) {
16643        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16644                != PackageManager.PERMISSION_GRANTED) {
16645            String msg = "Permission Denial: switchUser() from pid="
16646                    + Binder.getCallingPid()
16647                    + ", uid=" + Binder.getCallingUid()
16648                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16649            Slog.w(TAG, msg);
16650            throw new SecurityException(msg);
16651        }
16652        if (userId <= 0) {
16653            throw new IllegalArgumentException("Can't stop primary user " + userId);
16654        }
16655        synchronized (this) {
16656            return stopUserLocked(userId, callback);
16657        }
16658    }
16659
16660    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16661        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16662        if (mCurrentUserId == userId) {
16663            return ActivityManager.USER_OP_IS_CURRENT;
16664        }
16665
16666        final UserStartedState uss = mStartedUsers.get(userId);
16667        if (uss == null) {
16668            // User is not started, nothing to do...  but we do need to
16669            // callback if requested.
16670            if (callback != null) {
16671                mHandler.post(new Runnable() {
16672                    @Override
16673                    public void run() {
16674                        try {
16675                            callback.userStopped(userId);
16676                        } catch (RemoteException e) {
16677                        }
16678                    }
16679                });
16680            }
16681            return ActivityManager.USER_OP_SUCCESS;
16682        }
16683
16684        if (callback != null) {
16685            uss.mStopCallbacks.add(callback);
16686        }
16687
16688        if (uss.mState != UserStartedState.STATE_STOPPING
16689                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16690            uss.mState = UserStartedState.STATE_STOPPING;
16691            updateStartedUserArrayLocked();
16692
16693            long ident = Binder.clearCallingIdentity();
16694            try {
16695                // We are going to broadcast ACTION_USER_STOPPING and then
16696                // once that is done send a final ACTION_SHUTDOWN and then
16697                // stop the user.
16698                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16699                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16700                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16701                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16702                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16703                // This is the result receiver for the final shutdown broadcast.
16704                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16705                    @Override
16706                    public void performReceive(Intent intent, int resultCode, String data,
16707                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16708                        finishUserStop(uss);
16709                    }
16710                };
16711                // This is the result receiver for the initial stopping broadcast.
16712                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16713                    @Override
16714                    public void performReceive(Intent intent, int resultCode, String data,
16715                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16716                        // On to the next.
16717                        synchronized (ActivityManagerService.this) {
16718                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16719                                // Whoops, we are being started back up.  Abort, abort!
16720                                return;
16721                            }
16722                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16723                        }
16724                        broadcastIntentLocked(null, null, shutdownIntent,
16725                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16726                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16727                    }
16728                };
16729                // Kick things off.
16730                broadcastIntentLocked(null, null, stoppingIntent,
16731                        null, stoppingReceiver, 0, null, null,
16732                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16733                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16734            } finally {
16735                Binder.restoreCallingIdentity(ident);
16736            }
16737        }
16738
16739        return ActivityManager.USER_OP_SUCCESS;
16740    }
16741
16742    void finishUserStop(UserStartedState uss) {
16743        final int userId = uss.mHandle.getIdentifier();
16744        boolean stopped;
16745        ArrayList<IStopUserCallback> callbacks;
16746        synchronized (this) {
16747            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16748            if (mStartedUsers.get(userId) != uss) {
16749                stopped = false;
16750            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16751                stopped = false;
16752            } else {
16753                stopped = true;
16754                // User can no longer run.
16755                mStartedUsers.remove(userId);
16756                mUserLru.remove(Integer.valueOf(userId));
16757                updateStartedUserArrayLocked();
16758
16759                // Clean up all state and processes associated with the user.
16760                // Kill all the processes for the user.
16761                forceStopUserLocked(userId, "finish user");
16762            }
16763        }
16764
16765        for (int i=0; i<callbacks.size(); i++) {
16766            try {
16767                if (stopped) callbacks.get(i).userStopped(userId);
16768                else callbacks.get(i).userStopAborted(userId);
16769            } catch (RemoteException e) {
16770            }
16771        }
16772
16773        mStackSupervisor.removeUserLocked(userId);
16774    }
16775
16776    @Override
16777    public UserInfo getCurrentUser() {
16778        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16779                != PackageManager.PERMISSION_GRANTED) && (
16780                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16781                != PackageManager.PERMISSION_GRANTED)) {
16782            String msg = "Permission Denial: getCurrentUser() from pid="
16783                    + Binder.getCallingPid()
16784                    + ", uid=" + Binder.getCallingUid()
16785                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16786            Slog.w(TAG, msg);
16787            throw new SecurityException(msg);
16788        }
16789        synchronized (this) {
16790            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16791        }
16792    }
16793
16794    int getCurrentUserIdLocked() {
16795        return mCurrentUserId;
16796    }
16797
16798    @Override
16799    public boolean isUserRunning(int userId, boolean orStopped) {
16800        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16801                != PackageManager.PERMISSION_GRANTED) {
16802            String msg = "Permission Denial: isUserRunning() from pid="
16803                    + Binder.getCallingPid()
16804                    + ", uid=" + Binder.getCallingUid()
16805                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16806            Slog.w(TAG, msg);
16807            throw new SecurityException(msg);
16808        }
16809        synchronized (this) {
16810            return isUserRunningLocked(userId, orStopped);
16811        }
16812    }
16813
16814    boolean isUserRunningLocked(int userId, boolean orStopped) {
16815        UserStartedState state = mStartedUsers.get(userId);
16816        if (state == null) {
16817            return false;
16818        }
16819        if (orStopped) {
16820            return true;
16821        }
16822        return state.mState != UserStartedState.STATE_STOPPING
16823                && state.mState != UserStartedState.STATE_SHUTDOWN;
16824    }
16825
16826    @Override
16827    public int[] getRunningUserIds() {
16828        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16829                != PackageManager.PERMISSION_GRANTED) {
16830            String msg = "Permission Denial: isUserRunning() from pid="
16831                    + Binder.getCallingPid()
16832                    + ", uid=" + Binder.getCallingUid()
16833                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16834            Slog.w(TAG, msg);
16835            throw new SecurityException(msg);
16836        }
16837        synchronized (this) {
16838            return mStartedUserArray;
16839        }
16840    }
16841
16842    private void updateStartedUserArrayLocked() {
16843        int num = 0;
16844        for (int i=0; i<mStartedUsers.size();  i++) {
16845            UserStartedState uss = mStartedUsers.valueAt(i);
16846            // This list does not include stopping users.
16847            if (uss.mState != UserStartedState.STATE_STOPPING
16848                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16849                num++;
16850            }
16851        }
16852        mStartedUserArray = new int[num];
16853        num = 0;
16854        for (int i=0; i<mStartedUsers.size();  i++) {
16855            UserStartedState uss = mStartedUsers.valueAt(i);
16856            if (uss.mState != UserStartedState.STATE_STOPPING
16857                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16858                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16859                num++;
16860            }
16861        }
16862    }
16863
16864    @Override
16865    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16866        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16867                != PackageManager.PERMISSION_GRANTED) {
16868            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16869                    + Binder.getCallingPid()
16870                    + ", uid=" + Binder.getCallingUid()
16871                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16872            Slog.w(TAG, msg);
16873            throw new SecurityException(msg);
16874        }
16875
16876        mUserSwitchObservers.register(observer);
16877    }
16878
16879    @Override
16880    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16881        mUserSwitchObservers.unregister(observer);
16882    }
16883
16884    private boolean userExists(int userId) {
16885        if (userId == 0) {
16886            return true;
16887        }
16888        UserManagerService ums = getUserManagerLocked();
16889        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16890    }
16891
16892    int[] getUsersLocked() {
16893        UserManagerService ums = getUserManagerLocked();
16894        return ums != null ? ums.getUserIds() : new int[] { 0 };
16895    }
16896
16897    UserManagerService getUserManagerLocked() {
16898        if (mUserManager == null) {
16899            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16900            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16901        }
16902        return mUserManager;
16903    }
16904
16905    private int applyUserId(int uid, int userId) {
16906        return UserHandle.getUid(userId, uid);
16907    }
16908
16909    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16910        if (info == null) return null;
16911        ApplicationInfo newInfo = new ApplicationInfo(info);
16912        newInfo.uid = applyUserId(info.uid, userId);
16913        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16914                + info.packageName;
16915        return newInfo;
16916    }
16917
16918    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16919        if (aInfo == null
16920                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16921            return aInfo;
16922        }
16923
16924        ActivityInfo info = new ActivityInfo(aInfo);
16925        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16926        return info;
16927    }
16928}
16929