ActivityManagerService.java revision 688b5105d665a56e6f2f040f3ca89ca3006801df
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                || app.treatLikeActivity;
2319        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2320        if (!activityChange && hasActivity) {
2321            // The process has activities, so we are only allowing activity-based adjustments
2322            // to move it.  It should be kept in the front of the list with other
2323            // processes that have activities, and we don't want those to change their
2324            // order except due to activity operations.
2325            return;
2326        }
2327
2328        mLruSeq++;
2329        final long now = SystemClock.uptimeMillis();
2330        app.lastActivityTime = now;
2331
2332        // First a quick reject: if the app is already at the position we will
2333        // put it, then there is nothing to do.
2334        if (hasActivity) {
2335            final int N = mLruProcesses.size();
2336            if (N > 0 && mLruProcesses.get(N-1) == app) {
2337                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2338                return;
2339            }
2340        } else {
2341            if (mLruProcessServiceStart > 0
2342                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2343                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2344                return;
2345            }
2346        }
2347
2348        int lrui = mLruProcesses.lastIndexOf(app);
2349
2350        if (app.persistent && lrui >= 0) {
2351            // We don't care about the position of persistent processes, as long as
2352            // they are in the list.
2353            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2354            return;
2355        }
2356
2357        /* In progress: compute new position first, so we can avoid doing work
2358           if the process is not actually going to move.  Not yet working.
2359        int addIndex;
2360        int nextIndex;
2361        boolean inActivity = false, inService = false;
2362        if (hasActivity) {
2363            // Process has activities, put it at the very tipsy-top.
2364            addIndex = mLruProcesses.size();
2365            nextIndex = mLruProcessServiceStart;
2366            inActivity = true;
2367        } else if (hasService) {
2368            // Process has services, put it at the top of the service list.
2369            addIndex = mLruProcessActivityStart;
2370            nextIndex = mLruProcessServiceStart;
2371            inActivity = true;
2372            inService = true;
2373        } else  {
2374            // Process not otherwise of interest, it goes to the top of the non-service area.
2375            addIndex = mLruProcessServiceStart;
2376            if (client != null) {
2377                int clientIndex = mLruProcesses.lastIndexOf(client);
2378                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2379                        + app);
2380                if (clientIndex >= 0 && addIndex > clientIndex) {
2381                    addIndex = clientIndex;
2382                }
2383            }
2384            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2385        }
2386
2387        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2388                + mLruProcessActivityStart + "): " + app);
2389        */
2390
2391        if (lrui >= 0) {
2392            if (lrui < mLruProcessActivityStart) {
2393                mLruProcessActivityStart--;
2394            }
2395            if (lrui < mLruProcessServiceStart) {
2396                mLruProcessServiceStart--;
2397            }
2398            /*
2399            if (addIndex > lrui) {
2400                addIndex--;
2401            }
2402            if (nextIndex > lrui) {
2403                nextIndex--;
2404            }
2405            */
2406            mLruProcesses.remove(lrui);
2407        }
2408
2409        /*
2410        mLruProcesses.add(addIndex, app);
2411        if (inActivity) {
2412            mLruProcessActivityStart++;
2413        }
2414        if (inService) {
2415            mLruProcessActivityStart++;
2416        }
2417        */
2418
2419        int nextIndex;
2420        if (hasActivity) {
2421            final int N = mLruProcesses.size();
2422            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2423                // Process doesn't have activities, but has clients with
2424                // activities...  move it up, but one below the top (the top
2425                // should always have a real activity).
2426                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2427                mLruProcesses.add(N-1, app);
2428                // To keep it from spamming the LRU list (by making a bunch of clients),
2429                // we will push down any other entries owned by the app.
2430                final int uid = app.info.uid;
2431                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2432                    ProcessRecord subProc = mLruProcesses.get(i);
2433                    if (subProc.info.uid == uid) {
2434                        // We want to push this one down the list.  If the process after
2435                        // it is for the same uid, however, don't do so, because we don't
2436                        // want them internally to be re-ordered.
2437                        if (mLruProcesses.get(i-1).info.uid != uid) {
2438                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2439                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2440                            ProcessRecord tmp = mLruProcesses.get(i);
2441                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2442                            mLruProcesses.set(i-1, tmp);
2443                            i--;
2444                        }
2445                    } else {
2446                        // A gap, we can stop here.
2447                        break;
2448                    }
2449                }
2450            } else {
2451                // Process has activities, put it at the very tipsy-top.
2452                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2453                mLruProcesses.add(app);
2454            }
2455            nextIndex = mLruProcessServiceStart;
2456        } else if (hasService) {
2457            // Process has services, put it at the top of the service list.
2458            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2459            mLruProcesses.add(mLruProcessActivityStart, app);
2460            nextIndex = mLruProcessServiceStart;
2461            mLruProcessActivityStart++;
2462        } else  {
2463            // Process not otherwise of interest, it goes to the top of the non-service area.
2464            int index = mLruProcessServiceStart;
2465            if (client != null) {
2466                // If there is a client, don't allow the process to be moved up higher
2467                // in the list than that client.
2468                int clientIndex = mLruProcesses.lastIndexOf(client);
2469                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2470                        + " when updating " + app);
2471                if (clientIndex <= lrui) {
2472                    // Don't allow the client index restriction to push it down farther in the
2473                    // list than it already is.
2474                    clientIndex = lrui;
2475                }
2476                if (clientIndex >= 0 && index > clientIndex) {
2477                    index = clientIndex;
2478                }
2479            }
2480            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2481            mLruProcesses.add(index, app);
2482            nextIndex = index-1;
2483            mLruProcessActivityStart++;
2484            mLruProcessServiceStart++;
2485        }
2486
2487        // If the app is currently using a content provider or service,
2488        // bump those processes as well.
2489        for (int j=app.connections.size()-1; j>=0; j--) {
2490            ConnectionRecord cr = app.connections.valueAt(j);
2491            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2492                    && cr.binding.service.app != null
2493                    && cr.binding.service.app.lruSeq != mLruSeq
2494                    && !cr.binding.service.app.persistent) {
2495                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2496                        "service connection", cr, app);
2497            }
2498        }
2499        for (int j=app.conProviders.size()-1; j>=0; j--) {
2500            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2501            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2502                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2503                        "provider reference", cpr, app);
2504            }
2505        }
2506    }
2507
2508    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2509        if (uid == Process.SYSTEM_UID) {
2510            // The system gets to run in any process.  If there are multiple
2511            // processes with the same uid, just pick the first (this
2512            // should never happen).
2513            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2514            if (procs == null) return null;
2515            final int N = procs.size();
2516            for (int i = 0; i < N; i++) {
2517                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2518            }
2519        }
2520        ProcessRecord proc = mProcessNames.get(processName, uid);
2521        if (false && proc != null && !keepIfLarge
2522                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2523                && proc.lastCachedPss >= 4000) {
2524            // Turn this condition on to cause killing to happen regularly, for testing.
2525            if (proc.baseProcessTracker != null) {
2526                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2527            }
2528            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2529                    + "k from cached");
2530        } else if (proc != null && !keepIfLarge
2531                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2532                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2533            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2534            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2535                if (proc.baseProcessTracker != null) {
2536                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2537                }
2538                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2539                        + "k from cached");
2540            }
2541        }
2542        return proc;
2543    }
2544
2545    void ensurePackageDexOpt(String packageName) {
2546        IPackageManager pm = AppGlobals.getPackageManager();
2547        try {
2548            if (pm.performDexOpt(packageName)) {
2549                mDidDexOpt = true;
2550            }
2551        } catch (RemoteException e) {
2552        }
2553    }
2554
2555    boolean isNextTransitionForward() {
2556        int transit = mWindowManager.getPendingAppTransition();
2557        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2558                || transit == AppTransition.TRANSIT_TASK_OPEN
2559                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2560    }
2561
2562    final ProcessRecord startProcessLocked(String processName,
2563            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2564            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2565            boolean isolated, boolean keepIfLarge) {
2566        ProcessRecord app;
2567        if (!isolated) {
2568            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2569        } else {
2570            // If this is an isolated process, it can't re-use an existing process.
2571            app = null;
2572        }
2573        // We don't have to do anything more if:
2574        // (1) There is an existing application record; and
2575        // (2) The caller doesn't think it is dead, OR there is no thread
2576        //     object attached to it so we know it couldn't have crashed; and
2577        // (3) There is a pid assigned to it, so it is either starting or
2578        //     already running.
2579        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2580                + " app=" + app + " knownToBeDead=" + knownToBeDead
2581                + " thread=" + (app != null ? app.thread : null)
2582                + " pid=" + (app != null ? app.pid : -1));
2583        if (app != null && app.pid > 0) {
2584            if (!knownToBeDead || app.thread == null) {
2585                // We already have the app running, or are waiting for it to
2586                // come up (we have a pid but not yet its thread), so keep it.
2587                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2588                // If this is a new package in the process, add the package to the list
2589                app.addPackage(info.packageName, mProcessStats);
2590                return app;
2591            }
2592
2593            // An application record is attached to a previous process,
2594            // clean it up now.
2595            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2596            handleAppDiedLocked(app, true, true);
2597        }
2598
2599        String hostingNameStr = hostingName != null
2600                ? hostingName.flattenToShortString() : null;
2601
2602        if (!isolated) {
2603            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2604                // If we are in the background, then check to see if this process
2605                // is bad.  If so, we will just silently fail.
2606                if (mBadProcesses.get(info.processName, info.uid) != null) {
2607                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2608                            + "/" + info.processName);
2609                    return null;
2610                }
2611            } else {
2612                // When the user is explicitly starting a process, then clear its
2613                // crash count so that we won't make it bad until they see at
2614                // least one crash dialog again, and make the process good again
2615                // if it had been bad.
2616                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2617                        + "/" + info.processName);
2618                mProcessCrashTimes.remove(info.processName, info.uid);
2619                if (mBadProcesses.get(info.processName, info.uid) != null) {
2620                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2621                            UserHandle.getUserId(info.uid), info.uid,
2622                            info.processName);
2623                    mBadProcesses.remove(info.processName, info.uid);
2624                    if (app != null) {
2625                        app.bad = false;
2626                    }
2627                }
2628            }
2629        }
2630
2631        if (app == null) {
2632            app = newProcessRecordLocked(info, processName, isolated);
2633            if (app == null) {
2634                Slog.w(TAG, "Failed making new process record for "
2635                        + processName + "/" + info.uid + " isolated=" + isolated);
2636                return null;
2637            }
2638            mProcessNames.put(processName, app.uid, app);
2639            if (isolated) {
2640                mIsolatedProcesses.put(app.uid, app);
2641            }
2642        } else {
2643            // If this is a new package in the process, add the package to the list
2644            app.addPackage(info.packageName, mProcessStats);
2645        }
2646
2647        // If the system is not ready yet, then hold off on starting this
2648        // process until it is.
2649        if (!mProcessesReady
2650                && !isAllowedWhileBooting(info)
2651                && !allowWhileBooting) {
2652            if (!mProcessesOnHold.contains(app)) {
2653                mProcessesOnHold.add(app);
2654            }
2655            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2656            return app;
2657        }
2658
2659        startProcessLocked(app, hostingType, hostingNameStr);
2660        return (app.pid != 0) ? app : null;
2661    }
2662
2663    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2664        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2665    }
2666
2667    private final void startProcessLocked(ProcessRecord app,
2668            String hostingType, String hostingNameStr) {
2669        if (app.pid > 0 && app.pid != MY_PID) {
2670            synchronized (mPidsSelfLocked) {
2671                mPidsSelfLocked.remove(app.pid);
2672                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2673            }
2674            app.setPid(0);
2675        }
2676
2677        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2678                "startProcessLocked removing on hold: " + app);
2679        mProcessesOnHold.remove(app);
2680
2681        updateCpuStats();
2682
2683        try {
2684            int uid = app.uid;
2685
2686            int[] gids = null;
2687            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2688            if (!app.isolated) {
2689                int[] permGids = null;
2690                try {
2691                    final PackageManager pm = mContext.getPackageManager();
2692                    permGids = pm.getPackageGids(app.info.packageName);
2693
2694                    if (Environment.isExternalStorageEmulated()) {
2695                        if (pm.checkPermission(
2696                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2697                                app.info.packageName) == PERMISSION_GRANTED) {
2698                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2699                        } else {
2700                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2701                        }
2702                    }
2703                } catch (PackageManager.NameNotFoundException e) {
2704                    Slog.w(TAG, "Unable to retrieve gids", e);
2705                }
2706
2707                /*
2708                 * Add shared application GID so applications can share some
2709                 * resources like shared libraries
2710                 */
2711                if (permGids == null) {
2712                    gids = new int[1];
2713                } else {
2714                    gids = new int[permGids.length + 1];
2715                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2716                }
2717                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2718            }
2719            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2720                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2721                        && mTopComponent != null
2722                        && app.processName.equals(mTopComponent.getPackageName())) {
2723                    uid = 0;
2724                }
2725                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2726                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2727                    uid = 0;
2728                }
2729            }
2730            int debugFlags = 0;
2731            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2732                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2733                // Also turn on CheckJNI for debuggable apps. It's quite
2734                // awkward to turn on otherwise.
2735                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2736            }
2737            // Run the app in safe mode if its manifest requests so or the
2738            // system is booted in safe mode.
2739            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2740                Zygote.systemInSafeMode == true) {
2741                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2742            }
2743            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2744                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2745            }
2746            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2747                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2748            }
2749            if ("1".equals(SystemProperties.get("debug.assert"))) {
2750                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2751            }
2752
2753            // Start the process.  It will either succeed and return a result containing
2754            // the PID of the new process, or else throw a RuntimeException.
2755            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2756                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2757                    app.info.targetSdkVersion, app.info.seinfo, null);
2758
2759            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2760            synchronized (bs) {
2761                if (bs.isOnBattery()) {
2762                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2763                }
2764            }
2765
2766            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2767                    UserHandle.getUserId(uid), startResult.pid, uid,
2768                    app.processName, hostingType,
2769                    hostingNameStr != null ? hostingNameStr : "");
2770
2771            if (app.persistent) {
2772                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2773            }
2774
2775            StringBuilder buf = mStringBuilder;
2776            buf.setLength(0);
2777            buf.append("Start proc ");
2778            buf.append(app.processName);
2779            buf.append(" for ");
2780            buf.append(hostingType);
2781            if (hostingNameStr != null) {
2782                buf.append(" ");
2783                buf.append(hostingNameStr);
2784            }
2785            buf.append(": pid=");
2786            buf.append(startResult.pid);
2787            buf.append(" uid=");
2788            buf.append(uid);
2789            buf.append(" gids={");
2790            if (gids != null) {
2791                for (int gi=0; gi<gids.length; gi++) {
2792                    if (gi != 0) buf.append(", ");
2793                    buf.append(gids[gi]);
2794
2795                }
2796            }
2797            buf.append("}");
2798            Slog.i(TAG, buf.toString());
2799            app.setPid(startResult.pid);
2800            app.usingWrapper = startResult.usingWrapper;
2801            app.removed = false;
2802            synchronized (mPidsSelfLocked) {
2803                this.mPidsSelfLocked.put(startResult.pid, app);
2804                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2805                msg.obj = app;
2806                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2807                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2808            }
2809            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2810                    app.processName, app.info.uid);
2811            if (app.isolated) {
2812                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2813            }
2814        } catch (RuntimeException e) {
2815            // XXX do better error recovery.
2816            app.setPid(0);
2817            Slog.e(TAG, "Failure starting process " + app.processName, e);
2818        }
2819    }
2820
2821    void updateUsageStats(ActivityRecord component, boolean resumed) {
2822        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2823        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2824        if (resumed) {
2825            mUsageStatsService.noteResumeComponent(component.realActivity);
2826            synchronized (stats) {
2827                stats.noteActivityResumedLocked(component.app.uid);
2828            }
2829        } else {
2830            mUsageStatsService.notePauseComponent(component.realActivity);
2831            synchronized (stats) {
2832                stats.noteActivityPausedLocked(component.app.uid);
2833            }
2834        }
2835    }
2836
2837    Intent getHomeIntent() {
2838        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2839        intent.setComponent(mTopComponent);
2840        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2841            intent.addCategory(Intent.CATEGORY_HOME);
2842        }
2843        return intent;
2844    }
2845
2846    boolean startHomeActivityLocked(int userId) {
2847        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2848                && mTopAction == null) {
2849            // We are running in factory test mode, but unable to find
2850            // the factory test app, so just sit around displaying the
2851            // error message and don't try to start anything.
2852            return false;
2853        }
2854        Intent intent = getHomeIntent();
2855        ActivityInfo aInfo =
2856            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2857        if (aInfo != null) {
2858            intent.setComponent(new ComponentName(
2859                    aInfo.applicationInfo.packageName, aInfo.name));
2860            // Don't do this if the home app is currently being
2861            // instrumented.
2862            aInfo = new ActivityInfo(aInfo);
2863            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2864            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2865                    aInfo.applicationInfo.uid, true);
2866            if (app == null || app.instrumentationClass == null) {
2867                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2868                mStackSupervisor.startHomeActivity(intent, aInfo);
2869            }
2870        }
2871
2872        return true;
2873    }
2874
2875    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2876        ActivityInfo ai = null;
2877        ComponentName comp = intent.getComponent();
2878        try {
2879            if (comp != null) {
2880                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2881            } else {
2882                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2883                        intent,
2884                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2885                            flags, userId);
2886
2887                if (info != null) {
2888                    ai = info.activityInfo;
2889                }
2890            }
2891        } catch (RemoteException e) {
2892            // ignore
2893        }
2894
2895        return ai;
2896    }
2897
2898    /**
2899     * Starts the "new version setup screen" if appropriate.
2900     */
2901    void startSetupActivityLocked() {
2902        // Only do this once per boot.
2903        if (mCheckedForSetup) {
2904            return;
2905        }
2906
2907        // We will show this screen if the current one is a different
2908        // version than the last one shown, and we are not running in
2909        // low-level factory test mode.
2910        final ContentResolver resolver = mContext.getContentResolver();
2911        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2912                Settings.Global.getInt(resolver,
2913                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2914            mCheckedForSetup = true;
2915
2916            // See if we should be showing the platform update setup UI.
2917            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2918            List<ResolveInfo> ris = mContext.getPackageManager()
2919                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2920
2921            // We don't allow third party apps to replace this.
2922            ResolveInfo ri = null;
2923            for (int i=0; ris != null && i<ris.size(); i++) {
2924                if ((ris.get(i).activityInfo.applicationInfo.flags
2925                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2926                    ri = ris.get(i);
2927                    break;
2928                }
2929            }
2930
2931            if (ri != null) {
2932                String vers = ri.activityInfo.metaData != null
2933                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2934                        : null;
2935                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2936                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2937                            Intent.METADATA_SETUP_VERSION);
2938                }
2939                String lastVers = Settings.Secure.getString(
2940                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2941                if (vers != null && !vers.equals(lastVers)) {
2942                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2943                    intent.setComponent(new ComponentName(
2944                            ri.activityInfo.packageName, ri.activityInfo.name));
2945                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2946                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2947                }
2948            }
2949        }
2950    }
2951
2952    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2953        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2954    }
2955
2956    void enforceNotIsolatedCaller(String caller) {
2957        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2958            throw new SecurityException("Isolated process not allowed to call " + caller);
2959        }
2960    }
2961
2962    @Override
2963    public int getFrontActivityScreenCompatMode() {
2964        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2965        synchronized (this) {
2966            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2967        }
2968    }
2969
2970    @Override
2971    public void setFrontActivityScreenCompatMode(int mode) {
2972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2973                "setFrontActivityScreenCompatMode");
2974        synchronized (this) {
2975            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2976        }
2977    }
2978
2979    @Override
2980    public int getPackageScreenCompatMode(String packageName) {
2981        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2982        synchronized (this) {
2983            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2984        }
2985    }
2986
2987    @Override
2988    public void setPackageScreenCompatMode(String packageName, int mode) {
2989        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2990                "setPackageScreenCompatMode");
2991        synchronized (this) {
2992            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2993        }
2994    }
2995
2996    @Override
2997    public boolean getPackageAskScreenCompat(String packageName) {
2998        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2999        synchronized (this) {
3000            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3001        }
3002    }
3003
3004    @Override
3005    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3006        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3007                "setPackageAskScreenCompat");
3008        synchronized (this) {
3009            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3010        }
3011    }
3012
3013    private void dispatchProcessesChanged() {
3014        int N;
3015        synchronized (this) {
3016            N = mPendingProcessChanges.size();
3017            if (mActiveProcessChanges.length < N) {
3018                mActiveProcessChanges = new ProcessChangeItem[N];
3019            }
3020            mPendingProcessChanges.toArray(mActiveProcessChanges);
3021            mAvailProcessChanges.addAll(mPendingProcessChanges);
3022            mPendingProcessChanges.clear();
3023            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3024        }
3025
3026        int i = mProcessObservers.beginBroadcast();
3027        while (i > 0) {
3028            i--;
3029            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3030            if (observer != null) {
3031                try {
3032                    for (int j=0; j<N; j++) {
3033                        ProcessChangeItem item = mActiveProcessChanges[j];
3034                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3035                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3036                                    + item.pid + " uid=" + item.uid + ": "
3037                                    + item.foregroundActivities);
3038                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3039                                    item.foregroundActivities);
3040                        }
3041                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3042                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3043                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3044                            observer.onImportanceChanged(item.pid, item.uid,
3045                                    item.importance);
3046                        }
3047                    }
3048                } catch (RemoteException e) {
3049                }
3050            }
3051        }
3052        mProcessObservers.finishBroadcast();
3053    }
3054
3055    private void dispatchProcessDied(int pid, int uid) {
3056        int i = mProcessObservers.beginBroadcast();
3057        while (i > 0) {
3058            i--;
3059            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3060            if (observer != null) {
3061                try {
3062                    observer.onProcessDied(pid, uid);
3063                } catch (RemoteException e) {
3064                }
3065            }
3066        }
3067        mProcessObservers.finishBroadcast();
3068    }
3069
3070    final void doPendingActivityLaunchesLocked(boolean doResume) {
3071        final int N = mPendingActivityLaunches.size();
3072        if (N <= 0) {
3073            return;
3074        }
3075        for (int i=0; i<N; i++) {
3076            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3077            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3078                    doResume && i == (N-1), null);
3079        }
3080        mPendingActivityLaunches.clear();
3081    }
3082
3083    @Override
3084    public final int startActivity(IApplicationThread caller, String callingPackage,
3085            Intent intent, String resolvedType, IBinder resultTo,
3086            String resultWho, int requestCode, int startFlags,
3087            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3088        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3089                resultWho, requestCode,
3090                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3091    }
3092
3093    @Override
3094    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3095            Intent intent, String resolvedType, IBinder resultTo,
3096            String resultWho, int requestCode, int startFlags,
3097            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3098        enforceNotIsolatedCaller("startActivity");
3099        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3100                false, true, "startActivity", null);
3101        // TODO: Switch to user app stacks here.
3102        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3103                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3104                null, null, options, userId, null);
3105    }
3106
3107    @Override
3108    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3109            Intent intent, String resolvedType, IBinder resultTo,
3110            String resultWho, int requestCode, int startFlags, String profileFile,
3111            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3112        enforceNotIsolatedCaller("startActivityAndWait");
3113        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3114                false, true, "startActivityAndWait", null);
3115        WaitResult res = new WaitResult();
3116        // TODO: Switch to user app stacks here.
3117        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3118                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3119                res, null, options, UserHandle.getCallingUserId(), null);
3120        return res;
3121    }
3122
3123    @Override
3124    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3125            Intent intent, String resolvedType, IBinder resultTo,
3126            String resultWho, int requestCode, int startFlags, Configuration config,
3127            Bundle options, int userId) {
3128        enforceNotIsolatedCaller("startActivityWithConfig");
3129        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3130                false, true, "startActivityWithConfig", null);
3131        // TODO: Switch to user app stacks here.
3132        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3133                resolvedType, resultTo, resultWho, requestCode, startFlags,
3134                null, null, null, config, options, userId, null);
3135        return ret;
3136    }
3137
3138    @Override
3139    public int startActivityIntentSender(IApplicationThread caller,
3140            IntentSender intent, Intent fillInIntent, String resolvedType,
3141            IBinder resultTo, String resultWho, int requestCode,
3142            int flagsMask, int flagsValues, Bundle options) {
3143        enforceNotIsolatedCaller("startActivityIntentSender");
3144        // Refuse possible leaked file descriptors
3145        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3146            throw new IllegalArgumentException("File descriptors passed in Intent");
3147        }
3148
3149        IIntentSender sender = intent.getTarget();
3150        if (!(sender instanceof PendingIntentRecord)) {
3151            throw new IllegalArgumentException("Bad PendingIntent object");
3152        }
3153
3154        PendingIntentRecord pir = (PendingIntentRecord)sender;
3155
3156        synchronized (this) {
3157            // If this is coming from the currently resumed activity, it is
3158            // effectively saying that app switches are allowed at this point.
3159            final ActivityStack stack = getFocusedStack();
3160            if (stack.mResumedActivity != null &&
3161                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3162                mAppSwitchesAllowedTime = 0;
3163            }
3164        }
3165        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3166                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3167        return ret;
3168    }
3169
3170    @Override
3171    public boolean startNextMatchingActivity(IBinder callingActivity,
3172            Intent intent, Bundle options) {
3173        // Refuse possible leaked file descriptors
3174        if (intent != null && intent.hasFileDescriptors() == true) {
3175            throw new IllegalArgumentException("File descriptors passed in Intent");
3176        }
3177
3178        synchronized (this) {
3179            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3180            if (r == null) {
3181                ActivityOptions.abort(options);
3182                return false;
3183            }
3184            if (r.app == null || r.app.thread == null) {
3185                // The caller is not running...  d'oh!
3186                ActivityOptions.abort(options);
3187                return false;
3188            }
3189            intent = new Intent(intent);
3190            // The caller is not allowed to change the data.
3191            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3192            // And we are resetting to find the next component...
3193            intent.setComponent(null);
3194
3195            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3196
3197            ActivityInfo aInfo = null;
3198            try {
3199                List<ResolveInfo> resolves =
3200                    AppGlobals.getPackageManager().queryIntentActivities(
3201                            intent, r.resolvedType,
3202                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3203                            UserHandle.getCallingUserId());
3204
3205                // Look for the original activity in the list...
3206                final int N = resolves != null ? resolves.size() : 0;
3207                for (int i=0; i<N; i++) {
3208                    ResolveInfo rInfo = resolves.get(i);
3209                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3210                            && rInfo.activityInfo.name.equals(r.info.name)) {
3211                        // We found the current one...  the next matching is
3212                        // after it.
3213                        i++;
3214                        if (i<N) {
3215                            aInfo = resolves.get(i).activityInfo;
3216                        }
3217                        if (debug) {
3218                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3219                                    + "/" + r.info.name);
3220                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3221                                    + "/" + aInfo.name);
3222                        }
3223                        break;
3224                    }
3225                }
3226            } catch (RemoteException e) {
3227            }
3228
3229            if (aInfo == null) {
3230                // Nobody who is next!
3231                ActivityOptions.abort(options);
3232                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3233                return false;
3234            }
3235
3236            intent.setComponent(new ComponentName(
3237                    aInfo.applicationInfo.packageName, aInfo.name));
3238            intent.setFlags(intent.getFlags()&~(
3239                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3240                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3241                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3242                    Intent.FLAG_ACTIVITY_NEW_TASK));
3243
3244            // Okay now we need to start the new activity, replacing the
3245            // currently running activity.  This is a little tricky because
3246            // we want to start the new one as if the current one is finished,
3247            // but not finish the current one first so that there is no flicker.
3248            // And thus...
3249            final boolean wasFinishing = r.finishing;
3250            r.finishing = true;
3251
3252            // Propagate reply information over to the new activity.
3253            final ActivityRecord resultTo = r.resultTo;
3254            final String resultWho = r.resultWho;
3255            final int requestCode = r.requestCode;
3256            r.resultTo = null;
3257            if (resultTo != null) {
3258                resultTo.removeResultsLocked(r, resultWho, requestCode);
3259            }
3260
3261            final long origId = Binder.clearCallingIdentity();
3262            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3263                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3264                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3265                    options, false, null, null);
3266            Binder.restoreCallingIdentity(origId);
3267
3268            r.finishing = wasFinishing;
3269            if (res != ActivityManager.START_SUCCESS) {
3270                return false;
3271            }
3272            return true;
3273        }
3274    }
3275
3276    final int startActivityInPackage(int uid, String callingPackage,
3277            Intent intent, String resolvedType, IBinder resultTo,
3278            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3279                    IActivityContainer container) {
3280
3281        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3282                false, true, "startActivityInPackage", null);
3283
3284        // TODO: Switch to user app stacks here.
3285        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3286                resultTo, resultWho, requestCode, startFlags,
3287                null, null, null, null, options, userId, container);
3288        return ret;
3289    }
3290
3291    @Override
3292    public final int startActivities(IApplicationThread caller, String callingPackage,
3293            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3294            int userId) {
3295        enforceNotIsolatedCaller("startActivities");
3296        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3297                false, true, "startActivity", null);
3298        // TODO: Switch to user app stacks here.
3299        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3300                resolvedTypes, resultTo, options, userId);
3301        return ret;
3302    }
3303
3304    final int startActivitiesInPackage(int uid, String callingPackage,
3305            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3306            Bundle options, int userId) {
3307
3308        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3309                false, true, "startActivityInPackage", null);
3310        // TODO: Switch to user app stacks here.
3311        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3312                resultTo, options, userId);
3313        return ret;
3314    }
3315
3316    final void addRecentTaskLocked(TaskRecord task) {
3317        int N = mRecentTasks.size();
3318        // Quick case: check if the top-most recent task is the same.
3319        if (N > 0 && mRecentTasks.get(0) == task) {
3320            return;
3321        }
3322        // Remove any existing entries that are the same kind of task.
3323        final Intent intent = task.intent;
3324        final boolean document = intent != null && intent.isDocument();
3325        for (int i=0; i<N; i++) {
3326            TaskRecord tr = mRecentTasks.get(i);
3327            if (task != tr) {
3328                if (task.userId != tr.userId) {
3329                    continue;
3330                }
3331                final Intent trIntent = tr.intent;
3332                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3333                    (intent == null || !intent.filterEquals(trIntent))) {
3334                    continue;
3335                }
3336                if (document || trIntent != null && trIntent.isDocument()) {
3337                    // Document tasks do not match other tasks.
3338                    continue;
3339                }
3340            }
3341
3342            // Either task and tr are the same or, their affinities match or their intents match
3343            // and neither of them is a document.
3344            tr.disposeThumbnail();
3345            mRecentTasks.remove(i);
3346            i--;
3347            N--;
3348            if (task.intent == null) {
3349                // If the new recent task we are adding is not fully
3350                // specified, then replace it with the existing recent task.
3351                task = tr;
3352            }
3353        }
3354        if (N >= MAX_RECENT_TASKS) {
3355            mRecentTasks.remove(N-1).disposeThumbnail();
3356        }
3357        mRecentTasks.add(0, task);
3358    }
3359
3360    @Override
3361    public void reportActivityFullyDrawn(IBinder token) {
3362        synchronized (this) {
3363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3364            if (r == null) {
3365                return;
3366            }
3367            r.reportFullyDrawnLocked();
3368        }
3369    }
3370
3371    @Override
3372    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3373        synchronized (this) {
3374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3375            if (r == null) {
3376                return;
3377            }
3378            final long origId = Binder.clearCallingIdentity();
3379            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3380            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3381                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3382            if (config != null) {
3383                r.frozenBeforeDestroy = true;
3384                if (!updateConfigurationLocked(config, r, false, false)) {
3385                    mStackSupervisor.resumeTopActivitiesLocked();
3386                }
3387            }
3388            Binder.restoreCallingIdentity(origId);
3389        }
3390    }
3391
3392    @Override
3393    public int getRequestedOrientation(IBinder token) {
3394        synchronized (this) {
3395            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3396            if (r == null) {
3397                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3398            }
3399            return mWindowManager.getAppOrientation(r.appToken);
3400        }
3401    }
3402
3403    /**
3404     * This is the internal entry point for handling Activity.finish().
3405     *
3406     * @param token The Binder token referencing the Activity we want to finish.
3407     * @param resultCode Result code, if any, from this Activity.
3408     * @param resultData Result data (Intent), if any, from this Activity.
3409     *
3410     * @return Returns true if the activity successfully finished, or false if it is still running.
3411     */
3412    @Override
3413    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3414        // Refuse possible leaked file descriptors
3415        if (resultData != null && resultData.hasFileDescriptors() == true) {
3416            throw new IllegalArgumentException("File descriptors passed in Intent");
3417        }
3418
3419        synchronized(this) {
3420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3421            if (r == null) {
3422                return true;
3423            }
3424            if (mController != null) {
3425                // Find the first activity that is not finishing.
3426                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3427                if (next != null) {
3428                    // ask watcher if this is allowed
3429                    boolean resumeOK = true;
3430                    try {
3431                        resumeOK = mController.activityResuming(next.packageName);
3432                    } catch (RemoteException e) {
3433                        mController = null;
3434                        Watchdog.getInstance().setActivityController(null);
3435                    }
3436
3437                    if (!resumeOK) {
3438                        return false;
3439                    }
3440                }
3441            }
3442            final long origId = Binder.clearCallingIdentity();
3443            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3444                    resultData, "app-request", true);
3445            Binder.restoreCallingIdentity(origId);
3446            return res;
3447        }
3448    }
3449
3450    @Override
3451    public final void finishHeavyWeightApp() {
3452        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3453                != PackageManager.PERMISSION_GRANTED) {
3454            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3455                    + Binder.getCallingPid()
3456                    + ", uid=" + Binder.getCallingUid()
3457                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3458            Slog.w(TAG, msg);
3459            throw new SecurityException(msg);
3460        }
3461
3462        synchronized(this) {
3463            if (mHeavyWeightProcess == null) {
3464                return;
3465            }
3466
3467            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3468                    mHeavyWeightProcess.activities);
3469            for (int i=0; i<activities.size(); i++) {
3470                ActivityRecord r = activities.get(i);
3471                if (!r.finishing) {
3472                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3473                            null, "finish-heavy", true);
3474                }
3475            }
3476
3477            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3478                    mHeavyWeightProcess.userId, 0));
3479            mHeavyWeightProcess = null;
3480        }
3481    }
3482
3483    @Override
3484    public void crashApplication(int uid, int initialPid, String packageName,
3485            String message) {
3486        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3487                != PackageManager.PERMISSION_GRANTED) {
3488            String msg = "Permission Denial: crashApplication() from pid="
3489                    + Binder.getCallingPid()
3490                    + ", uid=" + Binder.getCallingUid()
3491                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3492            Slog.w(TAG, msg);
3493            throw new SecurityException(msg);
3494        }
3495
3496        synchronized(this) {
3497            ProcessRecord proc = null;
3498
3499            // Figure out which process to kill.  We don't trust that initialPid
3500            // still has any relation to current pids, so must scan through the
3501            // list.
3502            synchronized (mPidsSelfLocked) {
3503                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3504                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3505                    if (p.uid != uid) {
3506                        continue;
3507                    }
3508                    if (p.pid == initialPid) {
3509                        proc = p;
3510                        break;
3511                    }
3512                    if (p.pkgList.containsKey(packageName)) {
3513                        proc = p;
3514                    }
3515                }
3516            }
3517
3518            if (proc == null) {
3519                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3520                        + " initialPid=" + initialPid
3521                        + " packageName=" + packageName);
3522                return;
3523            }
3524
3525            if (proc.thread != null) {
3526                if (proc.pid == Process.myPid()) {
3527                    Log.w(TAG, "crashApplication: trying to crash self!");
3528                    return;
3529                }
3530                long ident = Binder.clearCallingIdentity();
3531                try {
3532                    proc.thread.scheduleCrash(message);
3533                } catch (RemoteException e) {
3534                }
3535                Binder.restoreCallingIdentity(ident);
3536            }
3537        }
3538    }
3539
3540    @Override
3541    public final void finishSubActivity(IBinder token, String resultWho,
3542            int requestCode) {
3543        synchronized(this) {
3544            final long origId = Binder.clearCallingIdentity();
3545            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3546            if (r != null) {
3547                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3548            }
3549            Binder.restoreCallingIdentity(origId);
3550        }
3551    }
3552
3553    @Override
3554    public boolean finishActivityAffinity(IBinder token) {
3555        synchronized(this) {
3556            final long origId = Binder.clearCallingIdentity();
3557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3558            boolean res = false;
3559            if (r != null) {
3560                res = r.task.stack.finishActivityAffinityLocked(r);
3561            }
3562            Binder.restoreCallingIdentity(origId);
3563            return res;
3564        }
3565    }
3566
3567    @Override
3568    public boolean willActivityBeVisible(IBinder token) {
3569        synchronized(this) {
3570            ActivityStack stack = ActivityRecord.getStackLocked(token);
3571            if (stack != null) {
3572                return stack.willActivityBeVisibleLocked(token);
3573            }
3574            return false;
3575        }
3576    }
3577
3578    @Override
3579    public void overridePendingTransition(IBinder token, String packageName,
3580            int enterAnim, int exitAnim) {
3581        synchronized(this) {
3582            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3583            if (self == null) {
3584                return;
3585            }
3586
3587            final long origId = Binder.clearCallingIdentity();
3588
3589            if (self.state == ActivityState.RESUMED
3590                    || self.state == ActivityState.PAUSING) {
3591                mWindowManager.overridePendingAppTransition(packageName,
3592                        enterAnim, exitAnim, null);
3593            }
3594
3595            Binder.restoreCallingIdentity(origId);
3596        }
3597    }
3598
3599    /**
3600     * Main function for removing an existing process from the activity manager
3601     * as a result of that process going away.  Clears out all connections
3602     * to the process.
3603     */
3604    private final void handleAppDiedLocked(ProcessRecord app,
3605            boolean restarting, boolean allowRestart) {
3606        int pid = app.pid;
3607        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3608        if (!restarting) {
3609            removeLruProcessLocked(app);
3610            if (pid > 0) {
3611                ProcessList.remove(pid);
3612            }
3613        }
3614
3615        if (mProfileProc == app) {
3616            clearProfilerLocked();
3617        }
3618
3619        // Remove this application's activities from active lists.
3620        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3621
3622        app.activities.clear();
3623
3624        if (app.instrumentationClass != null) {
3625            Slog.w(TAG, "Crash of app " + app.processName
3626                  + " running instrumentation " + app.instrumentationClass);
3627            Bundle info = new Bundle();
3628            info.putString("shortMsg", "Process crashed.");
3629            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3630        }
3631
3632        if (!restarting) {
3633            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3634                // If there was nothing to resume, and we are not already
3635                // restarting this process, but there is a visible activity that
3636                // is hosted by the process...  then make sure all visible
3637                // activities are running, taking care of restarting this
3638                // process.
3639                if (hasVisibleActivities) {
3640                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3641                }
3642            }
3643        }
3644    }
3645
3646    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3647        IBinder threadBinder = thread.asBinder();
3648        // Find the application record.
3649        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3650            ProcessRecord rec = mLruProcesses.get(i);
3651            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3652                return i;
3653            }
3654        }
3655        return -1;
3656    }
3657
3658    final ProcessRecord getRecordForAppLocked(
3659            IApplicationThread thread) {
3660        if (thread == null) {
3661            return null;
3662        }
3663
3664        int appIndex = getLRURecordIndexForAppLocked(thread);
3665        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3666    }
3667
3668    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3669        // If there are no longer any background processes running,
3670        // and the app that died was not running instrumentation,
3671        // then tell everyone we are now low on memory.
3672        boolean haveBg = false;
3673        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3674            ProcessRecord rec = mLruProcesses.get(i);
3675            if (rec.thread != null
3676                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3677                haveBg = true;
3678                break;
3679            }
3680        }
3681
3682        if (!haveBg) {
3683            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3684            if (doReport) {
3685                long now = SystemClock.uptimeMillis();
3686                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3687                    doReport = false;
3688                } else {
3689                    mLastMemUsageReportTime = now;
3690                }
3691            }
3692            final ArrayList<ProcessMemInfo> memInfos
3693                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3694            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3695            long now = SystemClock.uptimeMillis();
3696            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3697                ProcessRecord rec = mLruProcesses.get(i);
3698                if (rec == dyingProc || rec.thread == null) {
3699                    continue;
3700                }
3701                if (doReport) {
3702                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3703                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3704                }
3705                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3706                    // The low memory report is overriding any current
3707                    // state for a GC request.  Make sure to do
3708                    // heavy/important/visible/foreground processes first.
3709                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3710                        rec.lastRequestedGc = 0;
3711                    } else {
3712                        rec.lastRequestedGc = rec.lastLowMemory;
3713                    }
3714                    rec.reportLowMemory = true;
3715                    rec.lastLowMemory = now;
3716                    mProcessesToGc.remove(rec);
3717                    addProcessToGcListLocked(rec);
3718                }
3719            }
3720            if (doReport) {
3721                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3722                mHandler.sendMessage(msg);
3723            }
3724            scheduleAppGcsLocked();
3725        }
3726    }
3727
3728    final void appDiedLocked(ProcessRecord app, int pid,
3729            IApplicationThread thread) {
3730
3731        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3732        synchronized (stats) {
3733            stats.noteProcessDiedLocked(app.info.uid, pid);
3734        }
3735
3736        // Clean up already done if the process has been re-started.
3737        if (app.pid == pid && app.thread != null &&
3738                app.thread.asBinder() == thread.asBinder()) {
3739            boolean doLowMem = app.instrumentationClass == null;
3740            boolean doOomAdj = doLowMem;
3741            if (!app.killedByAm) {
3742                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3743                        + ") has died.");
3744                mAllowLowerMemLevel = true;
3745            } else {
3746                // Note that we always want to do oom adj to update our state with the
3747                // new number of procs.
3748                mAllowLowerMemLevel = false;
3749                doLowMem = false;
3750            }
3751            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3752            if (DEBUG_CLEANUP) Slog.v(
3753                TAG, "Dying app: " + app + ", pid: " + pid
3754                + ", thread: " + thread.asBinder());
3755            handleAppDiedLocked(app, false, true);
3756
3757            if (doOomAdj) {
3758                updateOomAdjLocked();
3759            }
3760            if (doLowMem) {
3761                doLowMemReportIfNeededLocked(app);
3762            }
3763        } else if (app.pid != pid) {
3764            // A new process has already been started.
3765            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3766                    + ") has died and restarted (pid " + app.pid + ").");
3767            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3768        } else if (DEBUG_PROCESSES) {
3769            Slog.d(TAG, "Received spurious death notification for thread "
3770                    + thread.asBinder());
3771        }
3772    }
3773
3774    /**
3775     * If a stack trace dump file is configured, dump process stack traces.
3776     * @param clearTraces causes the dump file to be erased prior to the new
3777     *    traces being written, if true; when false, the new traces will be
3778     *    appended to any existing file content.
3779     * @param firstPids of dalvik VM processes to dump stack traces for first
3780     * @param lastPids of dalvik VM processes to dump stack traces for last
3781     * @param nativeProcs optional list of native process names to dump stack crawls
3782     * @return file containing stack traces, or null if no dump file is configured
3783     */
3784    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3785            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3786        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3787        if (tracesPath == null || tracesPath.length() == 0) {
3788            return null;
3789        }
3790
3791        File tracesFile = new File(tracesPath);
3792        try {
3793            File tracesDir = tracesFile.getParentFile();
3794            if (!tracesDir.exists()) {
3795                tracesFile.mkdirs();
3796                if (!SELinux.restorecon(tracesDir)) {
3797                    return null;
3798                }
3799            }
3800            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3801
3802            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3803            tracesFile.createNewFile();
3804            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3805        } catch (IOException e) {
3806            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3807            return null;
3808        }
3809
3810        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3811        return tracesFile;
3812    }
3813
3814    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3815            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3816        // Use a FileObserver to detect when traces finish writing.
3817        // The order of traces is considered important to maintain for legibility.
3818        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3819            @Override
3820            public synchronized void onEvent(int event, String path) { notify(); }
3821        };
3822
3823        try {
3824            observer.startWatching();
3825
3826            // First collect all of the stacks of the most important pids.
3827            if (firstPids != null) {
3828                try {
3829                    int num = firstPids.size();
3830                    for (int i = 0; i < num; i++) {
3831                        synchronized (observer) {
3832                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3833                            observer.wait(200);  // Wait for write-close, give up after 200msec
3834                        }
3835                    }
3836                } catch (InterruptedException e) {
3837                    Log.wtf(TAG, e);
3838                }
3839            }
3840
3841            // Next collect the stacks of the native pids
3842            if (nativeProcs != null) {
3843                int[] pids = Process.getPidsForCommands(nativeProcs);
3844                if (pids != null) {
3845                    for (int pid : pids) {
3846                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3847                    }
3848                }
3849            }
3850
3851            // Lastly, measure CPU usage.
3852            if (processCpuTracker != null) {
3853                processCpuTracker.init();
3854                System.gc();
3855                processCpuTracker.update();
3856                try {
3857                    synchronized (processCpuTracker) {
3858                        processCpuTracker.wait(500); // measure over 1/2 second.
3859                    }
3860                } catch (InterruptedException e) {
3861                }
3862                processCpuTracker.update();
3863
3864                // We'll take the stack crawls of just the top apps using CPU.
3865                final int N = processCpuTracker.countWorkingStats();
3866                int numProcs = 0;
3867                for (int i=0; i<N && numProcs<5; i++) {
3868                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3869                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3870                        numProcs++;
3871                        try {
3872                            synchronized (observer) {
3873                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3874                                observer.wait(200);  // Wait for write-close, give up after 200msec
3875                            }
3876                        } catch (InterruptedException e) {
3877                            Log.wtf(TAG, e);
3878                        }
3879
3880                    }
3881                }
3882            }
3883        } finally {
3884            observer.stopWatching();
3885        }
3886    }
3887
3888    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3889        if (true || IS_USER_BUILD) {
3890            return;
3891        }
3892        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3893        if (tracesPath == null || tracesPath.length() == 0) {
3894            return;
3895        }
3896
3897        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3898        StrictMode.allowThreadDiskWrites();
3899        try {
3900            final File tracesFile = new File(tracesPath);
3901            final File tracesDir = tracesFile.getParentFile();
3902            final File tracesTmp = new File(tracesDir, "__tmp__");
3903            try {
3904                if (!tracesDir.exists()) {
3905                    tracesFile.mkdirs();
3906                    if (!SELinux.restorecon(tracesDir.getPath())) {
3907                        return;
3908                    }
3909                }
3910                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3911
3912                if (tracesFile.exists()) {
3913                    tracesTmp.delete();
3914                    tracesFile.renameTo(tracesTmp);
3915                }
3916                StringBuilder sb = new StringBuilder();
3917                Time tobj = new Time();
3918                tobj.set(System.currentTimeMillis());
3919                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3920                sb.append(": ");
3921                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3922                sb.append(" since ");
3923                sb.append(msg);
3924                FileOutputStream fos = new FileOutputStream(tracesFile);
3925                fos.write(sb.toString().getBytes());
3926                if (app == null) {
3927                    fos.write("\n*** No application process!".getBytes());
3928                }
3929                fos.close();
3930                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3931            } catch (IOException e) {
3932                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3933                return;
3934            }
3935
3936            if (app != null) {
3937                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3938                firstPids.add(app.pid);
3939                dumpStackTraces(tracesPath, firstPids, null, null, null);
3940            }
3941
3942            File lastTracesFile = null;
3943            File curTracesFile = null;
3944            for (int i=9; i>=0; i--) {
3945                String name = String.format(Locale.US, "slow%02d.txt", i);
3946                curTracesFile = new File(tracesDir, name);
3947                if (curTracesFile.exists()) {
3948                    if (lastTracesFile != null) {
3949                        curTracesFile.renameTo(lastTracesFile);
3950                    } else {
3951                        curTracesFile.delete();
3952                    }
3953                }
3954                lastTracesFile = curTracesFile;
3955            }
3956            tracesFile.renameTo(curTracesFile);
3957            if (tracesTmp.exists()) {
3958                tracesTmp.renameTo(tracesFile);
3959            }
3960        } finally {
3961            StrictMode.setThreadPolicy(oldPolicy);
3962        }
3963    }
3964
3965    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3966            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3967        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3968        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3969
3970        if (mController != null) {
3971            try {
3972                // 0 == continue, -1 = kill process immediately
3973                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3974                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3975            } catch (RemoteException e) {
3976                mController = null;
3977                Watchdog.getInstance().setActivityController(null);
3978            }
3979        }
3980
3981        long anrTime = SystemClock.uptimeMillis();
3982        if (MONITOR_CPU_USAGE) {
3983            updateCpuStatsNow();
3984        }
3985
3986        synchronized (this) {
3987            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3988            if (mShuttingDown) {
3989                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3990                return;
3991            } else if (app.notResponding) {
3992                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3993                return;
3994            } else if (app.crashing) {
3995                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3996                return;
3997            }
3998
3999            // In case we come through here for the same app before completing
4000            // this one, mark as anring now so we will bail out.
4001            app.notResponding = true;
4002
4003            // Log the ANR to the event log.
4004            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4005                    app.processName, app.info.flags, annotation);
4006
4007            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4008            firstPids.add(app.pid);
4009
4010            int parentPid = app.pid;
4011            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4012            if (parentPid != app.pid) firstPids.add(parentPid);
4013
4014            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4015
4016            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4017                ProcessRecord r = mLruProcesses.get(i);
4018                if (r != null && r.thread != null) {
4019                    int pid = r.pid;
4020                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4021                        if (r.persistent) {
4022                            firstPids.add(pid);
4023                        } else {
4024                            lastPids.put(pid, Boolean.TRUE);
4025                        }
4026                    }
4027                }
4028            }
4029        }
4030
4031        // Log the ANR to the main log.
4032        StringBuilder info = new StringBuilder();
4033        info.setLength(0);
4034        info.append("ANR in ").append(app.processName);
4035        if (activity != null && activity.shortComponentName != null) {
4036            info.append(" (").append(activity.shortComponentName).append(")");
4037        }
4038        info.append("\n");
4039        info.append("PID: ").append(app.pid).append("\n");
4040        if (annotation != null) {
4041            info.append("Reason: ").append(annotation).append("\n");
4042        }
4043        if (parent != null && parent != activity) {
4044            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4045        }
4046
4047        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4048
4049        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4050                NATIVE_STACKS_OF_INTEREST);
4051
4052        String cpuInfo = null;
4053        if (MONITOR_CPU_USAGE) {
4054            updateCpuStatsNow();
4055            synchronized (mProcessCpuThread) {
4056                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4057            }
4058            info.append(processCpuTracker.printCurrentLoad());
4059            info.append(cpuInfo);
4060        }
4061
4062        info.append(processCpuTracker.printCurrentState(anrTime));
4063
4064        Slog.e(TAG, info.toString());
4065        if (tracesFile == null) {
4066            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4067            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4068        }
4069
4070        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4071                cpuInfo, tracesFile, null);
4072
4073        if (mController != null) {
4074            try {
4075                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4076                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4077                if (res != 0) {
4078                    if (res < 0 && app.pid != MY_PID) {
4079                        Process.killProcess(app.pid);
4080                    } else {
4081                        synchronized (this) {
4082                            mServices.scheduleServiceTimeoutLocked(app);
4083                        }
4084                    }
4085                    return;
4086                }
4087            } catch (RemoteException e) {
4088                mController = null;
4089                Watchdog.getInstance().setActivityController(null);
4090            }
4091        }
4092
4093        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4094        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4095                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4096
4097        synchronized (this) {
4098            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4099                killUnneededProcessLocked(app, "background ANR");
4100                return;
4101            }
4102
4103            // Set the app's notResponding state, and look up the errorReportReceiver
4104            makeAppNotRespondingLocked(app,
4105                    activity != null ? activity.shortComponentName : null,
4106                    annotation != null ? "ANR " + annotation : "ANR",
4107                    info.toString());
4108
4109            // Bring up the infamous App Not Responding dialog
4110            Message msg = Message.obtain();
4111            HashMap<String, Object> map = new HashMap<String, Object>();
4112            msg.what = SHOW_NOT_RESPONDING_MSG;
4113            msg.obj = map;
4114            msg.arg1 = aboveSystem ? 1 : 0;
4115            map.put("app", app);
4116            if (activity != null) {
4117                map.put("activity", activity);
4118            }
4119
4120            mHandler.sendMessage(msg);
4121        }
4122    }
4123
4124    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4125        if (!mLaunchWarningShown) {
4126            mLaunchWarningShown = true;
4127            mHandler.post(new Runnable() {
4128                @Override
4129                public void run() {
4130                    synchronized (ActivityManagerService.this) {
4131                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4132                        d.show();
4133                        mHandler.postDelayed(new Runnable() {
4134                            @Override
4135                            public void run() {
4136                                synchronized (ActivityManagerService.this) {
4137                                    d.dismiss();
4138                                    mLaunchWarningShown = false;
4139                                }
4140                            }
4141                        }, 4000);
4142                    }
4143                }
4144            });
4145        }
4146    }
4147
4148    @Override
4149    public boolean clearApplicationUserData(final String packageName,
4150            final IPackageDataObserver observer, int userId) {
4151        enforceNotIsolatedCaller("clearApplicationUserData");
4152        int uid = Binder.getCallingUid();
4153        int pid = Binder.getCallingPid();
4154        userId = handleIncomingUser(pid, uid,
4155                userId, false, true, "clearApplicationUserData", null);
4156        long callingId = Binder.clearCallingIdentity();
4157        try {
4158            IPackageManager pm = AppGlobals.getPackageManager();
4159            int pkgUid = -1;
4160            synchronized(this) {
4161                try {
4162                    pkgUid = pm.getPackageUid(packageName, userId);
4163                } catch (RemoteException e) {
4164                }
4165                if (pkgUid == -1) {
4166                    Slog.w(TAG, "Invalid packageName: " + packageName);
4167                    if (observer != null) {
4168                        try {
4169                            observer.onRemoveCompleted(packageName, false);
4170                        } catch (RemoteException e) {
4171                            Slog.i(TAG, "Observer no longer exists.");
4172                        }
4173                    }
4174                    return false;
4175                }
4176                if (uid == pkgUid || checkComponentPermission(
4177                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4178                        pid, uid, -1, true)
4179                        == PackageManager.PERMISSION_GRANTED) {
4180                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4181                } else {
4182                    throw new SecurityException("PID " + pid + " does not have permission "
4183                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4184                                    + " of package " + packageName);
4185                }
4186            }
4187
4188            try {
4189                // Clear application user data
4190                pm.clearApplicationUserData(packageName, observer, userId);
4191
4192                // Remove all permissions granted from/to this package
4193                removeUriPermissionsForPackageLocked(packageName, userId, true);
4194
4195                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4196                        Uri.fromParts("package", packageName, null));
4197                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4198                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4199                        null, null, 0, null, null, null, false, false, userId);
4200            } catch (RemoteException e) {
4201            }
4202        } finally {
4203            Binder.restoreCallingIdentity(callingId);
4204        }
4205        return true;
4206    }
4207
4208    @Override
4209    public void killBackgroundProcesses(final String packageName, int userId) {
4210        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4211                != PackageManager.PERMISSION_GRANTED &&
4212                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4213                        != PackageManager.PERMISSION_GRANTED) {
4214            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4215                    + Binder.getCallingPid()
4216                    + ", uid=" + Binder.getCallingUid()
4217                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4218            Slog.w(TAG, msg);
4219            throw new SecurityException(msg);
4220        }
4221
4222        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4223                userId, true, true, "killBackgroundProcesses", null);
4224        long callingId = Binder.clearCallingIdentity();
4225        try {
4226            IPackageManager pm = AppGlobals.getPackageManager();
4227            synchronized(this) {
4228                int appId = -1;
4229                try {
4230                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4231                } catch (RemoteException e) {
4232                }
4233                if (appId == -1) {
4234                    Slog.w(TAG, "Invalid packageName: " + packageName);
4235                    return;
4236                }
4237                killPackageProcessesLocked(packageName, appId, userId,
4238                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4239            }
4240        } finally {
4241            Binder.restoreCallingIdentity(callingId);
4242        }
4243    }
4244
4245    @Override
4246    public void killAllBackgroundProcesses() {
4247        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4248                != PackageManager.PERMISSION_GRANTED) {
4249            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4250                    + Binder.getCallingPid()
4251                    + ", uid=" + Binder.getCallingUid()
4252                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4253            Slog.w(TAG, msg);
4254            throw new SecurityException(msg);
4255        }
4256
4257        long callingId = Binder.clearCallingIdentity();
4258        try {
4259            synchronized(this) {
4260                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4261                final int NP = mProcessNames.getMap().size();
4262                for (int ip=0; ip<NP; ip++) {
4263                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4264                    final int NA = apps.size();
4265                    for (int ia=0; ia<NA; ia++) {
4266                        ProcessRecord app = apps.valueAt(ia);
4267                        if (app.persistent) {
4268                            // we don't kill persistent processes
4269                            continue;
4270                        }
4271                        if (app.removed) {
4272                            procs.add(app);
4273                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4274                            app.removed = true;
4275                            procs.add(app);
4276                        }
4277                    }
4278                }
4279
4280                int N = procs.size();
4281                for (int i=0; i<N; i++) {
4282                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4283                }
4284                mAllowLowerMemLevel = true;
4285                updateOomAdjLocked();
4286                doLowMemReportIfNeededLocked(null);
4287            }
4288        } finally {
4289            Binder.restoreCallingIdentity(callingId);
4290        }
4291    }
4292
4293    @Override
4294    public void forceStopPackage(final String packageName, int userId) {
4295        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4296                != PackageManager.PERMISSION_GRANTED) {
4297            String msg = "Permission Denial: forceStopPackage() from pid="
4298                    + Binder.getCallingPid()
4299                    + ", uid=" + Binder.getCallingUid()
4300                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4301            Slog.w(TAG, msg);
4302            throw new SecurityException(msg);
4303        }
4304        final int callingPid = Binder.getCallingPid();
4305        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4306                userId, true, true, "forceStopPackage", null);
4307        long callingId = Binder.clearCallingIdentity();
4308        try {
4309            IPackageManager pm = AppGlobals.getPackageManager();
4310            synchronized(this) {
4311                int[] users = userId == UserHandle.USER_ALL
4312                        ? getUsersLocked() : new int[] { userId };
4313                for (int user : users) {
4314                    int pkgUid = -1;
4315                    try {
4316                        pkgUid = pm.getPackageUid(packageName, user);
4317                    } catch (RemoteException e) {
4318                    }
4319                    if (pkgUid == -1) {
4320                        Slog.w(TAG, "Invalid packageName: " + packageName);
4321                        continue;
4322                    }
4323                    try {
4324                        pm.setPackageStoppedState(packageName, true, user);
4325                    } catch (RemoteException e) {
4326                    } catch (IllegalArgumentException e) {
4327                        Slog.w(TAG, "Failed trying to unstop package "
4328                                + packageName + ": " + e);
4329                    }
4330                    if (isUserRunningLocked(user, false)) {
4331                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4332                    }
4333                }
4334            }
4335        } finally {
4336            Binder.restoreCallingIdentity(callingId);
4337        }
4338    }
4339
4340    /*
4341     * The pkg name and app id have to be specified.
4342     */
4343    @Override
4344    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4345        if (pkg == null) {
4346            return;
4347        }
4348        // Make sure the uid is valid.
4349        if (appid < 0) {
4350            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4351            return;
4352        }
4353        int callerUid = Binder.getCallingUid();
4354        // Only the system server can kill an application
4355        if (callerUid == Process.SYSTEM_UID) {
4356            // Post an aysnc message to kill the application
4357            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4358            msg.arg1 = appid;
4359            msg.arg2 = 0;
4360            Bundle bundle = new Bundle();
4361            bundle.putString("pkg", pkg);
4362            bundle.putString("reason", reason);
4363            msg.obj = bundle;
4364            mHandler.sendMessage(msg);
4365        } else {
4366            throw new SecurityException(callerUid + " cannot kill pkg: " +
4367                    pkg);
4368        }
4369    }
4370
4371    @Override
4372    public void closeSystemDialogs(String reason) {
4373        enforceNotIsolatedCaller("closeSystemDialogs");
4374
4375        final int pid = Binder.getCallingPid();
4376        final int uid = Binder.getCallingUid();
4377        final long origId = Binder.clearCallingIdentity();
4378        try {
4379            synchronized (this) {
4380                // Only allow this from foreground processes, so that background
4381                // applications can't abuse it to prevent system UI from being shown.
4382                if (uid >= Process.FIRST_APPLICATION_UID) {
4383                    ProcessRecord proc;
4384                    synchronized (mPidsSelfLocked) {
4385                        proc = mPidsSelfLocked.get(pid);
4386                    }
4387                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4388                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4389                                + " from background process " + proc);
4390                        return;
4391                    }
4392                }
4393                closeSystemDialogsLocked(reason);
4394            }
4395        } finally {
4396            Binder.restoreCallingIdentity(origId);
4397        }
4398    }
4399
4400    void closeSystemDialogsLocked(String reason) {
4401        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4402        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4403                | Intent.FLAG_RECEIVER_FOREGROUND);
4404        if (reason != null) {
4405            intent.putExtra("reason", reason);
4406        }
4407        mWindowManager.closeSystemDialogs(reason);
4408
4409        mStackSupervisor.closeSystemDialogsLocked();
4410
4411        broadcastIntentLocked(null, null, intent, null,
4412                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4413                Process.SYSTEM_UID, UserHandle.USER_ALL);
4414    }
4415
4416    @Override
4417    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4418        enforceNotIsolatedCaller("getProcessMemoryInfo");
4419        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4420        for (int i=pids.length-1; i>=0; i--) {
4421            ProcessRecord proc;
4422            int oomAdj;
4423            synchronized (this) {
4424                synchronized (mPidsSelfLocked) {
4425                    proc = mPidsSelfLocked.get(pids[i]);
4426                    oomAdj = proc != null ? proc.setAdj : 0;
4427                }
4428            }
4429            infos[i] = new Debug.MemoryInfo();
4430            Debug.getMemoryInfo(pids[i], infos[i]);
4431            if (proc != null) {
4432                synchronized (this) {
4433                    if (proc.thread != null && proc.setAdj == oomAdj) {
4434                        // Record this for posterity if the process has been stable.
4435                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4436                                infos[i].getTotalUss(), false, proc.pkgList);
4437                    }
4438                }
4439            }
4440        }
4441        return infos;
4442    }
4443
4444    @Override
4445    public long[] getProcessPss(int[] pids) {
4446        enforceNotIsolatedCaller("getProcessPss");
4447        long[] pss = new long[pids.length];
4448        for (int i=pids.length-1; i>=0; i--) {
4449            ProcessRecord proc;
4450            int oomAdj;
4451            synchronized (this) {
4452                synchronized (mPidsSelfLocked) {
4453                    proc = mPidsSelfLocked.get(pids[i]);
4454                    oomAdj = proc != null ? proc.setAdj : 0;
4455                }
4456            }
4457            long[] tmpUss = new long[1];
4458            pss[i] = Debug.getPss(pids[i], tmpUss);
4459            if (proc != null) {
4460                synchronized (this) {
4461                    if (proc.thread != null && proc.setAdj == oomAdj) {
4462                        // Record this for posterity if the process has been stable.
4463                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4464                    }
4465                }
4466            }
4467        }
4468        return pss;
4469    }
4470
4471    @Override
4472    public void killApplicationProcess(String processName, int uid) {
4473        if (processName == null) {
4474            return;
4475        }
4476
4477        int callerUid = Binder.getCallingUid();
4478        // Only the system server can kill an application
4479        if (callerUid == Process.SYSTEM_UID) {
4480            synchronized (this) {
4481                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4482                if (app != null && app.thread != null) {
4483                    try {
4484                        app.thread.scheduleSuicide();
4485                    } catch (RemoteException e) {
4486                        // If the other end already died, then our work here is done.
4487                    }
4488                } else {
4489                    Slog.w(TAG, "Process/uid not found attempting kill of "
4490                            + processName + " / " + uid);
4491                }
4492            }
4493        } else {
4494            throw new SecurityException(callerUid + " cannot kill app process: " +
4495                    processName);
4496        }
4497    }
4498
4499    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4500        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4501                false, true, false, false, UserHandle.getUserId(uid), reason);
4502        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4503                Uri.fromParts("package", packageName, null));
4504        if (!mProcessesReady) {
4505            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4506                    | Intent.FLAG_RECEIVER_FOREGROUND);
4507        }
4508        intent.putExtra(Intent.EXTRA_UID, uid);
4509        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4510        broadcastIntentLocked(null, null, intent,
4511                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4512                false, false,
4513                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4514    }
4515
4516    private void forceStopUserLocked(int userId, String reason) {
4517        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4518        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4519        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4520                | Intent.FLAG_RECEIVER_FOREGROUND);
4521        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4522        broadcastIntentLocked(null, null, intent,
4523                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4524                false, false,
4525                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4526    }
4527
4528    private final boolean killPackageProcessesLocked(String packageName, int appId,
4529            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4530            boolean doit, boolean evenPersistent, String reason) {
4531        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4532
4533        // Remove all processes this package may have touched: all with the
4534        // same UID (except for the system or root user), and all whose name
4535        // matches the package name.
4536        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4537        final int NP = mProcessNames.getMap().size();
4538        for (int ip=0; ip<NP; ip++) {
4539            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4540            final int NA = apps.size();
4541            for (int ia=0; ia<NA; ia++) {
4542                ProcessRecord app = apps.valueAt(ia);
4543                if (app.persistent && !evenPersistent) {
4544                    // we don't kill persistent processes
4545                    continue;
4546                }
4547                if (app.removed) {
4548                    if (doit) {
4549                        procs.add(app);
4550                    }
4551                    continue;
4552                }
4553
4554                // Skip process if it doesn't meet our oom adj requirement.
4555                if (app.setAdj < minOomAdj) {
4556                    continue;
4557                }
4558
4559                // If no package is specified, we call all processes under the
4560                // give user id.
4561                if (packageName == null) {
4562                    if (app.userId != userId) {
4563                        continue;
4564                    }
4565                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4566                        continue;
4567                    }
4568                // Package has been specified, we want to hit all processes
4569                // that match it.  We need to qualify this by the processes
4570                // that are running under the specified app and user ID.
4571                } else {
4572                    if (UserHandle.getAppId(app.uid) != appId) {
4573                        continue;
4574                    }
4575                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4576                        continue;
4577                    }
4578                    if (!app.pkgList.containsKey(packageName)) {
4579                        continue;
4580                    }
4581                }
4582
4583                // Process has passed all conditions, kill it!
4584                if (!doit) {
4585                    return true;
4586                }
4587                app.removed = true;
4588                procs.add(app);
4589            }
4590        }
4591
4592        int N = procs.size();
4593        for (int i=0; i<N; i++) {
4594            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4595        }
4596        updateOomAdjLocked();
4597        return N > 0;
4598    }
4599
4600    private final boolean forceStopPackageLocked(String name, int appId,
4601            boolean callerWillRestart, boolean purgeCache, boolean doit,
4602            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4603        int i;
4604        int N;
4605
4606        if (userId == UserHandle.USER_ALL && name == null) {
4607            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4608        }
4609
4610        if (appId < 0 && name != null) {
4611            try {
4612                appId = UserHandle.getAppId(
4613                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4614            } catch (RemoteException e) {
4615            }
4616        }
4617
4618        if (doit) {
4619            if (name != null) {
4620                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4621                        + " user=" + userId + ": " + reason);
4622            } else {
4623                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4624            }
4625
4626            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4627            for (int ip=pmap.size()-1; ip>=0; ip--) {
4628                SparseArray<Long> ba = pmap.valueAt(ip);
4629                for (i=ba.size()-1; i>=0; i--) {
4630                    boolean remove = false;
4631                    final int entUid = ba.keyAt(i);
4632                    if (name != null) {
4633                        if (userId == UserHandle.USER_ALL) {
4634                            if (UserHandle.getAppId(entUid) == appId) {
4635                                remove = true;
4636                            }
4637                        } else {
4638                            if (entUid == UserHandle.getUid(userId, appId)) {
4639                                remove = true;
4640                            }
4641                        }
4642                    } else if (UserHandle.getUserId(entUid) == userId) {
4643                        remove = true;
4644                    }
4645                    if (remove) {
4646                        ba.removeAt(i);
4647                    }
4648                }
4649                if (ba.size() == 0) {
4650                    pmap.removeAt(ip);
4651                }
4652            }
4653        }
4654
4655        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4656                -100, callerWillRestart, true, doit, evenPersistent,
4657                name == null ? ("stop user " + userId) : ("stop " + name));
4658
4659        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4660            if (!doit) {
4661                return true;
4662            }
4663            didSomething = true;
4664        }
4665
4666        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4667            if (!doit) {
4668                return true;
4669            }
4670            didSomething = true;
4671        }
4672
4673        if (name == null) {
4674            // Remove all sticky broadcasts from this user.
4675            mStickyBroadcasts.remove(userId);
4676        }
4677
4678        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4679        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4680                userId, providers)) {
4681            if (!doit) {
4682                return true;
4683            }
4684            didSomething = true;
4685        }
4686        N = providers.size();
4687        for (i=0; i<N; i++) {
4688            removeDyingProviderLocked(null, providers.get(i), true);
4689        }
4690
4691        // Remove transient permissions granted from/to this package/user
4692        removeUriPermissionsForPackageLocked(name, userId, false);
4693
4694        if (name == null || uninstalling) {
4695            // Remove pending intents.  For now we only do this when force
4696            // stopping users, because we have some problems when doing this
4697            // for packages -- app widgets are not currently cleaned up for
4698            // such packages, so they can be left with bad pending intents.
4699            if (mIntentSenderRecords.size() > 0) {
4700                Iterator<WeakReference<PendingIntentRecord>> it
4701                        = mIntentSenderRecords.values().iterator();
4702                while (it.hasNext()) {
4703                    WeakReference<PendingIntentRecord> wpir = it.next();
4704                    if (wpir == null) {
4705                        it.remove();
4706                        continue;
4707                    }
4708                    PendingIntentRecord pir = wpir.get();
4709                    if (pir == null) {
4710                        it.remove();
4711                        continue;
4712                    }
4713                    if (name == null) {
4714                        // Stopping user, remove all objects for the user.
4715                        if (pir.key.userId != userId) {
4716                            // Not the same user, skip it.
4717                            continue;
4718                        }
4719                    } else {
4720                        if (UserHandle.getAppId(pir.uid) != appId) {
4721                            // Different app id, skip it.
4722                            continue;
4723                        }
4724                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4725                            // Different user, skip it.
4726                            continue;
4727                        }
4728                        if (!pir.key.packageName.equals(name)) {
4729                            // Different package, skip it.
4730                            continue;
4731                        }
4732                    }
4733                    if (!doit) {
4734                        return true;
4735                    }
4736                    didSomething = true;
4737                    it.remove();
4738                    pir.canceled = true;
4739                    if (pir.key.activity != null) {
4740                        pir.key.activity.pendingResults.remove(pir.ref);
4741                    }
4742                }
4743            }
4744        }
4745
4746        if (doit) {
4747            if (purgeCache && name != null) {
4748                AttributeCache ac = AttributeCache.instance();
4749                if (ac != null) {
4750                    ac.removePackage(name);
4751                }
4752            }
4753            if (mBooted) {
4754                mStackSupervisor.resumeTopActivitiesLocked();
4755                mStackSupervisor.scheduleIdleLocked();
4756            }
4757        }
4758
4759        return didSomething;
4760    }
4761
4762    private final boolean removeProcessLocked(ProcessRecord app,
4763            boolean callerWillRestart, boolean allowRestart, String reason) {
4764        final String name = app.processName;
4765        final int uid = app.uid;
4766        if (DEBUG_PROCESSES) Slog.d(
4767            TAG, "Force removing proc " + app.toShortString() + " (" + name
4768            + "/" + uid + ")");
4769
4770        mProcessNames.remove(name, uid);
4771        mIsolatedProcesses.remove(app.uid);
4772        if (mHeavyWeightProcess == app) {
4773            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4774                    mHeavyWeightProcess.userId, 0));
4775            mHeavyWeightProcess = null;
4776        }
4777        boolean needRestart = false;
4778        if (app.pid > 0 && app.pid != MY_PID) {
4779            int pid = app.pid;
4780            synchronized (mPidsSelfLocked) {
4781                mPidsSelfLocked.remove(pid);
4782                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4783            }
4784            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4785                    app.processName, app.info.uid);
4786            if (app.isolated) {
4787                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4788            }
4789            killUnneededProcessLocked(app, reason);
4790            handleAppDiedLocked(app, true, allowRestart);
4791            removeLruProcessLocked(app);
4792
4793            if (app.persistent && !app.isolated) {
4794                if (!callerWillRestart) {
4795                    addAppLocked(app.info, false);
4796                } else {
4797                    needRestart = true;
4798                }
4799            }
4800        } else {
4801            mRemovedProcesses.add(app);
4802        }
4803
4804        return needRestart;
4805    }
4806
4807    private final void processStartTimedOutLocked(ProcessRecord app) {
4808        final int pid = app.pid;
4809        boolean gone = false;
4810        synchronized (mPidsSelfLocked) {
4811            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4812            if (knownApp != null && knownApp.thread == null) {
4813                mPidsSelfLocked.remove(pid);
4814                gone = true;
4815            }
4816        }
4817
4818        if (gone) {
4819            Slog.w(TAG, "Process " + app + " failed to attach");
4820            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4821                    pid, app.uid, app.processName);
4822            mProcessNames.remove(app.processName, app.uid);
4823            mIsolatedProcesses.remove(app.uid);
4824            if (mHeavyWeightProcess == app) {
4825                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4826                        mHeavyWeightProcess.userId, 0));
4827                mHeavyWeightProcess = null;
4828            }
4829            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4830                    app.processName, app.info.uid);
4831            if (app.isolated) {
4832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4833            }
4834            // Take care of any launching providers waiting for this process.
4835            checkAppInLaunchingProvidersLocked(app, true);
4836            // Take care of any services that are waiting for the process.
4837            mServices.processStartTimedOutLocked(app);
4838            killUnneededProcessLocked(app, "start timeout");
4839            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4840                Slog.w(TAG, "Unattached app died before backup, skipping");
4841                try {
4842                    IBackupManager bm = IBackupManager.Stub.asInterface(
4843                            ServiceManager.getService(Context.BACKUP_SERVICE));
4844                    bm.agentDisconnected(app.info.packageName);
4845                } catch (RemoteException e) {
4846                    // Can't happen; the backup manager is local
4847                }
4848            }
4849            if (isPendingBroadcastProcessLocked(pid)) {
4850                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4851                skipPendingBroadcastLocked(pid);
4852            }
4853        } else {
4854            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4855        }
4856    }
4857
4858    private final boolean attachApplicationLocked(IApplicationThread thread,
4859            int pid) {
4860
4861        // Find the application record that is being attached...  either via
4862        // the pid if we are running in multiple processes, or just pull the
4863        // next app record if we are emulating process with anonymous threads.
4864        ProcessRecord app;
4865        if (pid != MY_PID && pid >= 0) {
4866            synchronized (mPidsSelfLocked) {
4867                app = mPidsSelfLocked.get(pid);
4868            }
4869        } else {
4870            app = null;
4871        }
4872
4873        if (app == null) {
4874            Slog.w(TAG, "No pending application record for pid " + pid
4875                    + " (IApplicationThread " + thread + "); dropping process");
4876            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4877            if (pid > 0 && pid != MY_PID) {
4878                Process.killProcessQuiet(pid);
4879            } else {
4880                try {
4881                    thread.scheduleExit();
4882                } catch (Exception e) {
4883                    // Ignore exceptions.
4884                }
4885            }
4886            return false;
4887        }
4888
4889        // If this application record is still attached to a previous
4890        // process, clean it up now.
4891        if (app.thread != null) {
4892            handleAppDiedLocked(app, true, true);
4893        }
4894
4895        // Tell the process all about itself.
4896
4897        if (localLOGV) Slog.v(
4898                TAG, "Binding process pid " + pid + " to record " + app);
4899
4900        final String processName = app.processName;
4901        try {
4902            AppDeathRecipient adr = new AppDeathRecipient(
4903                    app, pid, thread);
4904            thread.asBinder().linkToDeath(adr, 0);
4905            app.deathRecipient = adr;
4906        } catch (RemoteException e) {
4907            app.resetPackageList(mProcessStats);
4908            startProcessLocked(app, "link fail", processName);
4909            return false;
4910        }
4911
4912        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4913
4914        app.makeActive(thread, mProcessStats);
4915        app.curAdj = app.setAdj = -100;
4916        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4917        app.forcingToForeground = null;
4918        updateProcessForegroundLocked(app, false, false);
4919        app.hasShownUi = false;
4920        app.debugging = false;
4921        app.cached = false;
4922
4923        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4924
4925        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4926        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4927
4928        if (!normalMode) {
4929            Slog.i(TAG, "Launching preboot mode app: " + app);
4930        }
4931
4932        if (localLOGV) Slog.v(
4933            TAG, "New app record " + app
4934            + " thread=" + thread.asBinder() + " pid=" + pid);
4935        try {
4936            int testMode = IApplicationThread.DEBUG_OFF;
4937            if (mDebugApp != null && mDebugApp.equals(processName)) {
4938                testMode = mWaitForDebugger
4939                    ? IApplicationThread.DEBUG_WAIT
4940                    : IApplicationThread.DEBUG_ON;
4941                app.debugging = true;
4942                if (mDebugTransient) {
4943                    mDebugApp = mOrigDebugApp;
4944                    mWaitForDebugger = mOrigWaitForDebugger;
4945                }
4946            }
4947            String profileFile = app.instrumentationProfileFile;
4948            ParcelFileDescriptor profileFd = null;
4949            boolean profileAutoStop = false;
4950            if (mProfileApp != null && mProfileApp.equals(processName)) {
4951                mProfileProc = app;
4952                profileFile = mProfileFile;
4953                profileFd = mProfileFd;
4954                profileAutoStop = mAutoStopProfiler;
4955            }
4956            boolean enableOpenGlTrace = false;
4957            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4958                enableOpenGlTrace = true;
4959                mOpenGlTraceApp = null;
4960            }
4961
4962            // If the app is being launched for restore or full backup, set it up specially
4963            boolean isRestrictedBackupMode = false;
4964            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4965                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4966                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4967                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4968            }
4969
4970            ensurePackageDexOpt(app.instrumentationInfo != null
4971                    ? app.instrumentationInfo.packageName
4972                    : app.info.packageName);
4973            if (app.instrumentationClass != null) {
4974                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4975            }
4976            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4977                    + processName + " with config " + mConfiguration);
4978            ApplicationInfo appInfo = app.instrumentationInfo != null
4979                    ? app.instrumentationInfo : app.info;
4980            app.compat = compatibilityInfoForPackageLocked(appInfo);
4981            if (profileFd != null) {
4982                profileFd = profileFd.dup();
4983            }
4984            thread.bindApplication(processName, appInfo, providers,
4985                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4986                    app.instrumentationArguments, app.instrumentationWatcher,
4987                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4988                    isRestrictedBackupMode || !normalMode, app.persistent,
4989                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4990                    mCoreSettingsObserver.getCoreSettingsLocked());
4991            updateLruProcessLocked(app, false, null);
4992            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4993        } catch (Exception e) {
4994            // todo: Yikes!  What should we do?  For now we will try to
4995            // start another process, but that could easily get us in
4996            // an infinite loop of restarting processes...
4997            Slog.w(TAG, "Exception thrown during bind!", e);
4998
4999            app.resetPackageList(mProcessStats);
5000            app.unlinkDeathRecipient();
5001            startProcessLocked(app, "bind fail", processName);
5002            return false;
5003        }
5004
5005        // Remove this record from the list of starting applications.
5006        mPersistentStartingProcesses.remove(app);
5007        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5008                "Attach application locked removing on hold: " + app);
5009        mProcessesOnHold.remove(app);
5010
5011        boolean badApp = false;
5012        boolean didSomething = false;
5013
5014        // See if the top visible activity is waiting to run in this process...
5015        if (normalMode) {
5016            try {
5017                if (mStackSupervisor.attachApplicationLocked(app)) {
5018                    didSomething = true;
5019                }
5020            } catch (Exception e) {
5021                badApp = true;
5022            }
5023        }
5024
5025        // Find any services that should be running in this process...
5026        if (!badApp) {
5027            try {
5028                didSomething |= mServices.attachApplicationLocked(app, processName);
5029            } catch (Exception e) {
5030                badApp = true;
5031            }
5032        }
5033
5034        // Check if a next-broadcast receiver is in this process...
5035        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5036            try {
5037                didSomething |= sendPendingBroadcastsLocked(app);
5038            } catch (Exception e) {
5039                // If the app died trying to launch the receiver we declare it 'bad'
5040                badApp = true;
5041            }
5042        }
5043
5044        // Check whether the next backup agent is in this process...
5045        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5046            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5047            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5048            try {
5049                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5050                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5051                        mBackupTarget.backupMode);
5052            } catch (Exception e) {
5053                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5054                e.printStackTrace();
5055            }
5056        }
5057
5058        if (badApp) {
5059            // todo: Also need to kill application to deal with all
5060            // kinds of exceptions.
5061            handleAppDiedLocked(app, false, true);
5062            return false;
5063        }
5064
5065        if (!didSomething) {
5066            updateOomAdjLocked();
5067        }
5068
5069        return true;
5070    }
5071
5072    @Override
5073    public final void attachApplication(IApplicationThread thread) {
5074        synchronized (this) {
5075            int callingPid = Binder.getCallingPid();
5076            final long origId = Binder.clearCallingIdentity();
5077            attachApplicationLocked(thread, callingPid);
5078            Binder.restoreCallingIdentity(origId);
5079        }
5080    }
5081
5082    @Override
5083    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5084        final long origId = Binder.clearCallingIdentity();
5085        synchronized (this) {
5086            ActivityStack stack = ActivityRecord.getStackLocked(token);
5087            if (stack != null) {
5088                ActivityRecord r =
5089                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5090                if (stopProfiling) {
5091                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5092                        try {
5093                            mProfileFd.close();
5094                        } catch (IOException e) {
5095                        }
5096                        clearProfilerLocked();
5097                    }
5098                }
5099            }
5100        }
5101        Binder.restoreCallingIdentity(origId);
5102    }
5103
5104    void enableScreenAfterBoot() {
5105        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5106                SystemClock.uptimeMillis());
5107        mWindowManager.enableScreenAfterBoot();
5108
5109        synchronized (this) {
5110            updateEventDispatchingLocked();
5111        }
5112    }
5113
5114    @Override
5115    public void showBootMessage(final CharSequence msg, final boolean always) {
5116        enforceNotIsolatedCaller("showBootMessage");
5117        mWindowManager.showBootMessage(msg, always);
5118    }
5119
5120    @Override
5121    public void dismissKeyguardOnNextActivity() {
5122        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5123        final long token = Binder.clearCallingIdentity();
5124        try {
5125            synchronized (this) {
5126                if (DEBUG_LOCKSCREEN) logLockScreen("");
5127                if (mLockScreenShown) {
5128                    mLockScreenShown = false;
5129                    comeOutOfSleepIfNeededLocked();
5130                }
5131                mStackSupervisor.setDismissKeyguard(true);
5132            }
5133        } finally {
5134            Binder.restoreCallingIdentity(token);
5135        }
5136    }
5137
5138    final void finishBooting() {
5139        IntentFilter pkgFilter = new IntentFilter();
5140        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5141        pkgFilter.addDataScheme("package");
5142        mContext.registerReceiver(new BroadcastReceiver() {
5143            @Override
5144            public void onReceive(Context context, Intent intent) {
5145                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5146                if (pkgs != null) {
5147                    for (String pkg : pkgs) {
5148                        synchronized (ActivityManagerService.this) {
5149                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5150                                    "finished booting")) {
5151                                setResultCode(Activity.RESULT_OK);
5152                                return;
5153                            }
5154                        }
5155                    }
5156                }
5157            }
5158        }, pkgFilter);
5159
5160        synchronized (this) {
5161            // Ensure that any processes we had put on hold are now started
5162            // up.
5163            final int NP = mProcessesOnHold.size();
5164            if (NP > 0) {
5165                ArrayList<ProcessRecord> procs =
5166                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5167                for (int ip=0; ip<NP; ip++) {
5168                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5169                            + procs.get(ip));
5170                    startProcessLocked(procs.get(ip), "on-hold", null);
5171                }
5172            }
5173
5174            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5175                // Start looking for apps that are abusing wake locks.
5176                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5177                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5178                // Tell anyone interested that we are done booting!
5179                SystemProperties.set("sys.boot_completed", "1");
5180                SystemProperties.set("dev.bootcomplete", "1");
5181                for (int i=0; i<mStartedUsers.size(); i++) {
5182                    UserStartedState uss = mStartedUsers.valueAt(i);
5183                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5184                        uss.mState = UserStartedState.STATE_RUNNING;
5185                        final int userId = mStartedUsers.keyAt(i);
5186                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5187                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5188                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5189                        broadcastIntentLocked(null, null, intent, null,
5190                                new IIntentReceiver.Stub() {
5191                                    @Override
5192                                    public void performReceive(Intent intent, int resultCode,
5193                                            String data, Bundle extras, boolean ordered,
5194                                            boolean sticky, int sendingUser) {
5195                                        synchronized (ActivityManagerService.this) {
5196                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5197                                                    true, false);
5198                                        }
5199                                    }
5200                                },
5201                                0, null, null,
5202                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5203                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5204                                userId);
5205                    }
5206                }
5207                scheduleStartRelatedUsersLocked();
5208            }
5209        }
5210    }
5211
5212    final void ensureBootCompleted() {
5213        boolean booting;
5214        boolean enableScreen;
5215        synchronized (this) {
5216            booting = mBooting;
5217            mBooting = false;
5218            enableScreen = !mBooted;
5219            mBooted = true;
5220        }
5221
5222        if (booting) {
5223            finishBooting();
5224        }
5225
5226        if (enableScreen) {
5227            enableScreenAfterBoot();
5228        }
5229    }
5230
5231    @Override
5232    public final void activityResumed(IBinder token) {
5233        final long origId = Binder.clearCallingIdentity();
5234        synchronized(this) {
5235            ActivityStack stack = ActivityRecord.getStackLocked(token);
5236            if (stack != null) {
5237                ActivityRecord.activityResumedLocked(token);
5238            }
5239        }
5240        Binder.restoreCallingIdentity(origId);
5241    }
5242
5243    @Override
5244    public final void activityPaused(IBinder token) {
5245        final long origId = Binder.clearCallingIdentity();
5246        synchronized(this) {
5247            ActivityStack stack = ActivityRecord.getStackLocked(token);
5248            if (stack != null) {
5249                stack.activityPausedLocked(token, false);
5250            }
5251        }
5252        Binder.restoreCallingIdentity(origId);
5253    }
5254
5255    @Override
5256    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5257            CharSequence description) {
5258        if (localLOGV) Slog.v(
5259            TAG, "Activity stopped: token=" + token);
5260
5261        // Refuse possible leaked file descriptors
5262        if (icicle != null && icicle.hasFileDescriptors()) {
5263            throw new IllegalArgumentException("File descriptors passed in Bundle");
5264        }
5265
5266        ActivityRecord r = null;
5267
5268        final long origId = Binder.clearCallingIdentity();
5269
5270        synchronized (this) {
5271            r = ActivityRecord.isInStackLocked(token);
5272            if (r != null) {
5273                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5274            }
5275        }
5276
5277        if (r != null) {
5278            sendPendingThumbnail(r, null, null, null, false);
5279        }
5280
5281        trimApplications();
5282
5283        Binder.restoreCallingIdentity(origId);
5284    }
5285
5286    @Override
5287    public final void activityDestroyed(IBinder token) {
5288        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5289        synchronized (this) {
5290            ActivityStack stack = ActivityRecord.getStackLocked(token);
5291            if (stack != null) {
5292                stack.activityDestroyedLocked(token);
5293            }
5294        }
5295    }
5296
5297    @Override
5298    public String getCallingPackage(IBinder token) {
5299        synchronized (this) {
5300            ActivityRecord r = getCallingRecordLocked(token);
5301            return r != null ? r.info.packageName : null;
5302        }
5303    }
5304
5305    @Override
5306    public ComponentName getCallingActivity(IBinder token) {
5307        synchronized (this) {
5308            ActivityRecord r = getCallingRecordLocked(token);
5309            return r != null ? r.intent.getComponent() : null;
5310        }
5311    }
5312
5313    private ActivityRecord getCallingRecordLocked(IBinder token) {
5314        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5315        if (r == null) {
5316            return null;
5317        }
5318        return r.resultTo;
5319    }
5320
5321    @Override
5322    public ComponentName getActivityClassForToken(IBinder token) {
5323        synchronized(this) {
5324            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5325            if (r == null) {
5326                return null;
5327            }
5328            return r.intent.getComponent();
5329        }
5330    }
5331
5332    @Override
5333    public String getPackageForToken(IBinder token) {
5334        synchronized(this) {
5335            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5336            if (r == null) {
5337                return null;
5338            }
5339            return r.packageName;
5340        }
5341    }
5342
5343    @Override
5344    public IIntentSender getIntentSender(int type,
5345            String packageName, IBinder token, String resultWho,
5346            int requestCode, Intent[] intents, String[] resolvedTypes,
5347            int flags, Bundle options, int userId) {
5348        enforceNotIsolatedCaller("getIntentSender");
5349        // Refuse possible leaked file descriptors
5350        if (intents != null) {
5351            if (intents.length < 1) {
5352                throw new IllegalArgumentException("Intents array length must be >= 1");
5353            }
5354            for (int i=0; i<intents.length; i++) {
5355                Intent intent = intents[i];
5356                if (intent != null) {
5357                    if (intent.hasFileDescriptors()) {
5358                        throw new IllegalArgumentException("File descriptors passed in Intent");
5359                    }
5360                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5361                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5362                        throw new IllegalArgumentException(
5363                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5364                    }
5365                    intents[i] = new Intent(intent);
5366                }
5367            }
5368            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5369                throw new IllegalArgumentException(
5370                        "Intent array length does not match resolvedTypes length");
5371            }
5372        }
5373        if (options != null) {
5374            if (options.hasFileDescriptors()) {
5375                throw new IllegalArgumentException("File descriptors passed in options");
5376            }
5377        }
5378
5379        synchronized(this) {
5380            int callingUid = Binder.getCallingUid();
5381            int origUserId = userId;
5382            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5383                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5384                    "getIntentSender", null);
5385            if (origUserId == UserHandle.USER_CURRENT) {
5386                // We don't want to evaluate this until the pending intent is
5387                // actually executed.  However, we do want to always do the
5388                // security checking for it above.
5389                userId = UserHandle.USER_CURRENT;
5390            }
5391            try {
5392                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5393                    int uid = AppGlobals.getPackageManager()
5394                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5395                    if (!UserHandle.isSameApp(callingUid, uid)) {
5396                        String msg = "Permission Denial: getIntentSender() from pid="
5397                            + Binder.getCallingPid()
5398                            + ", uid=" + Binder.getCallingUid()
5399                            + ", (need uid=" + uid + ")"
5400                            + " is not allowed to send as package " + packageName;
5401                        Slog.w(TAG, msg);
5402                        throw new SecurityException(msg);
5403                    }
5404                }
5405
5406                return getIntentSenderLocked(type, packageName, callingUid, userId,
5407                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5408
5409            } catch (RemoteException e) {
5410                throw new SecurityException(e);
5411            }
5412        }
5413    }
5414
5415    IIntentSender getIntentSenderLocked(int type, String packageName,
5416            int callingUid, int userId, IBinder token, String resultWho,
5417            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5418            Bundle options) {
5419        if (DEBUG_MU)
5420            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5421        ActivityRecord activity = null;
5422        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5423            activity = ActivityRecord.isInStackLocked(token);
5424            if (activity == null) {
5425                return null;
5426            }
5427            if (activity.finishing) {
5428                return null;
5429            }
5430        }
5431
5432        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5433        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5434        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5435        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5436                |PendingIntent.FLAG_UPDATE_CURRENT);
5437
5438        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5439                type, packageName, activity, resultWho,
5440                requestCode, intents, resolvedTypes, flags, options, userId);
5441        WeakReference<PendingIntentRecord> ref;
5442        ref = mIntentSenderRecords.get(key);
5443        PendingIntentRecord rec = ref != null ? ref.get() : null;
5444        if (rec != null) {
5445            if (!cancelCurrent) {
5446                if (updateCurrent) {
5447                    if (rec.key.requestIntent != null) {
5448                        rec.key.requestIntent.replaceExtras(intents != null ?
5449                                intents[intents.length - 1] : null);
5450                    }
5451                    if (intents != null) {
5452                        intents[intents.length-1] = rec.key.requestIntent;
5453                        rec.key.allIntents = intents;
5454                        rec.key.allResolvedTypes = resolvedTypes;
5455                    } else {
5456                        rec.key.allIntents = null;
5457                        rec.key.allResolvedTypes = null;
5458                    }
5459                }
5460                return rec;
5461            }
5462            rec.canceled = true;
5463            mIntentSenderRecords.remove(key);
5464        }
5465        if (noCreate) {
5466            return rec;
5467        }
5468        rec = new PendingIntentRecord(this, key, callingUid);
5469        mIntentSenderRecords.put(key, rec.ref);
5470        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5471            if (activity.pendingResults == null) {
5472                activity.pendingResults
5473                        = new HashSet<WeakReference<PendingIntentRecord>>();
5474            }
5475            activity.pendingResults.add(rec.ref);
5476        }
5477        return rec;
5478    }
5479
5480    @Override
5481    public void cancelIntentSender(IIntentSender sender) {
5482        if (!(sender instanceof PendingIntentRecord)) {
5483            return;
5484        }
5485        synchronized(this) {
5486            PendingIntentRecord rec = (PendingIntentRecord)sender;
5487            try {
5488                int uid = AppGlobals.getPackageManager()
5489                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5490                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5491                    String msg = "Permission Denial: cancelIntentSender() from pid="
5492                        + Binder.getCallingPid()
5493                        + ", uid=" + Binder.getCallingUid()
5494                        + " is not allowed to cancel packges "
5495                        + rec.key.packageName;
5496                    Slog.w(TAG, msg);
5497                    throw new SecurityException(msg);
5498                }
5499            } catch (RemoteException e) {
5500                throw new SecurityException(e);
5501            }
5502            cancelIntentSenderLocked(rec, true);
5503        }
5504    }
5505
5506    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5507        rec.canceled = true;
5508        mIntentSenderRecords.remove(rec.key);
5509        if (cleanActivity && rec.key.activity != null) {
5510            rec.key.activity.pendingResults.remove(rec.ref);
5511        }
5512    }
5513
5514    @Override
5515    public String getPackageForIntentSender(IIntentSender pendingResult) {
5516        if (!(pendingResult instanceof PendingIntentRecord)) {
5517            return null;
5518        }
5519        try {
5520            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5521            return res.key.packageName;
5522        } catch (ClassCastException e) {
5523        }
5524        return null;
5525    }
5526
5527    @Override
5528    public int getUidForIntentSender(IIntentSender sender) {
5529        if (sender instanceof PendingIntentRecord) {
5530            try {
5531                PendingIntentRecord res = (PendingIntentRecord)sender;
5532                return res.uid;
5533            } catch (ClassCastException e) {
5534            }
5535        }
5536        return -1;
5537    }
5538
5539    @Override
5540    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5541        if (!(pendingResult instanceof PendingIntentRecord)) {
5542            return false;
5543        }
5544        try {
5545            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5546            if (res.key.allIntents == null) {
5547                return false;
5548            }
5549            for (int i=0; i<res.key.allIntents.length; i++) {
5550                Intent intent = res.key.allIntents[i];
5551                if (intent.getPackage() != null && intent.getComponent() != null) {
5552                    return false;
5553                }
5554            }
5555            return true;
5556        } catch (ClassCastException e) {
5557        }
5558        return false;
5559    }
5560
5561    @Override
5562    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5563        if (!(pendingResult instanceof PendingIntentRecord)) {
5564            return false;
5565        }
5566        try {
5567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5568            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5569                return true;
5570            }
5571            return false;
5572        } catch (ClassCastException e) {
5573        }
5574        return false;
5575    }
5576
5577    @Override
5578    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5579        if (!(pendingResult instanceof PendingIntentRecord)) {
5580            return null;
5581        }
5582        try {
5583            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5584            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5585        } catch (ClassCastException e) {
5586        }
5587        return null;
5588    }
5589
5590    @Override
5591    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5592        if (!(pendingResult instanceof PendingIntentRecord)) {
5593            return null;
5594        }
5595        try {
5596            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5597            Intent intent = res.key.requestIntent;
5598            if (intent != null) {
5599                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5600                        || res.lastTagPrefix.equals(prefix))) {
5601                    return res.lastTag;
5602                }
5603                res.lastTagPrefix = prefix;
5604                StringBuilder sb = new StringBuilder(128);
5605                if (prefix != null) {
5606                    sb.append(prefix);
5607                }
5608                if (intent.getAction() != null) {
5609                    sb.append(intent.getAction());
5610                } else if (intent.getComponent() != null) {
5611                    intent.getComponent().appendShortString(sb);
5612                } else {
5613                    sb.append("?");
5614                }
5615                return res.lastTag = sb.toString();
5616            }
5617        } catch (ClassCastException e) {
5618        }
5619        return null;
5620    }
5621
5622    @Override
5623    public void setProcessLimit(int max) {
5624        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5625                "setProcessLimit()");
5626        synchronized (this) {
5627            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5628            mProcessLimitOverride = max;
5629        }
5630        trimApplications();
5631    }
5632
5633    @Override
5634    public int getProcessLimit() {
5635        synchronized (this) {
5636            return mProcessLimitOverride;
5637        }
5638    }
5639
5640    void foregroundTokenDied(ForegroundToken token) {
5641        synchronized (ActivityManagerService.this) {
5642            synchronized (mPidsSelfLocked) {
5643                ForegroundToken cur
5644                    = mForegroundProcesses.get(token.pid);
5645                if (cur != token) {
5646                    return;
5647                }
5648                mForegroundProcesses.remove(token.pid);
5649                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5650                if (pr == null) {
5651                    return;
5652                }
5653                pr.forcingToForeground = null;
5654                updateProcessForegroundLocked(pr, false, false);
5655            }
5656            updateOomAdjLocked();
5657        }
5658    }
5659
5660    @Override
5661    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5662        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5663                "setProcessForeground()");
5664        synchronized(this) {
5665            boolean changed = false;
5666
5667            synchronized (mPidsSelfLocked) {
5668                ProcessRecord pr = mPidsSelfLocked.get(pid);
5669                if (pr == null && isForeground) {
5670                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5671                    return;
5672                }
5673                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5674                if (oldToken != null) {
5675                    oldToken.token.unlinkToDeath(oldToken, 0);
5676                    mForegroundProcesses.remove(pid);
5677                    if (pr != null) {
5678                        pr.forcingToForeground = null;
5679                    }
5680                    changed = true;
5681                }
5682                if (isForeground && token != null) {
5683                    ForegroundToken newToken = new ForegroundToken() {
5684                        @Override
5685                        public void binderDied() {
5686                            foregroundTokenDied(this);
5687                        }
5688                    };
5689                    newToken.pid = pid;
5690                    newToken.token = token;
5691                    try {
5692                        token.linkToDeath(newToken, 0);
5693                        mForegroundProcesses.put(pid, newToken);
5694                        pr.forcingToForeground = token;
5695                        changed = true;
5696                    } catch (RemoteException e) {
5697                        // If the process died while doing this, we will later
5698                        // do the cleanup with the process death link.
5699                    }
5700                }
5701            }
5702
5703            if (changed) {
5704                updateOomAdjLocked();
5705            }
5706        }
5707    }
5708
5709    // =========================================================
5710    // PERMISSIONS
5711    // =========================================================
5712
5713    static class PermissionController extends IPermissionController.Stub {
5714        ActivityManagerService mActivityManagerService;
5715        PermissionController(ActivityManagerService activityManagerService) {
5716            mActivityManagerService = activityManagerService;
5717        }
5718
5719        @Override
5720        public boolean checkPermission(String permission, int pid, int uid) {
5721            return mActivityManagerService.checkPermission(permission, pid,
5722                    uid) == PackageManager.PERMISSION_GRANTED;
5723        }
5724    }
5725
5726    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5727        @Override
5728        public int checkComponentPermission(String permission, int pid, int uid,
5729                int owningUid, boolean exported) {
5730            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5731                    owningUid, exported);
5732        }
5733
5734        @Override
5735        public Object getAMSLock() {
5736            return ActivityManagerService.this;
5737        }
5738    }
5739
5740    /**
5741     * This can be called with or without the global lock held.
5742     */
5743    int checkComponentPermission(String permission, int pid, int uid,
5744            int owningUid, boolean exported) {
5745        // We might be performing an operation on behalf of an indirect binder
5746        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5747        // client identity accordingly before proceeding.
5748        Identity tlsIdentity = sCallerIdentity.get();
5749        if (tlsIdentity != null) {
5750            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5751                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5752            uid = tlsIdentity.uid;
5753            pid = tlsIdentity.pid;
5754        }
5755
5756        if (pid == MY_PID) {
5757            return PackageManager.PERMISSION_GRANTED;
5758        }
5759
5760        return ActivityManager.checkComponentPermission(permission, uid,
5761                owningUid, exported);
5762    }
5763
5764    /**
5765     * As the only public entry point for permissions checking, this method
5766     * can enforce the semantic that requesting a check on a null global
5767     * permission is automatically denied.  (Internally a null permission
5768     * string is used when calling {@link #checkComponentPermission} in cases
5769     * when only uid-based security is needed.)
5770     *
5771     * This can be called with or without the global lock held.
5772     */
5773    @Override
5774    public int checkPermission(String permission, int pid, int uid) {
5775        if (permission == null) {
5776            return PackageManager.PERMISSION_DENIED;
5777        }
5778        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5779    }
5780
5781    /**
5782     * Binder IPC calls go through the public entry point.
5783     * This can be called with or without the global lock held.
5784     */
5785    int checkCallingPermission(String permission) {
5786        return checkPermission(permission,
5787                Binder.getCallingPid(),
5788                UserHandle.getAppId(Binder.getCallingUid()));
5789    }
5790
5791    /**
5792     * This can be called with or without the global lock held.
5793     */
5794    void enforceCallingPermission(String permission, String func) {
5795        if (checkCallingPermission(permission)
5796                == PackageManager.PERMISSION_GRANTED) {
5797            return;
5798        }
5799
5800        String msg = "Permission Denial: " + func + " from pid="
5801                + Binder.getCallingPid()
5802                + ", uid=" + Binder.getCallingUid()
5803                + " requires " + permission;
5804        Slog.w(TAG, msg);
5805        throw new SecurityException(msg);
5806    }
5807
5808    /**
5809     * Determine if UID is holding permissions required to access {@link Uri} in
5810     * the given {@link ProviderInfo}. Final permission checking is always done
5811     * in {@link ContentProvider}.
5812     */
5813    private final boolean checkHoldingPermissionsLocked(
5814            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5815        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5816                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5817
5818        if (pi.applicationInfo.uid == uid) {
5819            return true;
5820        } else if (!pi.exported) {
5821            return false;
5822        }
5823
5824        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5825        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5826        try {
5827            // check if target holds top-level <provider> permissions
5828            if (!readMet && pi.readPermission != null
5829                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5830                readMet = true;
5831            }
5832            if (!writeMet && pi.writePermission != null
5833                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5834                writeMet = true;
5835            }
5836
5837            // track if unprotected read/write is allowed; any denied
5838            // <path-permission> below removes this ability
5839            boolean allowDefaultRead = pi.readPermission == null;
5840            boolean allowDefaultWrite = pi.writePermission == null;
5841
5842            // check if target holds any <path-permission> that match uri
5843            final PathPermission[] pps = pi.pathPermissions;
5844            if (pps != null) {
5845                final String path = uri.getPath();
5846                int i = pps.length;
5847                while (i > 0 && (!readMet || !writeMet)) {
5848                    i--;
5849                    PathPermission pp = pps[i];
5850                    if (pp.match(path)) {
5851                        if (!readMet) {
5852                            final String pprperm = pp.getReadPermission();
5853                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5854                                    + pprperm + " for " + pp.getPath()
5855                                    + ": match=" + pp.match(path)
5856                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5857                            if (pprperm != null) {
5858                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5859                                    readMet = true;
5860                                } else {
5861                                    allowDefaultRead = false;
5862                                }
5863                            }
5864                        }
5865                        if (!writeMet) {
5866                            final String ppwperm = pp.getWritePermission();
5867                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5868                                    + ppwperm + " for " + pp.getPath()
5869                                    + ": match=" + pp.match(path)
5870                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5871                            if (ppwperm != null) {
5872                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5873                                    writeMet = true;
5874                                } else {
5875                                    allowDefaultWrite = false;
5876                                }
5877                            }
5878                        }
5879                    }
5880                }
5881            }
5882
5883            // grant unprotected <provider> read/write, if not blocked by
5884            // <path-permission> above
5885            if (allowDefaultRead) readMet = true;
5886            if (allowDefaultWrite) writeMet = true;
5887
5888        } catch (RemoteException e) {
5889            return false;
5890        }
5891
5892        return readMet && writeMet;
5893    }
5894
5895    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5896        ProviderInfo pi = null;
5897        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5898        if (cpr != null) {
5899            pi = cpr.info;
5900        } else {
5901            try {
5902                pi = AppGlobals.getPackageManager().resolveContentProvider(
5903                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5904            } catch (RemoteException ex) {
5905            }
5906        }
5907        return pi;
5908    }
5909
5910    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5911        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5912        if (targetUris != null) {
5913            return targetUris.get(uri);
5914        } else {
5915            return null;
5916        }
5917    }
5918
5919    private UriPermission findOrCreateUriPermissionLocked(
5920            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5921        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5922        if (targetUris == null) {
5923            targetUris = Maps.newArrayMap();
5924            mGrantedUriPermissions.put(targetUid, targetUris);
5925        }
5926
5927        UriPermission perm = targetUris.get(uri);
5928        if (perm == null) {
5929            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5930            targetUris.put(uri, perm);
5931        }
5932
5933        return perm;
5934    }
5935
5936    private final boolean checkUriPermissionLocked(
5937            Uri uri, int uid, int modeFlags, int minStrength) {
5938        // Root gets to do everything.
5939        if (uid == 0) {
5940            return true;
5941        }
5942        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5943        if (perms == null) return false;
5944        UriPermission perm = perms.get(uri);
5945        if (perm == null) return false;
5946        return perm.getStrength(modeFlags) >= minStrength;
5947    }
5948
5949    @Override
5950    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5951        enforceNotIsolatedCaller("checkUriPermission");
5952
5953        // Another redirected-binder-call permissions check as in
5954        // {@link checkComponentPermission}.
5955        Identity tlsIdentity = sCallerIdentity.get();
5956        if (tlsIdentity != null) {
5957            uid = tlsIdentity.uid;
5958            pid = tlsIdentity.pid;
5959        }
5960
5961        // Our own process gets to do everything.
5962        if (pid == MY_PID) {
5963            return PackageManager.PERMISSION_GRANTED;
5964        }
5965        synchronized(this) {
5966            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5967                    ? PackageManager.PERMISSION_GRANTED
5968                    : PackageManager.PERMISSION_DENIED;
5969        }
5970    }
5971
5972    /**
5973     * Check if the targetPkg can be granted permission to access uri by
5974     * the callingUid using the given modeFlags.  Throws a security exception
5975     * if callingUid is not allowed to do this.  Returns the uid of the target
5976     * if the URI permission grant should be performed; returns -1 if it is not
5977     * needed (for example targetPkg already has permission to access the URI).
5978     * If you already know the uid of the target, you can supply it in
5979     * lastTargetUid else set that to -1.
5980     */
5981    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5982            Uri uri, int modeFlags, int lastTargetUid) {
5983        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5984        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5985                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5986        if (modeFlags == 0) {
5987            return -1;
5988        }
5989
5990        if (targetPkg != null) {
5991            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5992                    "Checking grant " + targetPkg + " permission to " + uri);
5993        }
5994
5995        final IPackageManager pm = AppGlobals.getPackageManager();
5996
5997        // If this is not a content: uri, we can't do anything with it.
5998        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5999            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6000                    "Can't grant URI permission for non-content URI: " + uri);
6001            return -1;
6002        }
6003
6004        final String authority = uri.getAuthority();
6005        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6006        if (pi == null) {
6007            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6008            return -1;
6009        }
6010
6011        int targetUid = lastTargetUid;
6012        if (targetUid < 0 && targetPkg != null) {
6013            try {
6014                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6015                if (targetUid < 0) {
6016                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6017                            "Can't grant URI permission no uid for: " + targetPkg);
6018                    return -1;
6019                }
6020            } catch (RemoteException ex) {
6021                return -1;
6022            }
6023        }
6024
6025        if (targetUid >= 0) {
6026            // First...  does the target actually need this permission?
6027            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6028                // No need to grant the target this permission.
6029                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6030                        "Target " + targetPkg + " already has full permission to " + uri);
6031                return -1;
6032            }
6033        } else {
6034            // First...  there is no target package, so can anyone access it?
6035            boolean allowed = pi.exported;
6036            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6037                if (pi.readPermission != null) {
6038                    allowed = false;
6039                }
6040            }
6041            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6042                if (pi.writePermission != null) {
6043                    allowed = false;
6044                }
6045            }
6046            if (allowed) {
6047                return -1;
6048            }
6049        }
6050
6051        // Second...  is the provider allowing granting of URI permissions?
6052        if (!pi.grantUriPermissions) {
6053            throw new SecurityException("Provider " + pi.packageName
6054                    + "/" + pi.name
6055                    + " does not allow granting of Uri permissions (uri "
6056                    + uri + ")");
6057        }
6058        if (pi.uriPermissionPatterns != null) {
6059            final int N = pi.uriPermissionPatterns.length;
6060            boolean allowed = false;
6061            for (int i=0; i<N; i++) {
6062                if (pi.uriPermissionPatterns[i] != null
6063                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6064                    allowed = true;
6065                    break;
6066                }
6067            }
6068            if (!allowed) {
6069                throw new SecurityException("Provider " + pi.packageName
6070                        + "/" + pi.name
6071                        + " does not allow granting of permission to path of Uri "
6072                        + uri);
6073            }
6074        }
6075
6076        // Third...  does the caller itself have permission to access
6077        // this uri?
6078        if (callingUid != Process.myUid()) {
6079            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6080                // Require they hold a strong enough Uri permission
6081                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6082                        : UriPermission.STRENGTH_OWNED;
6083                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6084                    throw new SecurityException("Uid " + callingUid
6085                            + " does not have permission to uri " + uri);
6086                }
6087            }
6088        }
6089
6090        return targetUid;
6091    }
6092
6093    @Override
6094    public int checkGrantUriPermission(int callingUid, String targetPkg,
6095            Uri uri, int modeFlags) {
6096        enforceNotIsolatedCaller("checkGrantUriPermission");
6097        synchronized(this) {
6098            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6099        }
6100    }
6101
6102    void grantUriPermissionUncheckedLocked(
6103            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6104        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6105        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6106                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6107        if (modeFlags == 0) {
6108            return;
6109        }
6110
6111        // So here we are: the caller has the assumed permission
6112        // to the uri, and the target doesn't.  Let's now give this to
6113        // the target.
6114
6115        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6116                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6117
6118        final String authority = uri.getAuthority();
6119        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6120        if (pi == null) {
6121            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6122            return;
6123        }
6124
6125        final UriPermission perm = findOrCreateUriPermissionLocked(
6126                pi.packageName, targetPkg, targetUid, uri);
6127        perm.grantModes(modeFlags, persistable, owner);
6128    }
6129
6130    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6131            int modeFlags, UriPermissionOwner owner) {
6132        if (targetPkg == null) {
6133            throw new NullPointerException("targetPkg");
6134        }
6135
6136        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6137        if (targetUid < 0) {
6138            return;
6139        }
6140
6141        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6142    }
6143
6144    static class NeededUriGrants extends ArrayList<Uri> {
6145        final String targetPkg;
6146        final int targetUid;
6147        final int flags;
6148
6149        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6150            this.targetPkg = targetPkg;
6151            this.targetUid = targetUid;
6152            this.flags = flags;
6153        }
6154    }
6155
6156    /**
6157     * Like checkGrantUriPermissionLocked, but takes an Intent.
6158     */
6159    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6160            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6161        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6162                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6163                + " clip=" + (intent != null ? intent.getClipData() : null)
6164                + " from " + intent + "; flags=0x"
6165                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6166
6167        if (targetPkg == null) {
6168            throw new NullPointerException("targetPkg");
6169        }
6170
6171        if (intent == null) {
6172            return null;
6173        }
6174        Uri data = intent.getData();
6175        ClipData clip = intent.getClipData();
6176        if (data == null && clip == null) {
6177            return null;
6178        }
6179
6180        if (data != null) {
6181            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6182                mode, needed != null ? needed.targetUid : -1);
6183            if (targetUid > 0) {
6184                if (needed == null) {
6185                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6186                }
6187                needed.add(data);
6188            }
6189        }
6190        if (clip != null) {
6191            for (int i=0; i<clip.getItemCount(); i++) {
6192                Uri uri = clip.getItemAt(i).getUri();
6193                if (uri != null) {
6194                    int targetUid = -1;
6195                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6196                            mode, needed != null ? needed.targetUid : -1);
6197                    if (targetUid > 0) {
6198                        if (needed == null) {
6199                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6200                        }
6201                        needed.add(uri);
6202                    }
6203                } else {
6204                    Intent clipIntent = clip.getItemAt(i).getIntent();
6205                    if (clipIntent != null) {
6206                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6207                                callingUid, targetPkg, clipIntent, mode, needed);
6208                        if (newNeeded != null) {
6209                            needed = newNeeded;
6210                        }
6211                    }
6212                }
6213            }
6214        }
6215
6216        return needed;
6217    }
6218
6219    /**
6220     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6221     */
6222    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6223            UriPermissionOwner owner) {
6224        if (needed != null) {
6225            for (int i=0; i<needed.size(); i++) {
6226                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6227                        needed.get(i), needed.flags, owner);
6228            }
6229        }
6230    }
6231
6232    void grantUriPermissionFromIntentLocked(int callingUid,
6233            String targetPkg, Intent intent, UriPermissionOwner owner) {
6234        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6235                intent, intent != null ? intent.getFlags() : 0, null);
6236        if (needed == null) {
6237            return;
6238        }
6239
6240        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6241    }
6242
6243    @Override
6244    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6245            Uri uri, int modeFlags) {
6246        enforceNotIsolatedCaller("grantUriPermission");
6247        synchronized(this) {
6248            final ProcessRecord r = getRecordForAppLocked(caller);
6249            if (r == null) {
6250                throw new SecurityException("Unable to find app for caller "
6251                        + caller
6252                        + " when granting permission to uri " + uri);
6253            }
6254            if (targetPkg == null) {
6255                throw new IllegalArgumentException("null target");
6256            }
6257            if (uri == null) {
6258                throw new IllegalArgumentException("null uri");
6259            }
6260
6261            // Persistable only supported through Intents
6262            Preconditions.checkFlagsArgument(modeFlags,
6263                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6264
6265            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6266                    null);
6267        }
6268    }
6269
6270    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6271        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6272                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6273            ArrayMap<Uri, UriPermission> perms
6274                    = mGrantedUriPermissions.get(perm.targetUid);
6275            if (perms != null) {
6276                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6277                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6278                perms.remove(perm.uri);
6279                if (perms.size() == 0) {
6280                    mGrantedUriPermissions.remove(perm.targetUid);
6281                }
6282            }
6283        }
6284    }
6285
6286    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6287        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6288
6289        final IPackageManager pm = AppGlobals.getPackageManager();
6290        final String authority = uri.getAuthority();
6291        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6292        if (pi == null) {
6293            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6294            return;
6295        }
6296
6297        // Does the caller have this permission on the URI?
6298        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6299            // Right now, if you are not the original owner of the permission,
6300            // you are not allowed to revoke it.
6301            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6302                throw new SecurityException("Uid " + callingUid
6303                        + " does not have permission to uri " + uri);
6304            //}
6305        }
6306
6307        boolean persistChanged = false;
6308
6309        // Go through all of the permissions and remove any that match.
6310        final List<String> SEGMENTS = uri.getPathSegments();
6311        if (SEGMENTS != null) {
6312            final int NS = SEGMENTS.size();
6313            int N = mGrantedUriPermissions.size();
6314            for (int i=0; i<N; i++) {
6315                ArrayMap<Uri, UriPermission> perms
6316                        = mGrantedUriPermissions.valueAt(i);
6317                Iterator<UriPermission> it = perms.values().iterator();
6318            toploop:
6319                while (it.hasNext()) {
6320                    UriPermission perm = it.next();
6321                    Uri targetUri = perm.uri;
6322                    if (!authority.equals(targetUri.getAuthority())) {
6323                        continue;
6324                    }
6325                    List<String> targetSegments = targetUri.getPathSegments();
6326                    if (targetSegments == null) {
6327                        continue;
6328                    }
6329                    if (targetSegments.size() < NS) {
6330                        continue;
6331                    }
6332                    for (int j=0; j<NS; j++) {
6333                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6334                            continue toploop;
6335                        }
6336                    }
6337                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6338                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6339                    persistChanged |= perm.clearModes(modeFlags, true);
6340                    if (perm.modeFlags == 0) {
6341                        it.remove();
6342                    }
6343                }
6344                if (perms.size() == 0) {
6345                    mGrantedUriPermissions.remove(
6346                            mGrantedUriPermissions.keyAt(i));
6347                    N--;
6348                    i--;
6349                }
6350            }
6351        }
6352
6353        if (persistChanged) {
6354            schedulePersistUriGrants();
6355        }
6356    }
6357
6358    @Override
6359    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6360            int modeFlags) {
6361        enforceNotIsolatedCaller("revokeUriPermission");
6362        synchronized(this) {
6363            final ProcessRecord r = getRecordForAppLocked(caller);
6364            if (r == null) {
6365                throw new SecurityException("Unable to find app for caller "
6366                        + caller
6367                        + " when revoking permission to uri " + uri);
6368            }
6369            if (uri == null) {
6370                Slog.w(TAG, "revokeUriPermission: null uri");
6371                return;
6372            }
6373
6374            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6375                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6376            if (modeFlags == 0) {
6377                return;
6378            }
6379
6380            final IPackageManager pm = AppGlobals.getPackageManager();
6381            final String authority = uri.getAuthority();
6382            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6383            if (pi == null) {
6384                Slog.w(TAG, "No content provider found for permission revoke: "
6385                        + uri.toSafeString());
6386                return;
6387            }
6388
6389            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6390        }
6391    }
6392
6393    /**
6394     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6395     * given package.
6396     *
6397     * @param packageName Package name to match, or {@code null} to apply to all
6398     *            packages.
6399     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6400     *            to all users.
6401     * @param persistable If persistable grants should be removed.
6402     */
6403    private void removeUriPermissionsForPackageLocked(
6404            String packageName, int userHandle, boolean persistable) {
6405        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6406            throw new IllegalArgumentException("Must narrow by either package or user");
6407        }
6408
6409        boolean persistChanged = false;
6410
6411        final int size = mGrantedUriPermissions.size();
6412        for (int i = 0; i < size; i++) {
6413            // Only inspect grants matching user
6414            if (userHandle == UserHandle.USER_ALL
6415                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6416                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6417                        .values().iterator();
6418                while (it.hasNext()) {
6419                    final UriPermission perm = it.next();
6420
6421                    // Only inspect grants matching package
6422                    if (packageName == null || perm.sourcePkg.equals(packageName)
6423                            || perm.targetPkg.equals(packageName)) {
6424                        persistChanged |= perm.clearModes(~0, persistable);
6425
6426                        // Only remove when no modes remain; any persisted grants
6427                        // will keep this alive.
6428                        if (perm.modeFlags == 0) {
6429                            it.remove();
6430                        }
6431                    }
6432                }
6433            }
6434        }
6435
6436        if (persistChanged) {
6437            schedulePersistUriGrants();
6438        }
6439    }
6440
6441    @Override
6442    public IBinder newUriPermissionOwner(String name) {
6443        enforceNotIsolatedCaller("newUriPermissionOwner");
6444        synchronized(this) {
6445            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6446            return owner.getExternalTokenLocked();
6447        }
6448    }
6449
6450    @Override
6451    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6452            Uri uri, int modeFlags) {
6453        synchronized(this) {
6454            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6455            if (owner == null) {
6456                throw new IllegalArgumentException("Unknown owner: " + token);
6457            }
6458            if (fromUid != Binder.getCallingUid()) {
6459                if (Binder.getCallingUid() != Process.myUid()) {
6460                    // Only system code can grant URI permissions on behalf
6461                    // of other users.
6462                    throw new SecurityException("nice try");
6463                }
6464            }
6465            if (targetPkg == null) {
6466                throw new IllegalArgumentException("null target");
6467            }
6468            if (uri == null) {
6469                throw new IllegalArgumentException("null uri");
6470            }
6471
6472            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6473        }
6474    }
6475
6476    @Override
6477    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6478        synchronized(this) {
6479            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6480            if (owner == null) {
6481                throw new IllegalArgumentException("Unknown owner: " + token);
6482            }
6483
6484            if (uri == null) {
6485                owner.removeUriPermissionsLocked(mode);
6486            } else {
6487                owner.removeUriPermissionLocked(uri, mode);
6488            }
6489        }
6490    }
6491
6492    private void schedulePersistUriGrants() {
6493        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6494            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6495                    10 * DateUtils.SECOND_IN_MILLIS);
6496        }
6497    }
6498
6499    private void writeGrantedUriPermissions() {
6500        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6501
6502        // Snapshot permissions so we can persist without lock
6503        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6504        synchronized (this) {
6505            final int size = mGrantedUriPermissions.size();
6506            for (int i = 0 ; i < size; i++) {
6507                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6508                    if (perm.persistedModeFlags != 0) {
6509                        persist.add(perm.snapshot());
6510                    }
6511                }
6512            }
6513        }
6514
6515        FileOutputStream fos = null;
6516        try {
6517            fos = mGrantFile.startWrite();
6518
6519            XmlSerializer out = new FastXmlSerializer();
6520            out.setOutput(fos, "utf-8");
6521            out.startDocument(null, true);
6522            out.startTag(null, TAG_URI_GRANTS);
6523            for (UriPermission.Snapshot perm : persist) {
6524                out.startTag(null, TAG_URI_GRANT);
6525                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6526                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6527                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6528                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6529                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6530                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6531                out.endTag(null, TAG_URI_GRANT);
6532            }
6533            out.endTag(null, TAG_URI_GRANTS);
6534            out.endDocument();
6535
6536            mGrantFile.finishWrite(fos);
6537        } catch (IOException e) {
6538            if (fos != null) {
6539                mGrantFile.failWrite(fos);
6540            }
6541        }
6542    }
6543
6544    private void readGrantedUriPermissionsLocked() {
6545        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6546
6547        final long now = System.currentTimeMillis();
6548
6549        FileInputStream fis = null;
6550        try {
6551            fis = mGrantFile.openRead();
6552            final XmlPullParser in = Xml.newPullParser();
6553            in.setInput(fis, null);
6554
6555            int type;
6556            while ((type = in.next()) != END_DOCUMENT) {
6557                final String tag = in.getName();
6558                if (type == START_TAG) {
6559                    if (TAG_URI_GRANT.equals(tag)) {
6560                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6561                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6562                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6563                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6564                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6565                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6566
6567                        // Sanity check that provider still belongs to source package
6568                        final ProviderInfo pi = getProviderInfoLocked(
6569                                uri.getAuthority(), userHandle);
6570                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6571                            int targetUid = -1;
6572                            try {
6573                                targetUid = AppGlobals.getPackageManager()
6574                                        .getPackageUid(targetPkg, userHandle);
6575                            } catch (RemoteException e) {
6576                            }
6577                            if (targetUid != -1) {
6578                                final UriPermission perm = findOrCreateUriPermissionLocked(
6579                                        sourcePkg, targetPkg, targetUid, uri);
6580                                perm.initPersistedModes(modeFlags, createdTime);
6581                            }
6582                        } else {
6583                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6584                                    + " but instead found " + pi);
6585                        }
6586                    }
6587                }
6588            }
6589        } catch (FileNotFoundException e) {
6590            // Missing grants is okay
6591        } catch (IOException e) {
6592            Log.wtf(TAG, "Failed reading Uri grants", e);
6593        } catch (XmlPullParserException e) {
6594            Log.wtf(TAG, "Failed reading Uri grants", e);
6595        } finally {
6596            IoUtils.closeQuietly(fis);
6597        }
6598    }
6599
6600    @Override
6601    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6602        enforceNotIsolatedCaller("takePersistableUriPermission");
6603
6604        Preconditions.checkFlagsArgument(modeFlags,
6605                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6606
6607        synchronized (this) {
6608            final int callingUid = Binder.getCallingUid();
6609            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6610            if (perm == null) {
6611                throw new SecurityException("No permission grant found for UID " + callingUid
6612                        + " and Uri " + uri.toSafeString());
6613            }
6614
6615            boolean persistChanged = perm.takePersistableModes(modeFlags);
6616            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6617
6618            if (persistChanged) {
6619                schedulePersistUriGrants();
6620            }
6621        }
6622    }
6623
6624    @Override
6625    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6626        enforceNotIsolatedCaller("releasePersistableUriPermission");
6627
6628        Preconditions.checkFlagsArgument(modeFlags,
6629                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6630
6631        synchronized (this) {
6632            final int callingUid = Binder.getCallingUid();
6633
6634            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6635            if (perm == null) {
6636                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6637                        + uri.toSafeString());
6638                return;
6639            }
6640
6641            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6642            removeUriPermissionIfNeededLocked(perm);
6643            if (persistChanged) {
6644                schedulePersistUriGrants();
6645            }
6646        }
6647    }
6648
6649    /**
6650     * Prune any older {@link UriPermission} for the given UID until outstanding
6651     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6652     *
6653     * @return if any mutations occured that require persisting.
6654     */
6655    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6656        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6657        if (perms == null) return false;
6658        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6659
6660        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6661        for (UriPermission perm : perms.values()) {
6662            if (perm.persistedModeFlags != 0) {
6663                persisted.add(perm);
6664            }
6665        }
6666
6667        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6668        if (trimCount <= 0) return false;
6669
6670        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6671        for (int i = 0; i < trimCount; i++) {
6672            final UriPermission perm = persisted.get(i);
6673
6674            if (DEBUG_URI_PERMISSION) {
6675                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6676            }
6677
6678            perm.releasePersistableModes(~0);
6679            removeUriPermissionIfNeededLocked(perm);
6680        }
6681
6682        return true;
6683    }
6684
6685    @Override
6686    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6687            String packageName, boolean incoming) {
6688        enforceNotIsolatedCaller("getPersistedUriPermissions");
6689        Preconditions.checkNotNull(packageName, "packageName");
6690
6691        final int callingUid = Binder.getCallingUid();
6692        final IPackageManager pm = AppGlobals.getPackageManager();
6693        try {
6694            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6695            if (packageUid != callingUid) {
6696                throw new SecurityException(
6697                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6698            }
6699        } catch (RemoteException e) {
6700            throw new SecurityException("Failed to verify package name ownership");
6701        }
6702
6703        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6704        synchronized (this) {
6705            if (incoming) {
6706                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6707                if (perms == null) {
6708                    Slog.w(TAG, "No permission grants found for " + packageName);
6709                } else {
6710                    final int size = perms.size();
6711                    for (int i = 0; i < size; i++) {
6712                        final UriPermission perm = perms.valueAt(i);
6713                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6714                            result.add(perm.buildPersistedPublicApiObject());
6715                        }
6716                    }
6717                }
6718            } else {
6719                final int size = mGrantedUriPermissions.size();
6720                for (int i = 0; i < size; i++) {
6721                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6722                    final int permsSize = perms.size();
6723                    for (int j = 0; j < permsSize; j++) {
6724                        final UriPermission perm = perms.valueAt(j);
6725                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6726                            result.add(perm.buildPersistedPublicApiObject());
6727                        }
6728                    }
6729                }
6730            }
6731        }
6732        return new ParceledListSlice<android.content.UriPermission>(result);
6733    }
6734
6735    @Override
6736    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6737        synchronized (this) {
6738            ProcessRecord app =
6739                who != null ? getRecordForAppLocked(who) : null;
6740            if (app == null) return;
6741
6742            Message msg = Message.obtain();
6743            msg.what = WAIT_FOR_DEBUGGER_MSG;
6744            msg.obj = app;
6745            msg.arg1 = waiting ? 1 : 0;
6746            mHandler.sendMessage(msg);
6747        }
6748    }
6749
6750    @Override
6751    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6752        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6753        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6754        outInfo.availMem = Process.getFreeMemory();
6755        outInfo.totalMem = Process.getTotalMemory();
6756        outInfo.threshold = homeAppMem;
6757        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6758        outInfo.hiddenAppThreshold = cachedAppMem;
6759        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6760                ProcessList.SERVICE_ADJ);
6761        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6762                ProcessList.VISIBLE_APP_ADJ);
6763        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6764                ProcessList.FOREGROUND_APP_ADJ);
6765    }
6766
6767    // =========================================================
6768    // TASK MANAGEMENT
6769    // =========================================================
6770
6771    @Override
6772    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6773                         IThumbnailReceiver receiver) {
6774        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6775
6776        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6777        ActivityRecord topRecord = null;
6778
6779        synchronized(this) {
6780            if (localLOGV) Slog.v(
6781                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6782                + ", receiver=" + receiver);
6783
6784            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6785                    != PackageManager.PERMISSION_GRANTED) {
6786                if (receiver != null) {
6787                    // If the caller wants to wait for pending thumbnails,
6788                    // it ain't gonna get them.
6789                    try {
6790                        receiver.finished();
6791                    } catch (RemoteException ex) {
6792                    }
6793                }
6794                String msg = "Permission Denial: getTasks() from pid="
6795                        + Binder.getCallingPid()
6796                        + ", uid=" + Binder.getCallingUid()
6797                        + " requires " + android.Manifest.permission.GET_TASKS;
6798                Slog.w(TAG, msg);
6799                throw new SecurityException(msg);
6800            }
6801
6802            // TODO: Improve with MRU list from all ActivityStacks.
6803            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6804
6805            if (!pending.pendingRecords.isEmpty()) {
6806                mPendingThumbnails.add(pending);
6807            }
6808        }
6809
6810        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6811
6812        if (topRecord != null) {
6813            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6814            try {
6815                IApplicationThread topThumbnail = topRecord.app.thread;
6816                topThumbnail.requestThumbnail(topRecord.appToken);
6817            } catch (Exception e) {
6818                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6819                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6820            }
6821        }
6822
6823        if (pending.pendingRecords.isEmpty() && receiver != null) {
6824            // In this case all thumbnails were available and the client
6825            // is being asked to be told when the remaining ones come in...
6826            // which is unusually, since the top-most currently running
6827            // activity should never have a canned thumbnail!  Oh well.
6828            try {
6829                receiver.finished();
6830            } catch (RemoteException ex) {
6831            }
6832        }
6833
6834        return list;
6835    }
6836
6837    TaskRecord getMostRecentTask() {
6838        return mRecentTasks.get(0);
6839    }
6840
6841    @Override
6842    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6843            int flags, int userId) {
6844        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6845                false, true, "getRecentTasks", null);
6846
6847        synchronized (this) {
6848            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6849                    "getRecentTasks()");
6850            final boolean detailed = checkCallingPermission(
6851                    android.Manifest.permission.GET_DETAILED_TASKS)
6852                    == PackageManager.PERMISSION_GRANTED;
6853
6854            IPackageManager pm = AppGlobals.getPackageManager();
6855
6856            final int N = mRecentTasks.size();
6857            ArrayList<ActivityManager.RecentTaskInfo> res
6858                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6859                            maxNum < N ? maxNum : N);
6860
6861            final Set<Integer> includedUsers;
6862            if ((flags & ActivityManager.RECENT_INCLUDE_RELATED) != 0) {
6863                includedUsers = getRelatedUsersLocked(userId);
6864            } else {
6865                includedUsers = new HashSet<Integer>();
6866            }
6867            includedUsers.add(Integer.valueOf(userId));
6868            for (int i=0; i<N && maxNum > 0; i++) {
6869                TaskRecord tr = mRecentTasks.get(i);
6870                // Only add calling user or related users recent tasks
6871                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6872
6873                // Return the entry if desired by the caller.  We always return
6874                // the first entry, because callers always expect this to be the
6875                // foreground app.  We may filter others if the caller has
6876                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6877                // we should exclude the entry.
6878
6879                if (i == 0
6880                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6881                        || (tr.intent == null)
6882                        || ((tr.intent.getFlags()
6883                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6884                    ActivityManager.RecentTaskInfo rti
6885                            = new ActivityManager.RecentTaskInfo();
6886                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6887                    rti.persistentId = tr.taskId;
6888                    rti.baseIntent = new Intent(
6889                            tr.intent != null ? tr.intent : tr.affinityIntent);
6890                    if (!detailed) {
6891                        rti.baseIntent.replaceExtras((Bundle)null);
6892                    }
6893                    rti.origActivity = tr.origActivity;
6894                    rti.description = tr.lastDescription;
6895                    rti.stackId = tr.stack.mStackId;
6896                    rti.userId = tr.userId;
6897
6898                    // Traverse upwards looking for any break between main task activities and
6899                    // utility activities.
6900                    final ArrayList<ActivityRecord> activities = tr.mActivities;
6901                    int activityNdx;
6902                    final int numActivities = activities.size();
6903                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
6904                            ++activityNdx) {
6905                        final ActivityRecord r = activities.get(activityNdx);
6906                        if (r.intent != null &&
6907                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
6908                                        != 0) {
6909                            break;
6910                        }
6911                    }
6912                    // Traverse downwards starting below break looking for set label and icon.
6913                    for (--activityNdx; activityNdx >= 0; --activityNdx) {
6914                        final ActivityRecord r = activities.get(activityNdx);
6915                        if (r.activityLabel != null || r.activityIcon != null) {
6916                            rti.activityLabel = r.activityLabel;
6917                            rti.activityIcon = r.activityIcon;
6918                            break;
6919                        }
6920                    }
6921
6922                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6923                        // Check whether this activity is currently available.
6924                        try {
6925                            if (rti.origActivity != null) {
6926                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6927                                        == null) {
6928                                    continue;
6929                                }
6930                            } else if (rti.baseIntent != null) {
6931                                if (pm.queryIntentActivities(rti.baseIntent,
6932                                        null, 0, userId) == null) {
6933                                    continue;
6934                                }
6935                            }
6936                        } catch (RemoteException e) {
6937                            // Will never happen.
6938                        }
6939                    }
6940
6941                    res.add(rti);
6942                    maxNum--;
6943                }
6944            }
6945            return res;
6946        }
6947    }
6948
6949    private TaskRecord recentTaskForIdLocked(int id) {
6950        final int N = mRecentTasks.size();
6951            for (int i=0; i<N; i++) {
6952                TaskRecord tr = mRecentTasks.get(i);
6953                if (tr.taskId == id) {
6954                    return tr;
6955                }
6956            }
6957            return null;
6958    }
6959
6960    @Override
6961    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6962        synchronized (this) {
6963            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6964                    "getTaskThumbnails()");
6965            TaskRecord tr = recentTaskForIdLocked(id);
6966            if (tr != null) {
6967                return tr.getTaskThumbnailsLocked();
6968            }
6969        }
6970        return null;
6971    }
6972
6973    @Override
6974    public Bitmap getTaskTopThumbnail(int id) {
6975        synchronized (this) {
6976            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6977                    "getTaskTopThumbnail()");
6978            TaskRecord tr = recentTaskForIdLocked(id);
6979            if (tr != null) {
6980                return tr.getTaskTopThumbnailLocked();
6981            }
6982        }
6983        return null;
6984    }
6985
6986    @Override
6987    public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel,
6988            Bitmap activityIcon) {
6989        synchronized (this) {
6990            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6991            if (r != null) {
6992                r.activityLabel = activityLabel.toString();
6993                r.activityIcon = activityIcon;
6994            }
6995        }
6996    }
6997
6998    @Override
6999    public boolean removeSubTask(int taskId, int subTaskIndex) {
7000        synchronized (this) {
7001            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7002                    "removeSubTask()");
7003            long ident = Binder.clearCallingIdentity();
7004            try {
7005                TaskRecord tr = recentTaskForIdLocked(taskId);
7006                if (tr != null) {
7007                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7008                }
7009                return false;
7010            } finally {
7011                Binder.restoreCallingIdentity(ident);
7012            }
7013        }
7014    }
7015
7016    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7017        if (!pr.killedByAm) {
7018            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7019            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7020                    pr.processName, pr.setAdj, reason);
7021            pr.killedByAm = true;
7022            Process.killProcessQuiet(pr.pid);
7023        }
7024    }
7025
7026    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7027        tr.disposeThumbnail();
7028        mRecentTasks.remove(tr);
7029        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7030        Intent baseIntent = new Intent(
7031                tr.intent != null ? tr.intent : tr.affinityIntent);
7032        ComponentName component = baseIntent.getComponent();
7033        if (component == null) {
7034            Slog.w(TAG, "Now component for base intent of task: " + tr);
7035            return;
7036        }
7037
7038        // Find any running services associated with this app.
7039        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7040
7041        if (killProcesses) {
7042            // Find any running processes associated with this app.
7043            final String pkg = component.getPackageName();
7044            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7045            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7046            for (int i=0; i<pmap.size(); i++) {
7047                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7048                for (int j=0; j<uids.size(); j++) {
7049                    ProcessRecord proc = uids.valueAt(j);
7050                    if (proc.userId != tr.userId) {
7051                        continue;
7052                    }
7053                    if (!proc.pkgList.containsKey(pkg)) {
7054                        continue;
7055                    }
7056                    procs.add(proc);
7057                }
7058            }
7059
7060            // Kill the running processes.
7061            for (int i=0; i<procs.size(); i++) {
7062                ProcessRecord pr = procs.get(i);
7063                if (pr == mHomeProcess) {
7064                    // Don't kill the home process along with tasks from the same package.
7065                    continue;
7066                }
7067                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7068                    killUnneededProcessLocked(pr, "remove task");
7069                } else {
7070                    pr.waitingToKill = "remove task";
7071                }
7072            }
7073        }
7074    }
7075
7076    @Override
7077    public boolean removeTask(int taskId, int flags) {
7078        synchronized (this) {
7079            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7080                    "removeTask()");
7081            long ident = Binder.clearCallingIdentity();
7082            try {
7083                TaskRecord tr = recentTaskForIdLocked(taskId);
7084                if (tr != null) {
7085                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7086                    if (r != null) {
7087                        cleanUpRemovedTaskLocked(tr, flags);
7088                        return true;
7089                    }
7090                    if (tr.mActivities.size() == 0) {
7091                        // Caller is just removing a recent task that is
7092                        // not actively running.  That is easy!
7093                        cleanUpRemovedTaskLocked(tr, flags);
7094                        return true;
7095                    }
7096                    Slog.w(TAG, "removeTask: task " + taskId
7097                            + " does not have activities to remove, "
7098                            + " but numActivities=" + tr.numActivities
7099                            + ": " + tr);
7100                }
7101            } finally {
7102                Binder.restoreCallingIdentity(ident);
7103            }
7104        }
7105        return false;
7106    }
7107
7108    /**
7109     * TODO: Add mController hook
7110     */
7111    @Override
7112    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7113        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7114                "moveTaskToFront()");
7115
7116        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7117        synchronized(this) {
7118            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7119                    Binder.getCallingUid(), "Task to front")) {
7120                ActivityOptions.abort(options);
7121                return;
7122            }
7123            final long origId = Binder.clearCallingIdentity();
7124            try {
7125                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7126                if (task == null) {
7127                    return;
7128                }
7129                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7130                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7131                    return;
7132                }
7133                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7134            } finally {
7135                Binder.restoreCallingIdentity(origId);
7136            }
7137            ActivityOptions.abort(options);
7138        }
7139    }
7140
7141    @Override
7142    public void moveTaskToBack(int taskId) {
7143        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7144                "moveTaskToBack()");
7145
7146        synchronized(this) {
7147            TaskRecord tr = recentTaskForIdLocked(taskId);
7148            if (tr != null) {
7149                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7150                ActivityStack stack = tr.stack;
7151                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7152                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7153                            Binder.getCallingUid(), "Task to back")) {
7154                        return;
7155                    }
7156                }
7157                final long origId = Binder.clearCallingIdentity();
7158                try {
7159                    stack.moveTaskToBackLocked(taskId, null);
7160                } finally {
7161                    Binder.restoreCallingIdentity(origId);
7162                }
7163            }
7164        }
7165    }
7166
7167    /**
7168     * Moves an activity, and all of the other activities within the same task, to the bottom
7169     * of the history stack.  The activity's order within the task is unchanged.
7170     *
7171     * @param token A reference to the activity we wish to move
7172     * @param nonRoot If false then this only works if the activity is the root
7173     *                of a task; if true it will work for any activity in a task.
7174     * @return Returns true if the move completed, false if not.
7175     */
7176    @Override
7177    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7178        enforceNotIsolatedCaller("moveActivityTaskToBack");
7179        synchronized(this) {
7180            final long origId = Binder.clearCallingIdentity();
7181            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7182            if (taskId >= 0) {
7183                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7184            }
7185            Binder.restoreCallingIdentity(origId);
7186        }
7187        return false;
7188    }
7189
7190    @Override
7191    public void moveTaskBackwards(int task) {
7192        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7193                "moveTaskBackwards()");
7194
7195        synchronized(this) {
7196            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7197                    Binder.getCallingUid(), "Task backwards")) {
7198                return;
7199            }
7200            final long origId = Binder.clearCallingIdentity();
7201            moveTaskBackwardsLocked(task);
7202            Binder.restoreCallingIdentity(origId);
7203        }
7204    }
7205
7206    private final void moveTaskBackwardsLocked(int task) {
7207        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7208    }
7209
7210    @Override
7211    public IBinder getHomeActivityToken() throws RemoteException {
7212        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7213                "getHomeActivityToken()");
7214        synchronized (this) {
7215            return mStackSupervisor.getHomeActivityToken();
7216        }
7217    }
7218
7219    @Override
7220    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7221            IActivityContainerCallback callback) throws RemoteException {
7222        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7223                "createActivityContainer()");
7224        synchronized (this) {
7225            if (parentActivityToken == null) {
7226                throw new IllegalArgumentException("parent token must not be null");
7227            }
7228            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7229            if (r == null) {
7230                return null;
7231            }
7232            return mStackSupervisor.createActivityContainer(r, callback);
7233        }
7234    }
7235
7236    @Override
7237    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7238        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7239                "deleteActivityContainer()");
7240        synchronized (this) {
7241            mStackSupervisor.deleteActivityContainer(container);
7242        }
7243    }
7244
7245    @Override
7246    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7247            throws RemoteException {
7248        synchronized (this) {
7249            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7250            if (stack != null) {
7251                return stack.mActivityContainer;
7252            }
7253            return null;
7254        }
7255    }
7256
7257    @Override
7258    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7259        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7260                "moveTaskToStack()");
7261        if (stackId == HOME_STACK_ID) {
7262            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7263                    new RuntimeException("here").fillInStackTrace());
7264        }
7265        synchronized (this) {
7266            long ident = Binder.clearCallingIdentity();
7267            try {
7268                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7269                        + stackId + " toTop=" + toTop);
7270                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7271            } finally {
7272                Binder.restoreCallingIdentity(ident);
7273            }
7274        }
7275    }
7276
7277    @Override
7278    public void resizeStack(int stackBoxId, Rect bounds) {
7279        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7280                "resizeStackBox()");
7281        long ident = Binder.clearCallingIdentity();
7282        try {
7283            mWindowManager.resizeStack(stackBoxId, bounds);
7284        } finally {
7285            Binder.restoreCallingIdentity(ident);
7286        }
7287    }
7288
7289    @Override
7290    public List<StackInfo> getAllStackInfos() {
7291        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7292                "getAllStackInfos()");
7293        long ident = Binder.clearCallingIdentity();
7294        try {
7295            synchronized (this) {
7296                return mStackSupervisor.getAllStackInfosLocked();
7297            }
7298        } finally {
7299            Binder.restoreCallingIdentity(ident);
7300        }
7301    }
7302
7303    @Override
7304    public StackInfo getStackInfo(int stackId) {
7305        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7306                "getStackInfo()");
7307        long ident = Binder.clearCallingIdentity();
7308        try {
7309            synchronized (this) {
7310                return mStackSupervisor.getStackInfoLocked(stackId);
7311            }
7312        } finally {
7313            Binder.restoreCallingIdentity(ident);
7314        }
7315    }
7316
7317    @Override
7318    public boolean isInHomeStack(int taskId) {
7319        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7320                "getStackInfo()");
7321        long ident = Binder.clearCallingIdentity();
7322        try {
7323            synchronized (this) {
7324                TaskRecord tr = recentTaskForIdLocked(taskId);
7325                if (tr != null) {
7326                    return tr.stack.isHomeStack();
7327                }
7328            }
7329        } finally {
7330            Binder.restoreCallingIdentity(ident);
7331        }
7332        return false;
7333    }
7334
7335    @Override
7336    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7337        synchronized(this) {
7338            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7339        }
7340    }
7341
7342    private boolean isLockTaskAuthorized(ComponentName name) {
7343//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7344//                "startLockTaskMode()");
7345//        DevicePolicyManager dpm = (DevicePolicyManager)
7346//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7347//        return dpm != null && dpm.isLockTaskPermitted(name);
7348        return true;
7349    }
7350
7351    private void startLockTaskMode(TaskRecord task) {
7352        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7353            return;
7354        }
7355        long ident = Binder.clearCallingIdentity();
7356        try {
7357            synchronized (this) {
7358                // Since we lost lock on task, make sure it is still there.
7359                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7360                if (task != null) {
7361                    mStackSupervisor.setLockTaskModeLocked(task);
7362                }
7363            }
7364        } finally {
7365            Binder.restoreCallingIdentity(ident);
7366        }
7367    }
7368
7369    @Override
7370    public void startLockTaskMode(int taskId) {
7371        long ident = Binder.clearCallingIdentity();
7372        try {
7373            final TaskRecord task;
7374            synchronized (this) {
7375                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7376            }
7377            if (task != null) {
7378                startLockTaskMode(task);
7379            }
7380        } finally {
7381            Binder.restoreCallingIdentity(ident);
7382        }
7383    }
7384
7385    @Override
7386    public void startLockTaskMode(IBinder token) {
7387        long ident = Binder.clearCallingIdentity();
7388        try {
7389            final TaskRecord task;
7390            synchronized (this) {
7391                final ActivityRecord r = ActivityRecord.forToken(token);
7392                if (r == null) {
7393                    return;
7394                }
7395                task = r.task;
7396            }
7397            if (task != null) {
7398                startLockTaskMode(task);
7399            }
7400        } finally {
7401            Binder.restoreCallingIdentity(ident);
7402        }
7403    }
7404
7405    @Override
7406    public void stopLockTaskMode() {
7407//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7408//                "stopLockTaskMode()");
7409        synchronized (this) {
7410            mStackSupervisor.setLockTaskModeLocked(null);
7411        }
7412    }
7413
7414    @Override
7415    public boolean isInLockTaskMode() {
7416        synchronized (this) {
7417            return mStackSupervisor.isInLockTaskMode();
7418        }
7419    }
7420
7421    // =========================================================
7422    // THUMBNAILS
7423    // =========================================================
7424
7425    public void reportThumbnail(IBinder token,
7426            Bitmap thumbnail, CharSequence description) {
7427        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7428        final long origId = Binder.clearCallingIdentity();
7429        sendPendingThumbnail(null, token, thumbnail, description, true);
7430        Binder.restoreCallingIdentity(origId);
7431    }
7432
7433    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7434            Bitmap thumbnail, CharSequence description, boolean always) {
7435        TaskRecord task;
7436        ArrayList<PendingThumbnailsRecord> receivers = null;
7437
7438        //System.out.println("Send pending thumbnail: " + r);
7439
7440        synchronized(this) {
7441            if (r == null) {
7442                r = ActivityRecord.isInStackLocked(token);
7443                if (r == null) {
7444                    return;
7445                }
7446            }
7447            if (thumbnail == null && r.thumbHolder != null) {
7448                thumbnail = r.thumbHolder.lastThumbnail;
7449                description = r.thumbHolder.lastDescription;
7450            }
7451            if (thumbnail == null && !always) {
7452                // If there is no thumbnail, and this entry is not actually
7453                // going away, then abort for now and pick up the next
7454                // thumbnail we get.
7455                return;
7456            }
7457            task = r.task;
7458
7459            int N = mPendingThumbnails.size();
7460            int i=0;
7461            while (i<N) {
7462                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7463                //System.out.println("Looking in " + pr.pendingRecords);
7464                if (pr.pendingRecords.remove(r)) {
7465                    if (receivers == null) {
7466                        receivers = new ArrayList<PendingThumbnailsRecord>();
7467                    }
7468                    receivers.add(pr);
7469                    if (pr.pendingRecords.size() == 0) {
7470                        pr.finished = true;
7471                        mPendingThumbnails.remove(i);
7472                        N--;
7473                        continue;
7474                    }
7475                }
7476                i++;
7477            }
7478        }
7479
7480        if (receivers != null) {
7481            final int N = receivers.size();
7482            for (int i=0; i<N; i++) {
7483                try {
7484                    PendingThumbnailsRecord pr = receivers.get(i);
7485                    pr.receiver.newThumbnail(
7486                        task != null ? task.taskId : -1, thumbnail, description);
7487                    if (pr.finished) {
7488                        pr.receiver.finished();
7489                    }
7490                } catch (Exception e) {
7491                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7492                }
7493            }
7494        }
7495    }
7496
7497    // =========================================================
7498    // CONTENT PROVIDERS
7499    // =========================================================
7500
7501    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7502        List<ProviderInfo> providers = null;
7503        try {
7504            providers = AppGlobals.getPackageManager().
7505                queryContentProviders(app.processName, app.uid,
7506                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7507        } catch (RemoteException ex) {
7508        }
7509        if (DEBUG_MU)
7510            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7511        int userId = app.userId;
7512        if (providers != null) {
7513            int N = providers.size();
7514            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7515            for (int i=0; i<N; i++) {
7516                ProviderInfo cpi =
7517                    (ProviderInfo)providers.get(i);
7518                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7519                        cpi.name, cpi.flags);
7520                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7521                    // This is a singleton provider, but a user besides the
7522                    // default user is asking to initialize a process it runs
7523                    // in...  well, no, it doesn't actually run in this process,
7524                    // it runs in the process of the default user.  Get rid of it.
7525                    providers.remove(i);
7526                    N--;
7527                    i--;
7528                    continue;
7529                }
7530
7531                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7532                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7533                if (cpr == null) {
7534                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7535                    mProviderMap.putProviderByClass(comp, cpr);
7536                }
7537                if (DEBUG_MU)
7538                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7539                app.pubProviders.put(cpi.name, cpr);
7540                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7541                    // Don't add this if it is a platform component that is marked
7542                    // to run in multiple processes, because this is actually
7543                    // part of the framework so doesn't make sense to track as a
7544                    // separate apk in the process.
7545                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7546                }
7547                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7548            }
7549        }
7550        return providers;
7551    }
7552
7553    /**
7554     * Check if {@link ProcessRecord} has a possible chance at accessing the
7555     * given {@link ProviderInfo}. Final permission checking is always done
7556     * in {@link ContentProvider}.
7557     */
7558    private final String checkContentProviderPermissionLocked(
7559            ProviderInfo cpi, ProcessRecord r) {
7560        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7561        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7562        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7563                cpi.applicationInfo.uid, cpi.exported)
7564                == PackageManager.PERMISSION_GRANTED) {
7565            return null;
7566        }
7567        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7568                cpi.applicationInfo.uid, cpi.exported)
7569                == PackageManager.PERMISSION_GRANTED) {
7570            return null;
7571        }
7572
7573        PathPermission[] pps = cpi.pathPermissions;
7574        if (pps != null) {
7575            int i = pps.length;
7576            while (i > 0) {
7577                i--;
7578                PathPermission pp = pps[i];
7579                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7580                        cpi.applicationInfo.uid, cpi.exported)
7581                        == PackageManager.PERMISSION_GRANTED) {
7582                    return null;
7583                }
7584                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7585                        cpi.applicationInfo.uid, cpi.exported)
7586                        == PackageManager.PERMISSION_GRANTED) {
7587                    return null;
7588                }
7589            }
7590        }
7591
7592        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7593        if (perms != null) {
7594            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7595                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7596                    return null;
7597                }
7598            }
7599        }
7600
7601        String msg;
7602        if (!cpi.exported) {
7603            msg = "Permission Denial: opening provider " + cpi.name
7604                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7605                    + ", uid=" + callingUid + ") that is not exported from uid "
7606                    + cpi.applicationInfo.uid;
7607        } else {
7608            msg = "Permission Denial: opening provider " + cpi.name
7609                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7610                    + ", uid=" + callingUid + ") requires "
7611                    + cpi.readPermission + " or " + cpi.writePermission;
7612        }
7613        Slog.w(TAG, msg);
7614        return msg;
7615    }
7616
7617    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7618            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7619        if (r != null) {
7620            for (int i=0; i<r.conProviders.size(); i++) {
7621                ContentProviderConnection conn = r.conProviders.get(i);
7622                if (conn.provider == cpr) {
7623                    if (DEBUG_PROVIDER) Slog.v(TAG,
7624                            "Adding provider requested by "
7625                            + r.processName + " from process "
7626                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7627                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7628                    if (stable) {
7629                        conn.stableCount++;
7630                        conn.numStableIncs++;
7631                    } else {
7632                        conn.unstableCount++;
7633                        conn.numUnstableIncs++;
7634                    }
7635                    return conn;
7636                }
7637            }
7638            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7639            if (stable) {
7640                conn.stableCount = 1;
7641                conn.numStableIncs = 1;
7642            } else {
7643                conn.unstableCount = 1;
7644                conn.numUnstableIncs = 1;
7645            }
7646            cpr.connections.add(conn);
7647            r.conProviders.add(conn);
7648            return conn;
7649        }
7650        cpr.addExternalProcessHandleLocked(externalProcessToken);
7651        return null;
7652    }
7653
7654    boolean decProviderCountLocked(ContentProviderConnection conn,
7655            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7656        if (conn != null) {
7657            cpr = conn.provider;
7658            if (DEBUG_PROVIDER) Slog.v(TAG,
7659                    "Removing provider requested by "
7660                    + conn.client.processName + " from process "
7661                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7662                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7663            if (stable) {
7664                conn.stableCount--;
7665            } else {
7666                conn.unstableCount--;
7667            }
7668            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7669                cpr.connections.remove(conn);
7670                conn.client.conProviders.remove(conn);
7671                return true;
7672            }
7673            return false;
7674        }
7675        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7676        return false;
7677    }
7678
7679    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7680            String name, IBinder token, boolean stable, int userId) {
7681        ContentProviderRecord cpr;
7682        ContentProviderConnection conn = null;
7683        ProviderInfo cpi = null;
7684
7685        synchronized(this) {
7686            ProcessRecord r = null;
7687            if (caller != null) {
7688                r = getRecordForAppLocked(caller);
7689                if (r == null) {
7690                    throw new SecurityException(
7691                            "Unable to find app for caller " + caller
7692                          + " (pid=" + Binder.getCallingPid()
7693                          + ") when getting content provider " + name);
7694                }
7695            }
7696
7697            // First check if this content provider has been published...
7698            cpr = mProviderMap.getProviderByName(name, userId);
7699            boolean providerRunning = cpr != null;
7700            if (providerRunning) {
7701                cpi = cpr.info;
7702                String msg;
7703                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7704                    throw new SecurityException(msg);
7705                }
7706
7707                if (r != null && cpr.canRunHere(r)) {
7708                    // This provider has been published or is in the process
7709                    // of being published...  but it is also allowed to run
7710                    // in the caller's process, so don't make a connection
7711                    // and just let the caller instantiate its own instance.
7712                    ContentProviderHolder holder = cpr.newHolder(null);
7713                    // don't give caller the provider object, it needs
7714                    // to make its own.
7715                    holder.provider = null;
7716                    return holder;
7717                }
7718
7719                final long origId = Binder.clearCallingIdentity();
7720
7721                // In this case the provider instance already exists, so we can
7722                // return it right away.
7723                conn = incProviderCountLocked(r, cpr, token, stable);
7724                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7725                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7726                        // If this is a perceptible app accessing the provider,
7727                        // make sure to count it as being accessed and thus
7728                        // back up on the LRU list.  This is good because
7729                        // content providers are often expensive to start.
7730                        updateLruProcessLocked(cpr.proc, false, null);
7731                    }
7732                }
7733
7734                if (cpr.proc != null) {
7735                    if (false) {
7736                        if (cpr.name.flattenToShortString().equals(
7737                                "com.android.providers.calendar/.CalendarProvider2")) {
7738                            Slog.v(TAG, "****************** KILLING "
7739                                + cpr.name.flattenToShortString());
7740                            Process.killProcess(cpr.proc.pid);
7741                        }
7742                    }
7743                    boolean success = updateOomAdjLocked(cpr.proc);
7744                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7745                    // NOTE: there is still a race here where a signal could be
7746                    // pending on the process even though we managed to update its
7747                    // adj level.  Not sure what to do about this, but at least
7748                    // the race is now smaller.
7749                    if (!success) {
7750                        // Uh oh...  it looks like the provider's process
7751                        // has been killed on us.  We need to wait for a new
7752                        // process to be started, and make sure its death
7753                        // doesn't kill our process.
7754                        Slog.i(TAG,
7755                                "Existing provider " + cpr.name.flattenToShortString()
7756                                + " is crashing; detaching " + r);
7757                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7758                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7759                        if (!lastRef) {
7760                            // This wasn't the last ref our process had on
7761                            // the provider...  we have now been killed, bail.
7762                            return null;
7763                        }
7764                        providerRunning = false;
7765                        conn = null;
7766                    }
7767                }
7768
7769                Binder.restoreCallingIdentity(origId);
7770            }
7771
7772            boolean singleton;
7773            if (!providerRunning) {
7774                try {
7775                    cpi = AppGlobals.getPackageManager().
7776                        resolveContentProvider(name,
7777                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7778                } catch (RemoteException ex) {
7779                }
7780                if (cpi == null) {
7781                    return null;
7782                }
7783                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7784                        cpi.name, cpi.flags);
7785                if (singleton) {
7786                    userId = 0;
7787                }
7788                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7789
7790                String msg;
7791                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7792                    throw new SecurityException(msg);
7793                }
7794
7795                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7796                        && !cpi.processName.equals("system")) {
7797                    // If this content provider does not run in the system
7798                    // process, and the system is not yet ready to run other
7799                    // processes, then fail fast instead of hanging.
7800                    throw new IllegalArgumentException(
7801                            "Attempt to launch content provider before system ready");
7802                }
7803
7804                // Make sure that the user who owns this provider is started.  If not,
7805                // we don't want to allow it to run.
7806                if (mStartedUsers.get(userId) == null) {
7807                    Slog.w(TAG, "Unable to launch app "
7808                            + cpi.applicationInfo.packageName + "/"
7809                            + cpi.applicationInfo.uid + " for provider "
7810                            + name + ": user " + userId + " is stopped");
7811                    return null;
7812                }
7813
7814                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7815                cpr = mProviderMap.getProviderByClass(comp, userId);
7816                final boolean firstClass = cpr == null;
7817                if (firstClass) {
7818                    try {
7819                        ApplicationInfo ai =
7820                            AppGlobals.getPackageManager().
7821                                getApplicationInfo(
7822                                        cpi.applicationInfo.packageName,
7823                                        STOCK_PM_FLAGS, userId);
7824                        if (ai == null) {
7825                            Slog.w(TAG, "No package info for content provider "
7826                                    + cpi.name);
7827                            return null;
7828                        }
7829                        ai = getAppInfoForUser(ai, userId);
7830                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7831                    } catch (RemoteException ex) {
7832                        // pm is in same process, this will never happen.
7833                    }
7834                }
7835
7836                if (r != null && cpr.canRunHere(r)) {
7837                    // If this is a multiprocess provider, then just return its
7838                    // info and allow the caller to instantiate it.  Only do
7839                    // this if the provider is the same user as the caller's
7840                    // process, or can run as root (so can be in any process).
7841                    return cpr.newHolder(null);
7842                }
7843
7844                if (DEBUG_PROVIDER) {
7845                    RuntimeException e = new RuntimeException("here");
7846                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7847                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7848                }
7849
7850                // This is single process, and our app is now connecting to it.
7851                // See if we are already in the process of launching this
7852                // provider.
7853                final int N = mLaunchingProviders.size();
7854                int i;
7855                for (i=0; i<N; i++) {
7856                    if (mLaunchingProviders.get(i) == cpr) {
7857                        break;
7858                    }
7859                }
7860
7861                // If the provider is not already being launched, then get it
7862                // started.
7863                if (i >= N) {
7864                    final long origId = Binder.clearCallingIdentity();
7865
7866                    try {
7867                        // Content provider is now in use, its package can't be stopped.
7868                        try {
7869                            AppGlobals.getPackageManager().setPackageStoppedState(
7870                                    cpr.appInfo.packageName, false, userId);
7871                        } catch (RemoteException e) {
7872                        } catch (IllegalArgumentException e) {
7873                            Slog.w(TAG, "Failed trying to unstop package "
7874                                    + cpr.appInfo.packageName + ": " + e);
7875                        }
7876
7877                        // Use existing process if already started
7878                        ProcessRecord proc = getProcessRecordLocked(
7879                                cpi.processName, cpr.appInfo.uid, false);
7880                        if (proc != null && proc.thread != null) {
7881                            if (DEBUG_PROVIDER) {
7882                                Slog.d(TAG, "Installing in existing process " + proc);
7883                            }
7884                            proc.pubProviders.put(cpi.name, cpr);
7885                            try {
7886                                proc.thread.scheduleInstallProvider(cpi);
7887                            } catch (RemoteException e) {
7888                            }
7889                        } else {
7890                            proc = startProcessLocked(cpi.processName,
7891                                    cpr.appInfo, false, 0, "content provider",
7892                                    new ComponentName(cpi.applicationInfo.packageName,
7893                                            cpi.name), false, false, false);
7894                            if (proc == null) {
7895                                Slog.w(TAG, "Unable to launch app "
7896                                        + cpi.applicationInfo.packageName + "/"
7897                                        + cpi.applicationInfo.uid + " for provider "
7898                                        + name + ": process is bad");
7899                                return null;
7900                            }
7901                        }
7902                        cpr.launchingApp = proc;
7903                        mLaunchingProviders.add(cpr);
7904                    } finally {
7905                        Binder.restoreCallingIdentity(origId);
7906                    }
7907                }
7908
7909                // Make sure the provider is published (the same provider class
7910                // may be published under multiple names).
7911                if (firstClass) {
7912                    mProviderMap.putProviderByClass(comp, cpr);
7913                }
7914
7915                mProviderMap.putProviderByName(name, cpr);
7916                conn = incProviderCountLocked(r, cpr, token, stable);
7917                if (conn != null) {
7918                    conn.waiting = true;
7919                }
7920            }
7921        }
7922
7923        // Wait for the provider to be published...
7924        synchronized (cpr) {
7925            while (cpr.provider == null) {
7926                if (cpr.launchingApp == null) {
7927                    Slog.w(TAG, "Unable to launch app "
7928                            + cpi.applicationInfo.packageName + "/"
7929                            + cpi.applicationInfo.uid + " for provider "
7930                            + name + ": launching app became null");
7931                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7932                            UserHandle.getUserId(cpi.applicationInfo.uid),
7933                            cpi.applicationInfo.packageName,
7934                            cpi.applicationInfo.uid, name);
7935                    return null;
7936                }
7937                try {
7938                    if (DEBUG_MU) {
7939                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7940                                + cpr.launchingApp);
7941                    }
7942                    if (conn != null) {
7943                        conn.waiting = true;
7944                    }
7945                    cpr.wait();
7946                } catch (InterruptedException ex) {
7947                } finally {
7948                    if (conn != null) {
7949                        conn.waiting = false;
7950                    }
7951                }
7952            }
7953        }
7954        return cpr != null ? cpr.newHolder(conn) : null;
7955    }
7956
7957    public final ContentProviderHolder getContentProvider(
7958            IApplicationThread caller, String name, int userId, boolean stable) {
7959        enforceNotIsolatedCaller("getContentProvider");
7960        if (caller == null) {
7961            String msg = "null IApplicationThread when getting content provider "
7962                    + name;
7963            Slog.w(TAG, msg);
7964            throw new SecurityException(msg);
7965        }
7966
7967        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7968                false, true, "getContentProvider", null);
7969        return getContentProviderImpl(caller, name, null, stable, userId);
7970    }
7971
7972    public ContentProviderHolder getContentProviderExternal(
7973            String name, int userId, IBinder token) {
7974        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7975            "Do not have permission in call getContentProviderExternal()");
7976        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7977                false, true, "getContentProvider", null);
7978        return getContentProviderExternalUnchecked(name, token, userId);
7979    }
7980
7981    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7982            IBinder token, int userId) {
7983        return getContentProviderImpl(null, name, token, true, userId);
7984    }
7985
7986    /**
7987     * Drop a content provider from a ProcessRecord's bookkeeping
7988     */
7989    public void removeContentProvider(IBinder connection, boolean stable) {
7990        enforceNotIsolatedCaller("removeContentProvider");
7991        long ident = Binder.clearCallingIdentity();
7992        try {
7993            synchronized (this) {
7994                ContentProviderConnection conn;
7995                try {
7996                    conn = (ContentProviderConnection)connection;
7997                } catch (ClassCastException e) {
7998                    String msg ="removeContentProvider: " + connection
7999                            + " not a ContentProviderConnection";
8000                    Slog.w(TAG, msg);
8001                    throw new IllegalArgumentException(msg);
8002                }
8003                if (conn == null) {
8004                    throw new NullPointerException("connection is null");
8005                }
8006                if (decProviderCountLocked(conn, null, null, stable)) {
8007                    updateOomAdjLocked();
8008                }
8009            }
8010        } finally {
8011            Binder.restoreCallingIdentity(ident);
8012        }
8013    }
8014
8015    public void removeContentProviderExternal(String name, IBinder token) {
8016        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8017            "Do not have permission in call removeContentProviderExternal()");
8018        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8019    }
8020
8021    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8022        synchronized (this) {
8023            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8024            if(cpr == null) {
8025                //remove from mProvidersByClass
8026                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8027                return;
8028            }
8029
8030            //update content provider record entry info
8031            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8032            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8033            if (localCpr.hasExternalProcessHandles()) {
8034                if (localCpr.removeExternalProcessHandleLocked(token)) {
8035                    updateOomAdjLocked();
8036                } else {
8037                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8038                            + " with no external reference for token: "
8039                            + token + ".");
8040                }
8041            } else {
8042                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8043                        + " with no external references.");
8044            }
8045        }
8046    }
8047
8048    public final void publishContentProviders(IApplicationThread caller,
8049            List<ContentProviderHolder> providers) {
8050        if (providers == null) {
8051            return;
8052        }
8053
8054        enforceNotIsolatedCaller("publishContentProviders");
8055        synchronized (this) {
8056            final ProcessRecord r = getRecordForAppLocked(caller);
8057            if (DEBUG_MU)
8058                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8059            if (r == null) {
8060                throw new SecurityException(
8061                        "Unable to find app for caller " + caller
8062                      + " (pid=" + Binder.getCallingPid()
8063                      + ") when publishing content providers");
8064            }
8065
8066            final long origId = Binder.clearCallingIdentity();
8067
8068            final int N = providers.size();
8069            for (int i=0; i<N; i++) {
8070                ContentProviderHolder src = providers.get(i);
8071                if (src == null || src.info == null || src.provider == null) {
8072                    continue;
8073                }
8074                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8075                if (DEBUG_MU)
8076                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8077                if (dst != null) {
8078                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8079                    mProviderMap.putProviderByClass(comp, dst);
8080                    String names[] = dst.info.authority.split(";");
8081                    for (int j = 0; j < names.length; j++) {
8082                        mProviderMap.putProviderByName(names[j], dst);
8083                    }
8084
8085                    int NL = mLaunchingProviders.size();
8086                    int j;
8087                    for (j=0; j<NL; j++) {
8088                        if (mLaunchingProviders.get(j) == dst) {
8089                            mLaunchingProviders.remove(j);
8090                            j--;
8091                            NL--;
8092                        }
8093                    }
8094                    synchronized (dst) {
8095                        dst.provider = src.provider;
8096                        dst.proc = r;
8097                        dst.notifyAll();
8098                    }
8099                    updateOomAdjLocked(r);
8100                }
8101            }
8102
8103            Binder.restoreCallingIdentity(origId);
8104        }
8105    }
8106
8107    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8108        ContentProviderConnection conn;
8109        try {
8110            conn = (ContentProviderConnection)connection;
8111        } catch (ClassCastException e) {
8112            String msg ="refContentProvider: " + connection
8113                    + " not a ContentProviderConnection";
8114            Slog.w(TAG, msg);
8115            throw new IllegalArgumentException(msg);
8116        }
8117        if (conn == null) {
8118            throw new NullPointerException("connection is null");
8119        }
8120
8121        synchronized (this) {
8122            if (stable > 0) {
8123                conn.numStableIncs += stable;
8124            }
8125            stable = conn.stableCount + stable;
8126            if (stable < 0) {
8127                throw new IllegalStateException("stableCount < 0: " + stable);
8128            }
8129
8130            if (unstable > 0) {
8131                conn.numUnstableIncs += unstable;
8132            }
8133            unstable = conn.unstableCount + unstable;
8134            if (unstable < 0) {
8135                throw new IllegalStateException("unstableCount < 0: " + unstable);
8136            }
8137
8138            if ((stable+unstable) <= 0) {
8139                throw new IllegalStateException("ref counts can't go to zero here: stable="
8140                        + stable + " unstable=" + unstable);
8141            }
8142            conn.stableCount = stable;
8143            conn.unstableCount = unstable;
8144            return !conn.dead;
8145        }
8146    }
8147
8148    public void unstableProviderDied(IBinder connection) {
8149        ContentProviderConnection conn;
8150        try {
8151            conn = (ContentProviderConnection)connection;
8152        } catch (ClassCastException e) {
8153            String msg ="refContentProvider: " + connection
8154                    + " not a ContentProviderConnection";
8155            Slog.w(TAG, msg);
8156            throw new IllegalArgumentException(msg);
8157        }
8158        if (conn == null) {
8159            throw new NullPointerException("connection is null");
8160        }
8161
8162        // Safely retrieve the content provider associated with the connection.
8163        IContentProvider provider;
8164        synchronized (this) {
8165            provider = conn.provider.provider;
8166        }
8167
8168        if (provider == null) {
8169            // Um, yeah, we're way ahead of you.
8170            return;
8171        }
8172
8173        // Make sure the caller is being honest with us.
8174        if (provider.asBinder().pingBinder()) {
8175            // Er, no, still looks good to us.
8176            synchronized (this) {
8177                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8178                        + " says " + conn + " died, but we don't agree");
8179                return;
8180            }
8181        }
8182
8183        // Well look at that!  It's dead!
8184        synchronized (this) {
8185            if (conn.provider.provider != provider) {
8186                // But something changed...  good enough.
8187                return;
8188            }
8189
8190            ProcessRecord proc = conn.provider.proc;
8191            if (proc == null || proc.thread == null) {
8192                // Seems like the process is already cleaned up.
8193                return;
8194            }
8195
8196            // As far as we're concerned, this is just like receiving a
8197            // death notification...  just a bit prematurely.
8198            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8199                    + ") early provider death");
8200            final long ident = Binder.clearCallingIdentity();
8201            try {
8202                appDiedLocked(proc, proc.pid, proc.thread);
8203            } finally {
8204                Binder.restoreCallingIdentity(ident);
8205            }
8206        }
8207    }
8208
8209    @Override
8210    public void appNotRespondingViaProvider(IBinder connection) {
8211        enforceCallingPermission(
8212                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8213
8214        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8215        if (conn == null) {
8216            Slog.w(TAG, "ContentProviderConnection is null");
8217            return;
8218        }
8219
8220        final ProcessRecord host = conn.provider.proc;
8221        if (host == null) {
8222            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8223            return;
8224        }
8225
8226        final long token = Binder.clearCallingIdentity();
8227        try {
8228            appNotResponding(host, null, null, false, "ContentProvider not responding");
8229        } finally {
8230            Binder.restoreCallingIdentity(token);
8231        }
8232    }
8233
8234    public final void installSystemProviders() {
8235        List<ProviderInfo> providers;
8236        synchronized (this) {
8237            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8238            providers = generateApplicationProvidersLocked(app);
8239            if (providers != null) {
8240                for (int i=providers.size()-1; i>=0; i--) {
8241                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8242                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8243                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8244                                + ": not system .apk");
8245                        providers.remove(i);
8246                    }
8247                }
8248            }
8249        }
8250        if (providers != null) {
8251            mSystemThread.installSystemProviders(providers);
8252        }
8253
8254        mCoreSettingsObserver = new CoreSettingsObserver(this);
8255
8256        mUsageStatsService.monitorPackages();
8257    }
8258
8259    /**
8260     * Allows app to retrieve the MIME type of a URI without having permission
8261     * to access its content provider.
8262     *
8263     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8264     *
8265     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8266     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8267     */
8268    public String getProviderMimeType(Uri uri, int userId) {
8269        enforceNotIsolatedCaller("getProviderMimeType");
8270        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8271                userId, false, true, "getProviderMimeType", null);
8272        final String name = uri.getAuthority();
8273        final long ident = Binder.clearCallingIdentity();
8274        ContentProviderHolder holder = null;
8275
8276        try {
8277            holder = getContentProviderExternalUnchecked(name, null, userId);
8278            if (holder != null) {
8279                return holder.provider.getType(uri);
8280            }
8281        } catch (RemoteException e) {
8282            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8283            return null;
8284        } finally {
8285            if (holder != null) {
8286                removeContentProviderExternalUnchecked(name, null, userId);
8287            }
8288            Binder.restoreCallingIdentity(ident);
8289        }
8290
8291        return null;
8292    }
8293
8294    // =========================================================
8295    // GLOBAL MANAGEMENT
8296    // =========================================================
8297
8298    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8299            boolean isolated) {
8300        String proc = customProcess != null ? customProcess : info.processName;
8301        BatteryStatsImpl.Uid.Proc ps = null;
8302        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8303        int uid = info.uid;
8304        if (isolated) {
8305            int userId = UserHandle.getUserId(uid);
8306            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8307            while (true) {
8308                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8309                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8310                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8311                }
8312                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8313                mNextIsolatedProcessUid++;
8314                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8315                    // No process for this uid, use it.
8316                    break;
8317                }
8318                stepsLeft--;
8319                if (stepsLeft <= 0) {
8320                    return null;
8321                }
8322            }
8323        }
8324        return new ProcessRecord(stats, info, proc, uid);
8325    }
8326
8327    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8328        ProcessRecord app;
8329        if (!isolated) {
8330            app = getProcessRecordLocked(info.processName, info.uid, true);
8331        } else {
8332            app = null;
8333        }
8334
8335        if (app == null) {
8336            app = newProcessRecordLocked(info, null, isolated);
8337            mProcessNames.put(info.processName, app.uid, app);
8338            if (isolated) {
8339                mIsolatedProcesses.put(app.uid, app);
8340            }
8341            updateLruProcessLocked(app, false, null);
8342            updateOomAdjLocked();
8343        }
8344
8345        // This package really, really can not be stopped.
8346        try {
8347            AppGlobals.getPackageManager().setPackageStoppedState(
8348                    info.packageName, false, UserHandle.getUserId(app.uid));
8349        } catch (RemoteException e) {
8350        } catch (IllegalArgumentException e) {
8351            Slog.w(TAG, "Failed trying to unstop package "
8352                    + info.packageName + ": " + e);
8353        }
8354
8355        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8356                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8357            app.persistent = true;
8358            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8359        }
8360        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8361            mPersistentStartingProcesses.add(app);
8362            startProcessLocked(app, "added application", app.processName);
8363        }
8364
8365        return app;
8366    }
8367
8368    public void unhandledBack() {
8369        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8370                "unhandledBack()");
8371
8372        synchronized(this) {
8373            final long origId = Binder.clearCallingIdentity();
8374            try {
8375                getFocusedStack().unhandledBackLocked();
8376            } finally {
8377                Binder.restoreCallingIdentity(origId);
8378            }
8379        }
8380    }
8381
8382    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8383        enforceNotIsolatedCaller("openContentUri");
8384        final int userId = UserHandle.getCallingUserId();
8385        String name = uri.getAuthority();
8386        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8387        ParcelFileDescriptor pfd = null;
8388        if (cph != null) {
8389            // We record the binder invoker's uid in thread-local storage before
8390            // going to the content provider to open the file.  Later, in the code
8391            // that handles all permissions checks, we look for this uid and use
8392            // that rather than the Activity Manager's own uid.  The effect is that
8393            // we do the check against the caller's permissions even though it looks
8394            // to the content provider like the Activity Manager itself is making
8395            // the request.
8396            sCallerIdentity.set(new Identity(
8397                    Binder.getCallingPid(), Binder.getCallingUid()));
8398            try {
8399                pfd = cph.provider.openFile(null, uri, "r", null);
8400            } catch (FileNotFoundException e) {
8401                // do nothing; pfd will be returned null
8402            } finally {
8403                // Ensure that whatever happens, we clean up the identity state
8404                sCallerIdentity.remove();
8405            }
8406
8407            // We've got the fd now, so we're done with the provider.
8408            removeContentProviderExternalUnchecked(name, null, userId);
8409        } else {
8410            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8411        }
8412        return pfd;
8413    }
8414
8415    // Actually is sleeping or shutting down or whatever else in the future
8416    // is an inactive state.
8417    public boolean isSleepingOrShuttingDown() {
8418        return mSleeping || mShuttingDown;
8419    }
8420
8421    public void goingToSleep() {
8422        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8423                != PackageManager.PERMISSION_GRANTED) {
8424            throw new SecurityException("Requires permission "
8425                    + android.Manifest.permission.DEVICE_POWER);
8426        }
8427
8428        synchronized(this) {
8429            mWentToSleep = true;
8430            updateEventDispatchingLocked();
8431
8432            if (!mSleeping) {
8433                mSleeping = true;
8434                mStackSupervisor.goingToSleepLocked();
8435
8436                // Initialize the wake times of all processes.
8437                checkExcessivePowerUsageLocked(false);
8438                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8439                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8440                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8441            }
8442        }
8443    }
8444
8445    @Override
8446    public boolean shutdown(int timeout) {
8447        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8448                != PackageManager.PERMISSION_GRANTED) {
8449            throw new SecurityException("Requires permission "
8450                    + android.Manifest.permission.SHUTDOWN);
8451        }
8452
8453        boolean timedout = false;
8454
8455        synchronized(this) {
8456            mShuttingDown = true;
8457            updateEventDispatchingLocked();
8458            timedout = mStackSupervisor.shutdownLocked(timeout);
8459        }
8460
8461        mAppOpsService.shutdown();
8462        mUsageStatsService.shutdown();
8463        mBatteryStatsService.shutdown();
8464        synchronized (this) {
8465            mProcessStats.shutdownLocked();
8466        }
8467
8468        return timedout;
8469    }
8470
8471    public final void activitySlept(IBinder token) {
8472        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8473
8474        final long origId = Binder.clearCallingIdentity();
8475
8476        synchronized (this) {
8477            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8478            if (r != null) {
8479                mStackSupervisor.activitySleptLocked(r);
8480            }
8481        }
8482
8483        Binder.restoreCallingIdentity(origId);
8484    }
8485
8486    void logLockScreen(String msg) {
8487        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8488                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8489                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8490                mStackSupervisor.mDismissKeyguardOnNextActivity);
8491    }
8492
8493    private void comeOutOfSleepIfNeededLocked() {
8494        if (!mWentToSleep && !mLockScreenShown) {
8495            if (mSleeping) {
8496                mSleeping = false;
8497                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8498            }
8499        }
8500    }
8501
8502    public void wakingUp() {
8503        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8504                != PackageManager.PERMISSION_GRANTED) {
8505            throw new SecurityException("Requires permission "
8506                    + android.Manifest.permission.DEVICE_POWER);
8507        }
8508
8509        synchronized(this) {
8510            mWentToSleep = false;
8511            updateEventDispatchingLocked();
8512            comeOutOfSleepIfNeededLocked();
8513        }
8514    }
8515
8516    private void updateEventDispatchingLocked() {
8517        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8518    }
8519
8520    public void setLockScreenShown(boolean shown) {
8521        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8522                != PackageManager.PERMISSION_GRANTED) {
8523            throw new SecurityException("Requires permission "
8524                    + android.Manifest.permission.DEVICE_POWER);
8525        }
8526
8527        synchronized(this) {
8528            long ident = Binder.clearCallingIdentity();
8529            try {
8530                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8531                mLockScreenShown = shown;
8532                comeOutOfSleepIfNeededLocked();
8533            } finally {
8534                Binder.restoreCallingIdentity(ident);
8535            }
8536        }
8537    }
8538
8539    public void stopAppSwitches() {
8540        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8541                != PackageManager.PERMISSION_GRANTED) {
8542            throw new SecurityException("Requires permission "
8543                    + android.Manifest.permission.STOP_APP_SWITCHES);
8544        }
8545
8546        synchronized(this) {
8547            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8548                    + APP_SWITCH_DELAY_TIME;
8549            mDidAppSwitch = false;
8550            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8551            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8552            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8553        }
8554    }
8555
8556    public void resumeAppSwitches() {
8557        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8558                != PackageManager.PERMISSION_GRANTED) {
8559            throw new SecurityException("Requires permission "
8560                    + android.Manifest.permission.STOP_APP_SWITCHES);
8561        }
8562
8563        synchronized(this) {
8564            // Note that we don't execute any pending app switches... we will
8565            // let those wait until either the timeout, or the next start
8566            // activity request.
8567            mAppSwitchesAllowedTime = 0;
8568        }
8569    }
8570
8571    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8572            String name) {
8573        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8574            return true;
8575        }
8576
8577        final int perm = checkComponentPermission(
8578                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8579                callingUid, -1, true);
8580        if (perm == PackageManager.PERMISSION_GRANTED) {
8581            return true;
8582        }
8583
8584        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8585        return false;
8586    }
8587
8588    public void setDebugApp(String packageName, boolean waitForDebugger,
8589            boolean persistent) {
8590        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8591                "setDebugApp()");
8592
8593        long ident = Binder.clearCallingIdentity();
8594        try {
8595            // Note that this is not really thread safe if there are multiple
8596            // callers into it at the same time, but that's not a situation we
8597            // care about.
8598            if (persistent) {
8599                final ContentResolver resolver = mContext.getContentResolver();
8600                Settings.Global.putString(
8601                    resolver, Settings.Global.DEBUG_APP,
8602                    packageName);
8603                Settings.Global.putInt(
8604                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8605                    waitForDebugger ? 1 : 0);
8606            }
8607
8608            synchronized (this) {
8609                if (!persistent) {
8610                    mOrigDebugApp = mDebugApp;
8611                    mOrigWaitForDebugger = mWaitForDebugger;
8612                }
8613                mDebugApp = packageName;
8614                mWaitForDebugger = waitForDebugger;
8615                mDebugTransient = !persistent;
8616                if (packageName != null) {
8617                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8618                            false, UserHandle.USER_ALL, "set debug app");
8619                }
8620            }
8621        } finally {
8622            Binder.restoreCallingIdentity(ident);
8623        }
8624    }
8625
8626    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8627        synchronized (this) {
8628            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8629            if (!isDebuggable) {
8630                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8631                    throw new SecurityException("Process not debuggable: " + app.packageName);
8632                }
8633            }
8634
8635            mOpenGlTraceApp = processName;
8636        }
8637    }
8638
8639    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8640            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8641        synchronized (this) {
8642            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8643            if (!isDebuggable) {
8644                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8645                    throw new SecurityException("Process not debuggable: " + app.packageName);
8646                }
8647            }
8648            mProfileApp = processName;
8649            mProfileFile = profileFile;
8650            if (mProfileFd != null) {
8651                try {
8652                    mProfileFd.close();
8653                } catch (IOException e) {
8654                }
8655                mProfileFd = null;
8656            }
8657            mProfileFd = profileFd;
8658            mProfileType = 0;
8659            mAutoStopProfiler = autoStopProfiler;
8660        }
8661    }
8662
8663    @Override
8664    public void setAlwaysFinish(boolean enabled) {
8665        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8666                "setAlwaysFinish()");
8667
8668        Settings.Global.putInt(
8669                mContext.getContentResolver(),
8670                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8671
8672        synchronized (this) {
8673            mAlwaysFinishActivities = enabled;
8674        }
8675    }
8676
8677    @Override
8678    public void setActivityController(IActivityController controller) {
8679        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8680                "setActivityController()");
8681        synchronized (this) {
8682            mController = controller;
8683            Watchdog.getInstance().setActivityController(controller);
8684        }
8685    }
8686
8687    @Override
8688    public void setUserIsMonkey(boolean userIsMonkey) {
8689        synchronized (this) {
8690            synchronized (mPidsSelfLocked) {
8691                final int callingPid = Binder.getCallingPid();
8692                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8693                if (precessRecord == null) {
8694                    throw new SecurityException("Unknown process: " + callingPid);
8695                }
8696                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8697                    throw new SecurityException("Only an instrumentation process "
8698                            + "with a UiAutomation can call setUserIsMonkey");
8699                }
8700            }
8701            mUserIsMonkey = userIsMonkey;
8702        }
8703    }
8704
8705    @Override
8706    public boolean isUserAMonkey() {
8707        synchronized (this) {
8708            // If there is a controller also implies the user is a monkey.
8709            return (mUserIsMonkey || mController != null);
8710        }
8711    }
8712
8713    public void requestBugReport() {
8714        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8715        SystemProperties.set("ctl.start", "bugreport");
8716    }
8717
8718    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8719        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8720    }
8721
8722    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8723        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8724            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8725        }
8726        return KEY_DISPATCHING_TIMEOUT;
8727    }
8728
8729    @Override
8730    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8731        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8732                != PackageManager.PERMISSION_GRANTED) {
8733            throw new SecurityException("Requires permission "
8734                    + android.Manifest.permission.FILTER_EVENTS);
8735        }
8736        ProcessRecord proc;
8737        long timeout;
8738        synchronized (this) {
8739            synchronized (mPidsSelfLocked) {
8740                proc = mPidsSelfLocked.get(pid);
8741            }
8742            timeout = getInputDispatchingTimeoutLocked(proc);
8743        }
8744
8745        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8746            return -1;
8747        }
8748
8749        return timeout;
8750    }
8751
8752    /**
8753     * Handle input dispatching timeouts.
8754     * Returns whether input dispatching should be aborted or not.
8755     */
8756    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8757            final ActivityRecord activity, final ActivityRecord parent,
8758            final boolean aboveSystem, String reason) {
8759        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8760                != PackageManager.PERMISSION_GRANTED) {
8761            throw new SecurityException("Requires permission "
8762                    + android.Manifest.permission.FILTER_EVENTS);
8763        }
8764
8765        final String annotation;
8766        if (reason == null) {
8767            annotation = "Input dispatching timed out";
8768        } else {
8769            annotation = "Input dispatching timed out (" + reason + ")";
8770        }
8771
8772        if (proc != null) {
8773            synchronized (this) {
8774                if (proc.debugging) {
8775                    return false;
8776                }
8777
8778                if (mDidDexOpt) {
8779                    // Give more time since we were dexopting.
8780                    mDidDexOpt = false;
8781                    return false;
8782                }
8783
8784                if (proc.instrumentationClass != null) {
8785                    Bundle info = new Bundle();
8786                    info.putString("shortMsg", "keyDispatchingTimedOut");
8787                    info.putString("longMsg", annotation);
8788                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8789                    return true;
8790                }
8791            }
8792            mHandler.post(new Runnable() {
8793                @Override
8794                public void run() {
8795                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8796                }
8797            });
8798        }
8799
8800        return true;
8801    }
8802
8803    public Bundle getAssistContextExtras(int requestType) {
8804        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8805                "getAssistContextExtras()");
8806        PendingAssistExtras pae;
8807        Bundle extras = new Bundle();
8808        synchronized (this) {
8809            ActivityRecord activity = getFocusedStack().mResumedActivity;
8810            if (activity == null) {
8811                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8812                return null;
8813            }
8814            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8815            if (activity.app == null || activity.app.thread == null) {
8816                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8817                return extras;
8818            }
8819            if (activity.app.pid == Binder.getCallingPid()) {
8820                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8821                return extras;
8822            }
8823            pae = new PendingAssistExtras(activity);
8824            try {
8825                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8826                        requestType);
8827                mPendingAssistExtras.add(pae);
8828                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8829            } catch (RemoteException e) {
8830                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8831                return extras;
8832            }
8833        }
8834        synchronized (pae) {
8835            while (!pae.haveResult) {
8836                try {
8837                    pae.wait();
8838                } catch (InterruptedException e) {
8839                }
8840            }
8841            if (pae.result != null) {
8842                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8843            }
8844        }
8845        synchronized (this) {
8846            mPendingAssistExtras.remove(pae);
8847            mHandler.removeCallbacks(pae);
8848        }
8849        return extras;
8850    }
8851
8852    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8853        PendingAssistExtras pae = (PendingAssistExtras)token;
8854        synchronized (pae) {
8855            pae.result = extras;
8856            pae.haveResult = true;
8857            pae.notifyAll();
8858        }
8859    }
8860
8861    public void registerProcessObserver(IProcessObserver observer) {
8862        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8863                "registerProcessObserver()");
8864        synchronized (this) {
8865            mProcessObservers.register(observer);
8866        }
8867    }
8868
8869    @Override
8870    public void unregisterProcessObserver(IProcessObserver observer) {
8871        synchronized (this) {
8872            mProcessObservers.unregister(observer);
8873        }
8874    }
8875
8876    @Override
8877    public boolean convertFromTranslucent(IBinder token) {
8878        final long origId = Binder.clearCallingIdentity();
8879        try {
8880            synchronized (this) {
8881                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8882                if (r == null) {
8883                    return false;
8884                }
8885                if (r.changeWindowTranslucency(true)) {
8886                    mWindowManager.setAppFullscreen(token, true);
8887                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8888                    return true;
8889                }
8890                return false;
8891            }
8892        } finally {
8893            Binder.restoreCallingIdentity(origId);
8894        }
8895    }
8896
8897    @Override
8898    public boolean convertToTranslucent(IBinder token) {
8899        final long origId = Binder.clearCallingIdentity();
8900        try {
8901            synchronized (this) {
8902                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8903                if (r == null) {
8904                    return false;
8905                }
8906                if (r.changeWindowTranslucency(false)) {
8907                    r.task.stack.convertToTranslucent(r);
8908                    mWindowManager.setAppFullscreen(token, false);
8909                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8910                    return true;
8911                }
8912                return false;
8913            }
8914        } finally {
8915            Binder.restoreCallingIdentity(origId);
8916        }
8917    }
8918
8919    @Override
8920    public void setImmersive(IBinder token, boolean immersive) {
8921        synchronized(this) {
8922            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8923            if (r == null) {
8924                throw new IllegalArgumentException();
8925            }
8926            r.immersive = immersive;
8927
8928            // update associated state if we're frontmost
8929            if (r == mFocusedActivity) {
8930                if (DEBUG_IMMERSIVE) {
8931                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8932                }
8933                applyUpdateLockStateLocked(r);
8934            }
8935        }
8936    }
8937
8938    @Override
8939    public boolean isImmersive(IBinder token) {
8940        synchronized (this) {
8941            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8942            if (r == null) {
8943                throw new IllegalArgumentException();
8944            }
8945            return r.immersive;
8946        }
8947    }
8948
8949    public boolean isTopActivityImmersive() {
8950        enforceNotIsolatedCaller("startActivity");
8951        synchronized (this) {
8952            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8953            return (r != null) ? r.immersive : false;
8954        }
8955    }
8956
8957    public final void enterSafeMode() {
8958        synchronized(this) {
8959            // It only makes sense to do this before the system is ready
8960            // and started launching other packages.
8961            if (!mSystemReady) {
8962                try {
8963                    AppGlobals.getPackageManager().enterSafeMode();
8964                } catch (RemoteException e) {
8965                }
8966            }
8967        }
8968    }
8969
8970    public final void showSafeModeOverlay() {
8971        View v = LayoutInflater.from(mContext).inflate(
8972                com.android.internal.R.layout.safe_mode, null);
8973        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8974        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8975        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8976        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8977        lp.gravity = Gravity.BOTTOM | Gravity.START;
8978        lp.format = v.getBackground().getOpacity();
8979        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8980                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8981        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8982        ((WindowManager)mContext.getSystemService(
8983                Context.WINDOW_SERVICE)).addView(v, lp);
8984    }
8985
8986    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8987        if (!(sender instanceof PendingIntentRecord)) {
8988            return;
8989        }
8990        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8991        synchronized (stats) {
8992            if (mBatteryStatsService.isOnBattery()) {
8993                mBatteryStatsService.enforceCallingPermission();
8994                PendingIntentRecord rec = (PendingIntentRecord)sender;
8995                int MY_UID = Binder.getCallingUid();
8996                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8997                BatteryStatsImpl.Uid.Pkg pkg =
8998                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8999                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9000                pkg.incWakeupsLocked();
9001            }
9002        }
9003    }
9004
9005    public boolean killPids(int[] pids, String pReason, boolean secure) {
9006        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9007            throw new SecurityException("killPids only available to the system");
9008        }
9009        String reason = (pReason == null) ? "Unknown" : pReason;
9010        // XXX Note: don't acquire main activity lock here, because the window
9011        // manager calls in with its locks held.
9012
9013        boolean killed = false;
9014        synchronized (mPidsSelfLocked) {
9015            int[] types = new int[pids.length];
9016            int worstType = 0;
9017            for (int i=0; i<pids.length; i++) {
9018                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9019                if (proc != null) {
9020                    int type = proc.setAdj;
9021                    types[i] = type;
9022                    if (type > worstType) {
9023                        worstType = type;
9024                    }
9025                }
9026            }
9027
9028            // If the worst oom_adj is somewhere in the cached proc LRU range,
9029            // then constrain it so we will kill all cached procs.
9030            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9031                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9032                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9033            }
9034
9035            // If this is not a secure call, don't let it kill processes that
9036            // are important.
9037            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9038                worstType = ProcessList.SERVICE_ADJ;
9039            }
9040
9041            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9042            for (int i=0; i<pids.length; i++) {
9043                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9044                if (proc == null) {
9045                    continue;
9046                }
9047                int adj = proc.setAdj;
9048                if (adj >= worstType && !proc.killedByAm) {
9049                    killUnneededProcessLocked(proc, reason);
9050                    killed = true;
9051                }
9052            }
9053        }
9054        return killed;
9055    }
9056
9057    @Override
9058    public void killUid(int uid, String reason) {
9059        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9060            throw new SecurityException("killUid only available to the system");
9061        }
9062        synchronized (this) {
9063            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9064                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9065                    reason != null ? reason : "kill uid");
9066        }
9067    }
9068
9069    @Override
9070    public boolean killProcessesBelowForeground(String reason) {
9071        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9072            throw new SecurityException("killProcessesBelowForeground() only available to system");
9073        }
9074
9075        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9076    }
9077
9078    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9079        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9080            throw new SecurityException("killProcessesBelowAdj() only available to system");
9081        }
9082
9083        boolean killed = false;
9084        synchronized (mPidsSelfLocked) {
9085            final int size = mPidsSelfLocked.size();
9086            for (int i = 0; i < size; i++) {
9087                final int pid = mPidsSelfLocked.keyAt(i);
9088                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9089                if (proc == null) continue;
9090
9091                final int adj = proc.setAdj;
9092                if (adj > belowAdj && !proc.killedByAm) {
9093                    killUnneededProcessLocked(proc, reason);
9094                    killed = true;
9095                }
9096            }
9097        }
9098        return killed;
9099    }
9100
9101    @Override
9102    public void hang(final IBinder who, boolean allowRestart) {
9103        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9104                != PackageManager.PERMISSION_GRANTED) {
9105            throw new SecurityException("Requires permission "
9106                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9107        }
9108
9109        final IBinder.DeathRecipient death = new DeathRecipient() {
9110            @Override
9111            public void binderDied() {
9112                synchronized (this) {
9113                    notifyAll();
9114                }
9115            }
9116        };
9117
9118        try {
9119            who.linkToDeath(death, 0);
9120        } catch (RemoteException e) {
9121            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9122            return;
9123        }
9124
9125        synchronized (this) {
9126            Watchdog.getInstance().setAllowRestart(allowRestart);
9127            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9128            synchronized (death) {
9129                while (who.isBinderAlive()) {
9130                    try {
9131                        death.wait();
9132                    } catch (InterruptedException e) {
9133                    }
9134                }
9135            }
9136            Watchdog.getInstance().setAllowRestart(true);
9137        }
9138    }
9139
9140    @Override
9141    public void restart() {
9142        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9143                != PackageManager.PERMISSION_GRANTED) {
9144            throw new SecurityException("Requires permission "
9145                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9146        }
9147
9148        Log.i(TAG, "Sending shutdown broadcast...");
9149
9150        BroadcastReceiver br = new BroadcastReceiver() {
9151            @Override public void onReceive(Context context, Intent intent) {
9152                // Now the broadcast is done, finish up the low-level shutdown.
9153                Log.i(TAG, "Shutting down activity manager...");
9154                shutdown(10000);
9155                Log.i(TAG, "Shutdown complete, restarting!");
9156                Process.killProcess(Process.myPid());
9157                System.exit(10);
9158            }
9159        };
9160
9161        // First send the high-level shut down broadcast.
9162        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9163        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9164        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9165        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9166        mContext.sendOrderedBroadcastAsUser(intent,
9167                UserHandle.ALL, null, br, mHandler, 0, null, null);
9168        */
9169        br.onReceive(mContext, intent);
9170    }
9171
9172    private long getLowRamTimeSinceIdle(long now) {
9173        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9174    }
9175
9176    @Override
9177    public void performIdleMaintenance() {
9178        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9179                != PackageManager.PERMISSION_GRANTED) {
9180            throw new SecurityException("Requires permission "
9181                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9182        }
9183
9184        synchronized (this) {
9185            final long now = SystemClock.uptimeMillis();
9186            final long timeSinceLastIdle = now - mLastIdleTime;
9187            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9188            mLastIdleTime = now;
9189            mLowRamTimeSinceLastIdle = 0;
9190            if (mLowRamStartTime != 0) {
9191                mLowRamStartTime = now;
9192            }
9193
9194            StringBuilder sb = new StringBuilder(128);
9195            sb.append("Idle maintenance over ");
9196            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9197            sb.append(" low RAM for ");
9198            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9199            Slog.i(TAG, sb.toString());
9200
9201            // If at least 1/3 of our time since the last idle period has been spent
9202            // with RAM low, then we want to kill processes.
9203            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9204
9205            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9206                ProcessRecord proc = mLruProcesses.get(i);
9207                if (proc.notCachedSinceIdle) {
9208                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9209                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9210                        if (doKilling && proc.initialIdlePss != 0
9211                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9212                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9213                                    + " from " + proc.initialIdlePss + ")");
9214                        }
9215                    }
9216                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9217                    proc.notCachedSinceIdle = true;
9218                    proc.initialIdlePss = 0;
9219                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9220                            mSleeping, now);
9221                }
9222            }
9223
9224            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9225            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9226        }
9227    }
9228
9229    public final void startRunning(String pkg, String cls, String action,
9230            String data) {
9231        synchronized(this) {
9232            if (mStartRunning) {
9233                return;
9234            }
9235            mStartRunning = true;
9236            mTopComponent = pkg != null && cls != null
9237                    ? new ComponentName(pkg, cls) : null;
9238            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9239            mTopData = data;
9240            if (!mSystemReady) {
9241                return;
9242            }
9243        }
9244
9245        systemReady(null);
9246    }
9247
9248    private void retrieveSettings() {
9249        final ContentResolver resolver = mContext.getContentResolver();
9250        String debugApp = Settings.Global.getString(
9251            resolver, Settings.Global.DEBUG_APP);
9252        boolean waitForDebugger = Settings.Global.getInt(
9253            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9254        boolean alwaysFinishActivities = Settings.Global.getInt(
9255            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9256        boolean forceRtl = Settings.Global.getInt(
9257                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9258        // Transfer any global setting for forcing RTL layout, into a System Property
9259        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9260
9261        Configuration configuration = new Configuration();
9262        Settings.System.getConfiguration(resolver, configuration);
9263        if (forceRtl) {
9264            // This will take care of setting the correct layout direction flags
9265            configuration.setLayoutDirection(configuration.locale);
9266        }
9267
9268        synchronized (this) {
9269            mDebugApp = mOrigDebugApp = debugApp;
9270            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9271            mAlwaysFinishActivities = alwaysFinishActivities;
9272            // This happens before any activities are started, so we can
9273            // change mConfiguration in-place.
9274            updateConfigurationLocked(configuration, null, false, true);
9275            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9276        }
9277    }
9278
9279    public boolean testIsSystemReady() {
9280        // no need to synchronize(this) just to read & return the value
9281        return mSystemReady;
9282    }
9283
9284    private static File getCalledPreBootReceiversFile() {
9285        File dataDir = Environment.getDataDirectory();
9286        File systemDir = new File(dataDir, "system");
9287        File fname = new File(systemDir, "called_pre_boots.dat");
9288        return fname;
9289    }
9290
9291    static final int LAST_DONE_VERSION = 10000;
9292
9293    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9294        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9295        File file = getCalledPreBootReceiversFile();
9296        FileInputStream fis = null;
9297        try {
9298            fis = new FileInputStream(file);
9299            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9300            int fvers = dis.readInt();
9301            if (fvers == LAST_DONE_VERSION) {
9302                String vers = dis.readUTF();
9303                String codename = dis.readUTF();
9304                String build = dis.readUTF();
9305                if (android.os.Build.VERSION.RELEASE.equals(vers)
9306                        && android.os.Build.VERSION.CODENAME.equals(codename)
9307                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9308                    int num = dis.readInt();
9309                    while (num > 0) {
9310                        num--;
9311                        String pkg = dis.readUTF();
9312                        String cls = dis.readUTF();
9313                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9314                    }
9315                }
9316            }
9317        } catch (FileNotFoundException e) {
9318        } catch (IOException e) {
9319            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9320        } finally {
9321            if (fis != null) {
9322                try {
9323                    fis.close();
9324                } catch (IOException e) {
9325                }
9326            }
9327        }
9328        return lastDoneReceivers;
9329    }
9330
9331    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9332        File file = getCalledPreBootReceiversFile();
9333        FileOutputStream fos = null;
9334        DataOutputStream dos = null;
9335        try {
9336            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9337            fos = new FileOutputStream(file);
9338            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9339            dos.writeInt(LAST_DONE_VERSION);
9340            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9341            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9342            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9343            dos.writeInt(list.size());
9344            for (int i=0; i<list.size(); i++) {
9345                dos.writeUTF(list.get(i).getPackageName());
9346                dos.writeUTF(list.get(i).getClassName());
9347            }
9348        } catch (IOException e) {
9349            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9350            file.delete();
9351        } finally {
9352            FileUtils.sync(fos);
9353            if (dos != null) {
9354                try {
9355                    dos.close();
9356                } catch (IOException e) {
9357                    // TODO Auto-generated catch block
9358                    e.printStackTrace();
9359                }
9360            }
9361        }
9362    }
9363
9364    public void systemReady(final Runnable goingCallback) {
9365        synchronized(this) {
9366            if (mSystemReady) {
9367                if (goingCallback != null) goingCallback.run();
9368                return;
9369            }
9370
9371            // Check to see if there are any update receivers to run.
9372            if (!mDidUpdate) {
9373                if (mWaitingUpdate) {
9374                    return;
9375                }
9376                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9377                List<ResolveInfo> ris = null;
9378                try {
9379                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9380                            intent, null, 0, 0);
9381                } catch (RemoteException e) {
9382                }
9383                if (ris != null) {
9384                    for (int i=ris.size()-1; i>=0; i--) {
9385                        if ((ris.get(i).activityInfo.applicationInfo.flags
9386                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9387                            ris.remove(i);
9388                        }
9389                    }
9390                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9391
9392                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9393
9394                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9395                    for (int i=0; i<ris.size(); i++) {
9396                        ActivityInfo ai = ris.get(i).activityInfo;
9397                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9398                        if (lastDoneReceivers.contains(comp)) {
9399                            // We already did the pre boot receiver for this app with the current
9400                            // platform version, so don't do it again...
9401                            ris.remove(i);
9402                            i--;
9403                            // ...however, do keep it as one that has been done, so we don't
9404                            // forget about it when rewriting the file of last done receivers.
9405                            doneReceivers.add(comp);
9406                        }
9407                    }
9408
9409                    final int[] users = getUsersLocked();
9410                    for (int i=0; i<ris.size(); i++) {
9411                        ActivityInfo ai = ris.get(i).activityInfo;
9412                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9413                        doneReceivers.add(comp);
9414                        intent.setComponent(comp);
9415                        for (int j=0; j<users.length; j++) {
9416                            IIntentReceiver finisher = null;
9417                            if (i == ris.size()-1 && j == users.length-1) {
9418                                finisher = new IIntentReceiver.Stub() {
9419                                    public void performReceive(Intent intent, int resultCode,
9420                                            String data, Bundle extras, boolean ordered,
9421                                            boolean sticky, int sendingUser) {
9422                                        // The raw IIntentReceiver interface is called
9423                                        // with the AM lock held, so redispatch to
9424                                        // execute our code without the lock.
9425                                        mHandler.post(new Runnable() {
9426                                            public void run() {
9427                                                synchronized (ActivityManagerService.this) {
9428                                                    mDidUpdate = true;
9429                                                }
9430                                                writeLastDonePreBootReceivers(doneReceivers);
9431                                                showBootMessage(mContext.getText(
9432                                                        R.string.android_upgrading_complete),
9433                                                        false);
9434                                                systemReady(goingCallback);
9435                                            }
9436                                        });
9437                                    }
9438                                };
9439                            }
9440                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9441                                    + " for user " + users[j]);
9442                            broadcastIntentLocked(null, null, intent, null, finisher,
9443                                    0, null, null, null, AppOpsManager.OP_NONE,
9444                                    true, false, MY_PID, Process.SYSTEM_UID,
9445                                    users[j]);
9446                            if (finisher != null) {
9447                                mWaitingUpdate = true;
9448                            }
9449                        }
9450                    }
9451                }
9452                if (mWaitingUpdate) {
9453                    return;
9454                }
9455                mDidUpdate = true;
9456            }
9457
9458            mAppOpsService.systemReady();
9459            mSystemReady = true;
9460            if (!mStartRunning) {
9461                return;
9462            }
9463        }
9464
9465        ArrayList<ProcessRecord> procsToKill = null;
9466        synchronized(mPidsSelfLocked) {
9467            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9468                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9469                if (!isAllowedWhileBooting(proc.info)){
9470                    if (procsToKill == null) {
9471                        procsToKill = new ArrayList<ProcessRecord>();
9472                    }
9473                    procsToKill.add(proc);
9474                }
9475            }
9476        }
9477
9478        synchronized(this) {
9479            if (procsToKill != null) {
9480                for (int i=procsToKill.size()-1; i>=0; i--) {
9481                    ProcessRecord proc = procsToKill.get(i);
9482                    Slog.i(TAG, "Removing system update proc: " + proc);
9483                    removeProcessLocked(proc, true, false, "system update done");
9484                }
9485            }
9486
9487            // Now that we have cleaned up any update processes, we
9488            // are ready to start launching real processes and know that
9489            // we won't trample on them any more.
9490            mProcessesReady = true;
9491        }
9492
9493        Slog.i(TAG, "System now ready");
9494        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9495            SystemClock.uptimeMillis());
9496
9497        synchronized(this) {
9498            // Make sure we have no pre-ready processes sitting around.
9499
9500            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9501                ResolveInfo ri = mContext.getPackageManager()
9502                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9503                                STOCK_PM_FLAGS);
9504                CharSequence errorMsg = null;
9505                if (ri != null) {
9506                    ActivityInfo ai = ri.activityInfo;
9507                    ApplicationInfo app = ai.applicationInfo;
9508                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9509                        mTopAction = Intent.ACTION_FACTORY_TEST;
9510                        mTopData = null;
9511                        mTopComponent = new ComponentName(app.packageName,
9512                                ai.name);
9513                    } else {
9514                        errorMsg = mContext.getResources().getText(
9515                                com.android.internal.R.string.factorytest_not_system);
9516                    }
9517                } else {
9518                    errorMsg = mContext.getResources().getText(
9519                            com.android.internal.R.string.factorytest_no_action);
9520                }
9521                if (errorMsg != null) {
9522                    mTopAction = null;
9523                    mTopData = null;
9524                    mTopComponent = null;
9525                    Message msg = Message.obtain();
9526                    msg.what = SHOW_FACTORY_ERROR_MSG;
9527                    msg.getData().putCharSequence("msg", errorMsg);
9528                    mHandler.sendMessage(msg);
9529                }
9530            }
9531        }
9532
9533        retrieveSettings();
9534
9535        synchronized (this) {
9536            readGrantedUriPermissionsLocked();
9537        }
9538
9539        if (goingCallback != null) goingCallback.run();
9540
9541        synchronized (this) {
9542            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9543                try {
9544                    List apps = AppGlobals.getPackageManager().
9545                        getPersistentApplications(STOCK_PM_FLAGS);
9546                    if (apps != null) {
9547                        int N = apps.size();
9548                        int i;
9549                        for (i=0; i<N; i++) {
9550                            ApplicationInfo info
9551                                = (ApplicationInfo)apps.get(i);
9552                            if (info != null &&
9553                                    !info.packageName.equals("android")) {
9554                                addAppLocked(info, false);
9555                            }
9556                        }
9557                    }
9558                } catch (RemoteException ex) {
9559                    // pm is in same process, this will never happen.
9560                }
9561            }
9562
9563            // Start up initial activity.
9564            mBooting = true;
9565
9566            try {
9567                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9568                    Message msg = Message.obtain();
9569                    msg.what = SHOW_UID_ERROR_MSG;
9570                    mHandler.sendMessage(msg);
9571                }
9572            } catch (RemoteException e) {
9573            }
9574
9575            long ident = Binder.clearCallingIdentity();
9576            try {
9577                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9578                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9579                        | Intent.FLAG_RECEIVER_FOREGROUND);
9580                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9581                broadcastIntentLocked(null, null, intent,
9582                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9583                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9584                intent = new Intent(Intent.ACTION_USER_STARTING);
9585                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9586                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9587                broadcastIntentLocked(null, null, intent,
9588                        null, new IIntentReceiver.Stub() {
9589                            @Override
9590                            public void performReceive(Intent intent, int resultCode, String data,
9591                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9592                                    throws RemoteException {
9593                            }
9594                        }, 0, null, null,
9595                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9596                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9597            } finally {
9598                Binder.restoreCallingIdentity(ident);
9599            }
9600            mStackSupervisor.resumeTopActivitiesLocked();
9601            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9602        }
9603    }
9604
9605    private boolean makeAppCrashingLocked(ProcessRecord app,
9606            String shortMsg, String longMsg, String stackTrace) {
9607        app.crashing = true;
9608        app.crashingReport = generateProcessError(app,
9609                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9610        startAppProblemLocked(app);
9611        app.stopFreezingAllLocked();
9612        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9613    }
9614
9615    private void makeAppNotRespondingLocked(ProcessRecord app,
9616            String activity, String shortMsg, String longMsg) {
9617        app.notResponding = true;
9618        app.notRespondingReport = generateProcessError(app,
9619                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9620                activity, shortMsg, longMsg, null);
9621        startAppProblemLocked(app);
9622        app.stopFreezingAllLocked();
9623    }
9624
9625    /**
9626     * Generate a process error record, suitable for attachment to a ProcessRecord.
9627     *
9628     * @param app The ProcessRecord in which the error occurred.
9629     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9630     *                      ActivityManager.AppErrorStateInfo
9631     * @param activity The activity associated with the crash, if known.
9632     * @param shortMsg Short message describing the crash.
9633     * @param longMsg Long message describing the crash.
9634     * @param stackTrace Full crash stack trace, may be null.
9635     *
9636     * @return Returns a fully-formed AppErrorStateInfo record.
9637     */
9638    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9639            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9640        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9641
9642        report.condition = condition;
9643        report.processName = app.processName;
9644        report.pid = app.pid;
9645        report.uid = app.info.uid;
9646        report.tag = activity;
9647        report.shortMsg = shortMsg;
9648        report.longMsg = longMsg;
9649        report.stackTrace = stackTrace;
9650
9651        return report;
9652    }
9653
9654    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9655        synchronized (this) {
9656            app.crashing = false;
9657            app.crashingReport = null;
9658            app.notResponding = false;
9659            app.notRespondingReport = null;
9660            if (app.anrDialog == fromDialog) {
9661                app.anrDialog = null;
9662            }
9663            if (app.waitDialog == fromDialog) {
9664                app.waitDialog = null;
9665            }
9666            if (app.pid > 0 && app.pid != MY_PID) {
9667                handleAppCrashLocked(app, null, null, null);
9668                killUnneededProcessLocked(app, "user request after error");
9669            }
9670        }
9671    }
9672
9673    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9674            String stackTrace) {
9675        long now = SystemClock.uptimeMillis();
9676
9677        Long crashTime;
9678        if (!app.isolated) {
9679            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9680        } else {
9681            crashTime = null;
9682        }
9683        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9684            // This process loses!
9685            Slog.w(TAG, "Process " + app.info.processName
9686                    + " has crashed too many times: killing!");
9687            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9688                    app.userId, app.info.processName, app.uid);
9689            mStackSupervisor.handleAppCrashLocked(app);
9690            if (!app.persistent) {
9691                // We don't want to start this process again until the user
9692                // explicitly does so...  but for persistent process, we really
9693                // need to keep it running.  If a persistent process is actually
9694                // repeatedly crashing, then badness for everyone.
9695                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9696                        app.info.processName);
9697                if (!app.isolated) {
9698                    // XXX We don't have a way to mark isolated processes
9699                    // as bad, since they don't have a peristent identity.
9700                    mBadProcesses.put(app.info.processName, app.uid,
9701                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9702                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9703                }
9704                app.bad = true;
9705                app.removed = true;
9706                // Don't let services in this process be restarted and potentially
9707                // annoy the user repeatedly.  Unless it is persistent, since those
9708                // processes run critical code.
9709                removeProcessLocked(app, false, false, "crash");
9710                mStackSupervisor.resumeTopActivitiesLocked();
9711                return false;
9712            }
9713            mStackSupervisor.resumeTopActivitiesLocked();
9714        } else {
9715            mStackSupervisor.finishTopRunningActivityLocked(app);
9716        }
9717
9718        // Bump up the crash count of any services currently running in the proc.
9719        for (int i=app.services.size()-1; i>=0; i--) {
9720            // Any services running in the application need to be placed
9721            // back in the pending list.
9722            ServiceRecord sr = app.services.valueAt(i);
9723            sr.crashCount++;
9724        }
9725
9726        // If the crashing process is what we consider to be the "home process" and it has been
9727        // replaced by a third-party app, clear the package preferred activities from packages
9728        // with a home activity running in the process to prevent a repeatedly crashing app
9729        // from blocking the user to manually clear the list.
9730        final ArrayList<ActivityRecord> activities = app.activities;
9731        if (app == mHomeProcess && activities.size() > 0
9732                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9733            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9734                final ActivityRecord r = activities.get(activityNdx);
9735                if (r.isHomeActivity()) {
9736                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9737                    try {
9738                        ActivityThread.getPackageManager()
9739                                .clearPackagePreferredActivities(r.packageName);
9740                    } catch (RemoteException c) {
9741                        // pm is in same process, this will never happen.
9742                    }
9743                }
9744            }
9745        }
9746
9747        if (!app.isolated) {
9748            // XXX Can't keep track of crash times for isolated processes,
9749            // because they don't have a perisistent identity.
9750            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9751        }
9752
9753        return true;
9754    }
9755
9756    void startAppProblemLocked(ProcessRecord app) {
9757        if (app.userId == mCurrentUserId) {
9758            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9759                    mContext, app.info.packageName, app.info.flags);
9760        } else {
9761            // If this app is not running under the current user, then we
9762            // can't give it a report button because that would require
9763            // launching the report UI under a different user.
9764            app.errorReportReceiver = null;
9765        }
9766        skipCurrentReceiverLocked(app);
9767    }
9768
9769    void skipCurrentReceiverLocked(ProcessRecord app) {
9770        for (BroadcastQueue queue : mBroadcastQueues) {
9771            queue.skipCurrentReceiverLocked(app);
9772        }
9773    }
9774
9775    /**
9776     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9777     * The application process will exit immediately after this call returns.
9778     * @param app object of the crashing app, null for the system server
9779     * @param crashInfo describing the exception
9780     */
9781    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9782        ProcessRecord r = findAppProcess(app, "Crash");
9783        final String processName = app == null ? "system_server"
9784                : (r == null ? "unknown" : r.processName);
9785
9786        handleApplicationCrashInner("crash", r, processName, crashInfo);
9787    }
9788
9789    /* Native crash reporting uses this inner version because it needs to be somewhat
9790     * decoupled from the AM-managed cleanup lifecycle
9791     */
9792    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9793            ApplicationErrorReport.CrashInfo crashInfo) {
9794        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9795                UserHandle.getUserId(Binder.getCallingUid()), processName,
9796                r == null ? -1 : r.info.flags,
9797                crashInfo.exceptionClassName,
9798                crashInfo.exceptionMessage,
9799                crashInfo.throwFileName,
9800                crashInfo.throwLineNumber);
9801
9802        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9803
9804        crashApplication(r, crashInfo);
9805    }
9806
9807    public void handleApplicationStrictModeViolation(
9808            IBinder app,
9809            int violationMask,
9810            StrictMode.ViolationInfo info) {
9811        ProcessRecord r = findAppProcess(app, "StrictMode");
9812        if (r == null) {
9813            return;
9814        }
9815
9816        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9817            Integer stackFingerprint = info.hashCode();
9818            boolean logIt = true;
9819            synchronized (mAlreadyLoggedViolatedStacks) {
9820                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9821                    logIt = false;
9822                    // TODO: sub-sample into EventLog for these, with
9823                    // the info.durationMillis?  Then we'd get
9824                    // the relative pain numbers, without logging all
9825                    // the stack traces repeatedly.  We'd want to do
9826                    // likewise in the client code, which also does
9827                    // dup suppression, before the Binder call.
9828                } else {
9829                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9830                        mAlreadyLoggedViolatedStacks.clear();
9831                    }
9832                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9833                }
9834            }
9835            if (logIt) {
9836                logStrictModeViolationToDropBox(r, info);
9837            }
9838        }
9839
9840        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9841            AppErrorResult result = new AppErrorResult();
9842            synchronized (this) {
9843                final long origId = Binder.clearCallingIdentity();
9844
9845                Message msg = Message.obtain();
9846                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9847                HashMap<String, Object> data = new HashMap<String, Object>();
9848                data.put("result", result);
9849                data.put("app", r);
9850                data.put("violationMask", violationMask);
9851                data.put("info", info);
9852                msg.obj = data;
9853                mHandler.sendMessage(msg);
9854
9855                Binder.restoreCallingIdentity(origId);
9856            }
9857            int res = result.get();
9858            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9859        }
9860    }
9861
9862    // Depending on the policy in effect, there could be a bunch of
9863    // these in quick succession so we try to batch these together to
9864    // minimize disk writes, number of dropbox entries, and maximize
9865    // compression, by having more fewer, larger records.
9866    private void logStrictModeViolationToDropBox(
9867            ProcessRecord process,
9868            StrictMode.ViolationInfo info) {
9869        if (info == null) {
9870            return;
9871        }
9872        final boolean isSystemApp = process == null ||
9873                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9874                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9875        final String processName = process == null ? "unknown" : process.processName;
9876        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9877        final DropBoxManager dbox = (DropBoxManager)
9878                mContext.getSystemService(Context.DROPBOX_SERVICE);
9879
9880        // Exit early if the dropbox isn't configured to accept this report type.
9881        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9882
9883        boolean bufferWasEmpty;
9884        boolean needsFlush;
9885        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9886        synchronized (sb) {
9887            bufferWasEmpty = sb.length() == 0;
9888            appendDropBoxProcessHeaders(process, processName, sb);
9889            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9890            sb.append("System-App: ").append(isSystemApp).append("\n");
9891            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9892            if (info.violationNumThisLoop != 0) {
9893                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9894            }
9895            if (info.numAnimationsRunning != 0) {
9896                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9897            }
9898            if (info.broadcastIntentAction != null) {
9899                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9900            }
9901            if (info.durationMillis != -1) {
9902                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9903            }
9904            if (info.numInstances != -1) {
9905                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9906            }
9907            if (info.tags != null) {
9908                for (String tag : info.tags) {
9909                    sb.append("Span-Tag: ").append(tag).append("\n");
9910                }
9911            }
9912            sb.append("\n");
9913            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9914                sb.append(info.crashInfo.stackTrace);
9915            }
9916            sb.append("\n");
9917
9918            // Only buffer up to ~64k.  Various logging bits truncate
9919            // things at 128k.
9920            needsFlush = (sb.length() > 64 * 1024);
9921        }
9922
9923        // Flush immediately if the buffer's grown too large, or this
9924        // is a non-system app.  Non-system apps are isolated with a
9925        // different tag & policy and not batched.
9926        //
9927        // Batching is useful during internal testing with
9928        // StrictMode settings turned up high.  Without batching,
9929        // thousands of separate files could be created on boot.
9930        if (!isSystemApp || needsFlush) {
9931            new Thread("Error dump: " + dropboxTag) {
9932                @Override
9933                public void run() {
9934                    String report;
9935                    synchronized (sb) {
9936                        report = sb.toString();
9937                        sb.delete(0, sb.length());
9938                        sb.trimToSize();
9939                    }
9940                    if (report.length() != 0) {
9941                        dbox.addText(dropboxTag, report);
9942                    }
9943                }
9944            }.start();
9945            return;
9946        }
9947
9948        // System app batching:
9949        if (!bufferWasEmpty) {
9950            // An existing dropbox-writing thread is outstanding, so
9951            // we don't need to start it up.  The existing thread will
9952            // catch the buffer appends we just did.
9953            return;
9954        }
9955
9956        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9957        // (After this point, we shouldn't access AMS internal data structures.)
9958        new Thread("Error dump: " + dropboxTag) {
9959            @Override
9960            public void run() {
9961                // 5 second sleep to let stacks arrive and be batched together
9962                try {
9963                    Thread.sleep(5000);  // 5 seconds
9964                } catch (InterruptedException e) {}
9965
9966                String errorReport;
9967                synchronized (mStrictModeBuffer) {
9968                    errorReport = mStrictModeBuffer.toString();
9969                    if (errorReport.length() == 0) {
9970                        return;
9971                    }
9972                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9973                    mStrictModeBuffer.trimToSize();
9974                }
9975                dbox.addText(dropboxTag, errorReport);
9976            }
9977        }.start();
9978    }
9979
9980    /**
9981     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9982     * @param app object of the crashing app, null for the system server
9983     * @param tag reported by the caller
9984     * @param crashInfo describing the context of the error
9985     * @return true if the process should exit immediately (WTF is fatal)
9986     */
9987    public boolean handleApplicationWtf(IBinder app, String tag,
9988            ApplicationErrorReport.CrashInfo crashInfo) {
9989        ProcessRecord r = findAppProcess(app, "WTF");
9990        final String processName = app == null ? "system_server"
9991                : (r == null ? "unknown" : r.processName);
9992
9993        EventLog.writeEvent(EventLogTags.AM_WTF,
9994                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9995                processName,
9996                r == null ? -1 : r.info.flags,
9997                tag, crashInfo.exceptionMessage);
9998
9999        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10000
10001        if (r != null && r.pid != Process.myPid() &&
10002                Settings.Global.getInt(mContext.getContentResolver(),
10003                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10004            crashApplication(r, crashInfo);
10005            return true;
10006        } else {
10007            return false;
10008        }
10009    }
10010
10011    /**
10012     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10013     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10014     */
10015    private ProcessRecord findAppProcess(IBinder app, String reason) {
10016        if (app == null) {
10017            return null;
10018        }
10019
10020        synchronized (this) {
10021            final int NP = mProcessNames.getMap().size();
10022            for (int ip=0; ip<NP; ip++) {
10023                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10024                final int NA = apps.size();
10025                for (int ia=0; ia<NA; ia++) {
10026                    ProcessRecord p = apps.valueAt(ia);
10027                    if (p.thread != null && p.thread.asBinder() == app) {
10028                        return p;
10029                    }
10030                }
10031            }
10032
10033            Slog.w(TAG, "Can't find mystery application for " + reason
10034                    + " from pid=" + Binder.getCallingPid()
10035                    + " uid=" + Binder.getCallingUid() + ": " + app);
10036            return null;
10037        }
10038    }
10039
10040    /**
10041     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10042     * to append various headers to the dropbox log text.
10043     */
10044    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10045            StringBuilder sb) {
10046        // Watchdog thread ends up invoking this function (with
10047        // a null ProcessRecord) to add the stack file to dropbox.
10048        // Do not acquire a lock on this (am) in such cases, as it
10049        // could cause a potential deadlock, if and when watchdog
10050        // is invoked due to unavailability of lock on am and it
10051        // would prevent watchdog from killing system_server.
10052        if (process == null) {
10053            sb.append("Process: ").append(processName).append("\n");
10054            return;
10055        }
10056        // Note: ProcessRecord 'process' is guarded by the service
10057        // instance.  (notably process.pkgList, which could otherwise change
10058        // concurrently during execution of this method)
10059        synchronized (this) {
10060            sb.append("Process: ").append(processName).append("\n");
10061            int flags = process.info.flags;
10062            IPackageManager pm = AppGlobals.getPackageManager();
10063            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10064            for (int ip=0; ip<process.pkgList.size(); ip++) {
10065                String pkg = process.pkgList.keyAt(ip);
10066                sb.append("Package: ").append(pkg);
10067                try {
10068                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10069                    if (pi != null) {
10070                        sb.append(" v").append(pi.versionCode);
10071                        if (pi.versionName != null) {
10072                            sb.append(" (").append(pi.versionName).append(")");
10073                        }
10074                    }
10075                } catch (RemoteException e) {
10076                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10077                }
10078                sb.append("\n");
10079            }
10080        }
10081    }
10082
10083    private static String processClass(ProcessRecord process) {
10084        if (process == null || process.pid == MY_PID) {
10085            return "system_server";
10086        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10087            return "system_app";
10088        } else {
10089            return "data_app";
10090        }
10091    }
10092
10093    /**
10094     * Write a description of an error (crash, WTF, ANR) to the drop box.
10095     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10096     * @param process which caused the error, null means the system server
10097     * @param activity which triggered the error, null if unknown
10098     * @param parent activity related to the error, null if unknown
10099     * @param subject line related to the error, null if absent
10100     * @param report in long form describing the error, null if absent
10101     * @param logFile to include in the report, null if none
10102     * @param crashInfo giving an application stack trace, null if absent
10103     */
10104    public void addErrorToDropBox(String eventType,
10105            ProcessRecord process, String processName, ActivityRecord activity,
10106            ActivityRecord parent, String subject,
10107            final String report, final File logFile,
10108            final ApplicationErrorReport.CrashInfo crashInfo) {
10109        // NOTE -- this must never acquire the ActivityManagerService lock,
10110        // otherwise the watchdog may be prevented from resetting the system.
10111
10112        final String dropboxTag = processClass(process) + "_" + eventType;
10113        final DropBoxManager dbox = (DropBoxManager)
10114                mContext.getSystemService(Context.DROPBOX_SERVICE);
10115
10116        // Exit early if the dropbox isn't configured to accept this report type.
10117        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10118
10119        final StringBuilder sb = new StringBuilder(1024);
10120        appendDropBoxProcessHeaders(process, processName, sb);
10121        if (activity != null) {
10122            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10123        }
10124        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10125            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10126        }
10127        if (parent != null && parent != activity) {
10128            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10129        }
10130        if (subject != null) {
10131            sb.append("Subject: ").append(subject).append("\n");
10132        }
10133        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10134        if (Debug.isDebuggerConnected()) {
10135            sb.append("Debugger: Connected\n");
10136        }
10137        sb.append("\n");
10138
10139        // Do the rest in a worker thread to avoid blocking the caller on I/O
10140        // (After this point, we shouldn't access AMS internal data structures.)
10141        Thread worker = new Thread("Error dump: " + dropboxTag) {
10142            @Override
10143            public void run() {
10144                if (report != null) {
10145                    sb.append(report);
10146                }
10147                if (logFile != null) {
10148                    try {
10149                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10150                                    "\n\n[[TRUNCATED]]"));
10151                    } catch (IOException e) {
10152                        Slog.e(TAG, "Error reading " + logFile, e);
10153                    }
10154                }
10155                if (crashInfo != null && crashInfo.stackTrace != null) {
10156                    sb.append(crashInfo.stackTrace);
10157                }
10158
10159                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10160                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10161                if (lines > 0) {
10162                    sb.append("\n");
10163
10164                    // Merge several logcat streams, and take the last N lines
10165                    InputStreamReader input = null;
10166                    try {
10167                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10168                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10169                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10170
10171                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10172                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10173                        input = new InputStreamReader(logcat.getInputStream());
10174
10175                        int num;
10176                        char[] buf = new char[8192];
10177                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10178                    } catch (IOException e) {
10179                        Slog.e(TAG, "Error running logcat", e);
10180                    } finally {
10181                        if (input != null) try { input.close(); } catch (IOException e) {}
10182                    }
10183                }
10184
10185                dbox.addText(dropboxTag, sb.toString());
10186            }
10187        };
10188
10189        if (process == null) {
10190            // If process is null, we are being called from some internal code
10191            // and may be about to die -- run this synchronously.
10192            worker.run();
10193        } else {
10194            worker.start();
10195        }
10196    }
10197
10198    /**
10199     * Bring up the "unexpected error" dialog box for a crashing app.
10200     * Deal with edge cases (intercepts from instrumented applications,
10201     * ActivityController, error intent receivers, that sort of thing).
10202     * @param r the application crashing
10203     * @param crashInfo describing the failure
10204     */
10205    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10206        long timeMillis = System.currentTimeMillis();
10207        String shortMsg = crashInfo.exceptionClassName;
10208        String longMsg = crashInfo.exceptionMessage;
10209        String stackTrace = crashInfo.stackTrace;
10210        if (shortMsg != null && longMsg != null) {
10211            longMsg = shortMsg + ": " + longMsg;
10212        } else if (shortMsg != null) {
10213            longMsg = shortMsg;
10214        }
10215
10216        AppErrorResult result = new AppErrorResult();
10217        synchronized (this) {
10218            if (mController != null) {
10219                try {
10220                    String name = r != null ? r.processName : null;
10221                    int pid = r != null ? r.pid : Binder.getCallingPid();
10222                    if (!mController.appCrashed(name, pid,
10223                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10224                        Slog.w(TAG, "Force-killing crashed app " + name
10225                                + " at watcher's request");
10226                        Process.killProcess(pid);
10227                        return;
10228                    }
10229                } catch (RemoteException e) {
10230                    mController = null;
10231                    Watchdog.getInstance().setActivityController(null);
10232                }
10233            }
10234
10235            final long origId = Binder.clearCallingIdentity();
10236
10237            // If this process is running instrumentation, finish it.
10238            if (r != null && r.instrumentationClass != null) {
10239                Slog.w(TAG, "Error in app " + r.processName
10240                      + " running instrumentation " + r.instrumentationClass + ":");
10241                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10242                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10243                Bundle info = new Bundle();
10244                info.putString("shortMsg", shortMsg);
10245                info.putString("longMsg", longMsg);
10246                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10247                Binder.restoreCallingIdentity(origId);
10248                return;
10249            }
10250
10251            // If we can't identify the process or it's already exceeded its crash quota,
10252            // quit right away without showing a crash dialog.
10253            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10254                Binder.restoreCallingIdentity(origId);
10255                return;
10256            }
10257
10258            Message msg = Message.obtain();
10259            msg.what = SHOW_ERROR_MSG;
10260            HashMap data = new HashMap();
10261            data.put("result", result);
10262            data.put("app", r);
10263            msg.obj = data;
10264            mHandler.sendMessage(msg);
10265
10266            Binder.restoreCallingIdentity(origId);
10267        }
10268
10269        int res = result.get();
10270
10271        Intent appErrorIntent = null;
10272        synchronized (this) {
10273            if (r != null && !r.isolated) {
10274                // XXX Can't keep track of crash time for isolated processes,
10275                // since they don't have a persistent identity.
10276                mProcessCrashTimes.put(r.info.processName, r.uid,
10277                        SystemClock.uptimeMillis());
10278            }
10279            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10280                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10281            }
10282        }
10283
10284        if (appErrorIntent != null) {
10285            try {
10286                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10287            } catch (ActivityNotFoundException e) {
10288                Slog.w(TAG, "bug report receiver dissappeared", e);
10289            }
10290        }
10291    }
10292
10293    Intent createAppErrorIntentLocked(ProcessRecord r,
10294            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10295        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10296        if (report == null) {
10297            return null;
10298        }
10299        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10300        result.setComponent(r.errorReportReceiver);
10301        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10302        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10303        return result;
10304    }
10305
10306    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10307            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10308        if (r.errorReportReceiver == null) {
10309            return null;
10310        }
10311
10312        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10313            return null;
10314        }
10315
10316        ApplicationErrorReport report = new ApplicationErrorReport();
10317        report.packageName = r.info.packageName;
10318        report.installerPackageName = r.errorReportReceiver.getPackageName();
10319        report.processName = r.processName;
10320        report.time = timeMillis;
10321        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10322
10323        if (r.crashing || r.forceCrashReport) {
10324            report.type = ApplicationErrorReport.TYPE_CRASH;
10325            report.crashInfo = crashInfo;
10326        } else if (r.notResponding) {
10327            report.type = ApplicationErrorReport.TYPE_ANR;
10328            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10329
10330            report.anrInfo.activity = r.notRespondingReport.tag;
10331            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10332            report.anrInfo.info = r.notRespondingReport.longMsg;
10333        }
10334
10335        return report;
10336    }
10337
10338    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10339        enforceNotIsolatedCaller("getProcessesInErrorState");
10340        // assume our apps are happy - lazy create the list
10341        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10342
10343        final boolean allUsers = ActivityManager.checkUidPermission(
10344                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10345                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10346        int userId = UserHandle.getUserId(Binder.getCallingUid());
10347
10348        synchronized (this) {
10349
10350            // iterate across all processes
10351            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10352                ProcessRecord app = mLruProcesses.get(i);
10353                if (!allUsers && app.userId != userId) {
10354                    continue;
10355                }
10356                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10357                    // This one's in trouble, so we'll generate a report for it
10358                    // crashes are higher priority (in case there's a crash *and* an anr)
10359                    ActivityManager.ProcessErrorStateInfo report = null;
10360                    if (app.crashing) {
10361                        report = app.crashingReport;
10362                    } else if (app.notResponding) {
10363                        report = app.notRespondingReport;
10364                    }
10365
10366                    if (report != null) {
10367                        if (errList == null) {
10368                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10369                        }
10370                        errList.add(report);
10371                    } else {
10372                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10373                                " crashing = " + app.crashing +
10374                                " notResponding = " + app.notResponding);
10375                    }
10376                }
10377            }
10378        }
10379
10380        return errList;
10381    }
10382
10383    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10384        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10385            if (currApp != null) {
10386                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10387            }
10388            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10389        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10390            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10391        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10392            if (currApp != null) {
10393                currApp.lru = 0;
10394            }
10395            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10396        } else if (adj >= ProcessList.SERVICE_ADJ) {
10397            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10398        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10399            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10400        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10401            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10402        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10403            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10404        } else {
10405            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10406        }
10407    }
10408
10409    private void fillInProcMemInfo(ProcessRecord app,
10410            ActivityManager.RunningAppProcessInfo outInfo) {
10411        outInfo.pid = app.pid;
10412        outInfo.uid = app.info.uid;
10413        if (mHeavyWeightProcess == app) {
10414            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10415        }
10416        if (app.persistent) {
10417            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10418        }
10419        if (app.activities.size() > 0) {
10420            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10421        }
10422        outInfo.lastTrimLevel = app.trimMemoryLevel;
10423        int adj = app.curAdj;
10424        outInfo.importance = oomAdjToImportance(adj, outInfo);
10425        outInfo.importanceReasonCode = app.adjTypeCode;
10426    }
10427
10428    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10429        enforceNotIsolatedCaller("getRunningAppProcesses");
10430        // Lazy instantiation of list
10431        List<ActivityManager.RunningAppProcessInfo> runList = null;
10432        final boolean allUsers = ActivityManager.checkUidPermission(
10433                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10434                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10435        int userId = UserHandle.getUserId(Binder.getCallingUid());
10436        synchronized (this) {
10437            // Iterate across all processes
10438            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10439                ProcessRecord app = mLruProcesses.get(i);
10440                if (!allUsers && app.userId != userId) {
10441                    continue;
10442                }
10443                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10444                    // Generate process state info for running application
10445                    ActivityManager.RunningAppProcessInfo currApp =
10446                        new ActivityManager.RunningAppProcessInfo(app.processName,
10447                                app.pid, app.getPackageList());
10448                    fillInProcMemInfo(app, currApp);
10449                    if (app.adjSource instanceof ProcessRecord) {
10450                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10451                        currApp.importanceReasonImportance = oomAdjToImportance(
10452                                app.adjSourceOom, null);
10453                    } else if (app.adjSource instanceof ActivityRecord) {
10454                        ActivityRecord r = (ActivityRecord)app.adjSource;
10455                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10456                    }
10457                    if (app.adjTarget instanceof ComponentName) {
10458                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10459                    }
10460                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10461                    //        + " lru=" + currApp.lru);
10462                    if (runList == null) {
10463                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10464                    }
10465                    runList.add(currApp);
10466                }
10467            }
10468        }
10469        return runList;
10470    }
10471
10472    public List<ApplicationInfo> getRunningExternalApplications() {
10473        enforceNotIsolatedCaller("getRunningExternalApplications");
10474        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10475        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10476        if (runningApps != null && runningApps.size() > 0) {
10477            Set<String> extList = new HashSet<String>();
10478            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10479                if (app.pkgList != null) {
10480                    for (String pkg : app.pkgList) {
10481                        extList.add(pkg);
10482                    }
10483                }
10484            }
10485            IPackageManager pm = AppGlobals.getPackageManager();
10486            for (String pkg : extList) {
10487                try {
10488                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10489                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10490                        retList.add(info);
10491                    }
10492                } catch (RemoteException e) {
10493                }
10494            }
10495        }
10496        return retList;
10497    }
10498
10499    @Override
10500    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10501        enforceNotIsolatedCaller("getMyMemoryState");
10502        synchronized (this) {
10503            ProcessRecord proc;
10504            synchronized (mPidsSelfLocked) {
10505                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10506            }
10507            fillInProcMemInfo(proc, outInfo);
10508        }
10509    }
10510
10511    @Override
10512    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10513        if (checkCallingPermission(android.Manifest.permission.DUMP)
10514                != PackageManager.PERMISSION_GRANTED) {
10515            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10516                    + Binder.getCallingPid()
10517                    + ", uid=" + Binder.getCallingUid()
10518                    + " without permission "
10519                    + android.Manifest.permission.DUMP);
10520            return;
10521        }
10522
10523        boolean dumpAll = false;
10524        boolean dumpClient = false;
10525        String dumpPackage = null;
10526
10527        int opti = 0;
10528        while (opti < args.length) {
10529            String opt = args[opti];
10530            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10531                break;
10532            }
10533            opti++;
10534            if ("-a".equals(opt)) {
10535                dumpAll = true;
10536            } else if ("-c".equals(opt)) {
10537                dumpClient = true;
10538            } else if ("-h".equals(opt)) {
10539                pw.println("Activity manager dump options:");
10540                pw.println("  [-a] [-c] [-h] [cmd] ...");
10541                pw.println("  cmd may be one of:");
10542                pw.println("    a[ctivities]: activity stack state");
10543                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10544                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10545                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10546                pw.println("    o[om]: out of memory management");
10547                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10548                pw.println("    provider [COMP_SPEC]: provider client-side state");
10549                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10550                pw.println("    service [COMP_SPEC]: service client-side state");
10551                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10552                pw.println("    all: dump all activities");
10553                pw.println("    top: dump the top activity");
10554                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10555                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10556                pw.println("    a partial substring in a component name, a");
10557                pw.println("    hex object identifier.");
10558                pw.println("  -a: include all available server state.");
10559                pw.println("  -c: include client state.");
10560                return;
10561            } else {
10562                pw.println("Unknown argument: " + opt + "; use -h for help");
10563            }
10564        }
10565
10566        long origId = Binder.clearCallingIdentity();
10567        boolean more = false;
10568        // Is the caller requesting to dump a particular piece of data?
10569        if (opti < args.length) {
10570            String cmd = args[opti];
10571            opti++;
10572            if ("activities".equals(cmd) || "a".equals(cmd)) {
10573                synchronized (this) {
10574                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10575                }
10576            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10577                String[] newArgs;
10578                String name;
10579                if (opti >= args.length) {
10580                    name = null;
10581                    newArgs = EMPTY_STRING_ARRAY;
10582                } else {
10583                    name = args[opti];
10584                    opti++;
10585                    newArgs = new String[args.length - opti];
10586                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10587                            args.length - opti);
10588                }
10589                synchronized (this) {
10590                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10591                }
10592            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10593                String[] newArgs;
10594                String name;
10595                if (opti >= args.length) {
10596                    name = null;
10597                    newArgs = EMPTY_STRING_ARRAY;
10598                } else {
10599                    name = args[opti];
10600                    opti++;
10601                    newArgs = new String[args.length - opti];
10602                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10603                            args.length - opti);
10604                }
10605                synchronized (this) {
10606                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10607                }
10608            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10609                String[] newArgs;
10610                String name;
10611                if (opti >= args.length) {
10612                    name = null;
10613                    newArgs = EMPTY_STRING_ARRAY;
10614                } else {
10615                    name = args[opti];
10616                    opti++;
10617                    newArgs = new String[args.length - opti];
10618                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10619                            args.length - opti);
10620                }
10621                synchronized (this) {
10622                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10623                }
10624            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10625                synchronized (this) {
10626                    dumpOomLocked(fd, pw, args, opti, true);
10627                }
10628            } else if ("provider".equals(cmd)) {
10629                String[] newArgs;
10630                String name;
10631                if (opti >= args.length) {
10632                    name = null;
10633                    newArgs = EMPTY_STRING_ARRAY;
10634                } else {
10635                    name = args[opti];
10636                    opti++;
10637                    newArgs = new String[args.length - opti];
10638                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10639                }
10640                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10641                    pw.println("No providers match: " + name);
10642                    pw.println("Use -h for help.");
10643                }
10644            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10645                synchronized (this) {
10646                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10647                }
10648            } else if ("service".equals(cmd)) {
10649                String[] newArgs;
10650                String name;
10651                if (opti >= args.length) {
10652                    name = null;
10653                    newArgs = EMPTY_STRING_ARRAY;
10654                } else {
10655                    name = args[opti];
10656                    opti++;
10657                    newArgs = new String[args.length - opti];
10658                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10659                            args.length - opti);
10660                }
10661                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10662                    pw.println("No services match: " + name);
10663                    pw.println("Use -h for help.");
10664                }
10665            } else if ("package".equals(cmd)) {
10666                String[] newArgs;
10667                if (opti >= args.length) {
10668                    pw.println("package: no package name specified");
10669                    pw.println("Use -h for help.");
10670                } else {
10671                    dumpPackage = args[opti];
10672                    opti++;
10673                    newArgs = new String[args.length - opti];
10674                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10675                            args.length - opti);
10676                    args = newArgs;
10677                    opti = 0;
10678                    more = true;
10679                }
10680            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10681                synchronized (this) {
10682                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10683                }
10684            } else {
10685                // Dumping a single activity?
10686                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10687                    pw.println("Bad activity command, or no activities match: " + cmd);
10688                    pw.println("Use -h for help.");
10689                }
10690            }
10691            if (!more) {
10692                Binder.restoreCallingIdentity(origId);
10693                return;
10694            }
10695        }
10696
10697        // No piece of data specified, dump everything.
10698        synchronized (this) {
10699            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10700            pw.println();
10701            if (dumpAll) {
10702                pw.println("-------------------------------------------------------------------------------");
10703            }
10704            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10705            pw.println();
10706            if (dumpAll) {
10707                pw.println("-------------------------------------------------------------------------------");
10708            }
10709            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10710            pw.println();
10711            if (dumpAll) {
10712                pw.println("-------------------------------------------------------------------------------");
10713            }
10714            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10715            pw.println();
10716            if (dumpAll) {
10717                pw.println("-------------------------------------------------------------------------------");
10718            }
10719            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10720            pw.println();
10721            if (dumpAll) {
10722                pw.println("-------------------------------------------------------------------------------");
10723            }
10724            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10725        }
10726        Binder.restoreCallingIdentity(origId);
10727    }
10728
10729    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10730            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10731        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10732
10733        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10734                dumpPackage);
10735        boolean needSep = printedAnything;
10736
10737        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10738                dumpPackage, needSep, "  mFocusedActivity: ");
10739        if (printed) {
10740            printedAnything = true;
10741            needSep = false;
10742        }
10743
10744        if (dumpPackage == null) {
10745            if (needSep) {
10746                pw.println();
10747            }
10748            needSep = true;
10749            printedAnything = true;
10750            mStackSupervisor.dump(pw, "  ");
10751        }
10752
10753        if (mRecentTasks.size() > 0) {
10754            boolean printedHeader = false;
10755
10756            final int N = mRecentTasks.size();
10757            for (int i=0; i<N; i++) {
10758                TaskRecord tr = mRecentTasks.get(i);
10759                if (dumpPackage != null) {
10760                    if (tr.realActivity == null ||
10761                            !dumpPackage.equals(tr.realActivity)) {
10762                        continue;
10763                    }
10764                }
10765                if (!printedHeader) {
10766                    if (needSep) {
10767                        pw.println();
10768                    }
10769                    pw.println("  Recent tasks:");
10770                    printedHeader = true;
10771                    printedAnything = true;
10772                }
10773                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10774                        pw.println(tr);
10775                if (dumpAll) {
10776                    mRecentTasks.get(i).dump(pw, "    ");
10777                }
10778            }
10779        }
10780
10781        if (!printedAnything) {
10782            pw.println("  (nothing)");
10783        }
10784    }
10785
10786    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10787            int opti, boolean dumpAll, String dumpPackage) {
10788        boolean needSep = false;
10789        boolean printedAnything = false;
10790        int numPers = 0;
10791
10792        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10793
10794        if (dumpAll) {
10795            final int NP = mProcessNames.getMap().size();
10796            for (int ip=0; ip<NP; ip++) {
10797                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10798                final int NA = procs.size();
10799                for (int ia=0; ia<NA; ia++) {
10800                    ProcessRecord r = procs.valueAt(ia);
10801                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10802                        continue;
10803                    }
10804                    if (!needSep) {
10805                        pw.println("  All known processes:");
10806                        needSep = true;
10807                        printedAnything = true;
10808                    }
10809                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10810                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10811                        pw.print(" "); pw.println(r);
10812                    r.dump(pw, "    ");
10813                    if (r.persistent) {
10814                        numPers++;
10815                    }
10816                }
10817            }
10818        }
10819
10820        if (mIsolatedProcesses.size() > 0) {
10821            boolean printed = false;
10822            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10823                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10824                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10825                    continue;
10826                }
10827                if (!printed) {
10828                    if (needSep) {
10829                        pw.println();
10830                    }
10831                    pw.println("  Isolated process list (sorted by uid):");
10832                    printedAnything = true;
10833                    printed = true;
10834                    needSep = true;
10835                }
10836                pw.println(String.format("%sIsolated #%2d: %s",
10837                        "    ", i, r.toString()));
10838            }
10839        }
10840
10841        if (mLruProcesses.size() > 0) {
10842            if (needSep) {
10843                pw.println();
10844            }
10845            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10846                    pw.print(" total, non-act at ");
10847                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10848                    pw.print(", non-svc at ");
10849                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10850                    pw.println("):");
10851            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10852            needSep = true;
10853            printedAnything = true;
10854        }
10855
10856        if (dumpAll || dumpPackage != null) {
10857            synchronized (mPidsSelfLocked) {
10858                boolean printed = false;
10859                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10860                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10861                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10862                        continue;
10863                    }
10864                    if (!printed) {
10865                        if (needSep) pw.println();
10866                        needSep = true;
10867                        pw.println("  PID mappings:");
10868                        printed = true;
10869                        printedAnything = true;
10870                    }
10871                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10872                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10873                }
10874            }
10875        }
10876
10877        if (mForegroundProcesses.size() > 0) {
10878            synchronized (mPidsSelfLocked) {
10879                boolean printed = false;
10880                for (int i=0; i<mForegroundProcesses.size(); i++) {
10881                    ProcessRecord r = mPidsSelfLocked.get(
10882                            mForegroundProcesses.valueAt(i).pid);
10883                    if (dumpPackage != null && (r == null
10884                            || !r.pkgList.containsKey(dumpPackage))) {
10885                        continue;
10886                    }
10887                    if (!printed) {
10888                        if (needSep) pw.println();
10889                        needSep = true;
10890                        pw.println("  Foreground Processes:");
10891                        printed = true;
10892                        printedAnything = true;
10893                    }
10894                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10895                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10896                }
10897            }
10898        }
10899
10900        if (mPersistentStartingProcesses.size() > 0) {
10901            if (needSep) pw.println();
10902            needSep = true;
10903            printedAnything = true;
10904            pw.println("  Persisent processes that are starting:");
10905            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10906                    "Starting Norm", "Restarting PERS", dumpPackage);
10907        }
10908
10909        if (mRemovedProcesses.size() > 0) {
10910            if (needSep) pw.println();
10911            needSep = true;
10912            printedAnything = true;
10913            pw.println("  Processes that are being removed:");
10914            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10915                    "Removed Norm", "Removed PERS", dumpPackage);
10916        }
10917
10918        if (mProcessesOnHold.size() > 0) {
10919            if (needSep) pw.println();
10920            needSep = true;
10921            printedAnything = true;
10922            pw.println("  Processes that are on old until the system is ready:");
10923            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10924                    "OnHold Norm", "OnHold PERS", dumpPackage);
10925        }
10926
10927        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10928
10929        if (mProcessCrashTimes.getMap().size() > 0) {
10930            boolean printed = false;
10931            long now = SystemClock.uptimeMillis();
10932            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10933            final int NP = pmap.size();
10934            for (int ip=0; ip<NP; ip++) {
10935                String pname = pmap.keyAt(ip);
10936                SparseArray<Long> uids = pmap.valueAt(ip);
10937                final int N = uids.size();
10938                for (int i=0; i<N; i++) {
10939                    int puid = uids.keyAt(i);
10940                    ProcessRecord r = mProcessNames.get(pname, puid);
10941                    if (dumpPackage != null && (r == null
10942                            || !r.pkgList.containsKey(dumpPackage))) {
10943                        continue;
10944                    }
10945                    if (!printed) {
10946                        if (needSep) pw.println();
10947                        needSep = true;
10948                        pw.println("  Time since processes crashed:");
10949                        printed = true;
10950                        printedAnything = true;
10951                    }
10952                    pw.print("    Process "); pw.print(pname);
10953                            pw.print(" uid "); pw.print(puid);
10954                            pw.print(": last crashed ");
10955                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10956                            pw.println(" ago");
10957                }
10958            }
10959        }
10960
10961        if (mBadProcesses.getMap().size() > 0) {
10962            boolean printed = false;
10963            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10964            final int NP = pmap.size();
10965            for (int ip=0; ip<NP; ip++) {
10966                String pname = pmap.keyAt(ip);
10967                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10968                final int N = uids.size();
10969                for (int i=0; i<N; i++) {
10970                    int puid = uids.keyAt(i);
10971                    ProcessRecord r = mProcessNames.get(pname, puid);
10972                    if (dumpPackage != null && (r == null
10973                            || !r.pkgList.containsKey(dumpPackage))) {
10974                        continue;
10975                    }
10976                    if (!printed) {
10977                        if (needSep) pw.println();
10978                        needSep = true;
10979                        pw.println("  Bad processes:");
10980                        printedAnything = true;
10981                    }
10982                    BadProcessInfo info = uids.valueAt(i);
10983                    pw.print("    Bad process "); pw.print(pname);
10984                            pw.print(" uid "); pw.print(puid);
10985                            pw.print(": crashed at time "); pw.println(info.time);
10986                    if (info.shortMsg != null) {
10987                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10988                    }
10989                    if (info.longMsg != null) {
10990                        pw.print("      Long msg: "); pw.println(info.longMsg);
10991                    }
10992                    if (info.stack != null) {
10993                        pw.println("      Stack:");
10994                        int lastPos = 0;
10995                        for (int pos=0; pos<info.stack.length(); pos++) {
10996                            if (info.stack.charAt(pos) == '\n') {
10997                                pw.print("        ");
10998                                pw.write(info.stack, lastPos, pos-lastPos);
10999                                pw.println();
11000                                lastPos = pos+1;
11001                            }
11002                        }
11003                        if (lastPos < info.stack.length()) {
11004                            pw.print("        ");
11005                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11006                            pw.println();
11007                        }
11008                    }
11009                }
11010            }
11011        }
11012
11013        if (dumpPackage == null) {
11014            pw.println();
11015            needSep = false;
11016            pw.println("  mStartedUsers:");
11017            for (int i=0; i<mStartedUsers.size(); i++) {
11018                UserStartedState uss = mStartedUsers.valueAt(i);
11019                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11020                        pw.print(": "); uss.dump("", pw);
11021            }
11022            pw.print("  mStartedUserArray: [");
11023            for (int i=0; i<mStartedUserArray.length; i++) {
11024                if (i > 0) pw.print(", ");
11025                pw.print(mStartedUserArray[i]);
11026            }
11027            pw.println("]");
11028            pw.print("  mUserLru: [");
11029            for (int i=0; i<mUserLru.size(); i++) {
11030                if (i > 0) pw.print(", ");
11031                pw.print(mUserLru.get(i));
11032            }
11033            pw.println("]");
11034            if (dumpAll) {
11035                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11036            }
11037        }
11038        if (mHomeProcess != null && (dumpPackage == null
11039                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11040            if (needSep) {
11041                pw.println();
11042                needSep = false;
11043            }
11044            pw.println("  mHomeProcess: " + mHomeProcess);
11045        }
11046        if (mPreviousProcess != null && (dumpPackage == null
11047                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11048            if (needSep) {
11049                pw.println();
11050                needSep = false;
11051            }
11052            pw.println("  mPreviousProcess: " + mPreviousProcess);
11053        }
11054        if (dumpAll) {
11055            StringBuilder sb = new StringBuilder(128);
11056            sb.append("  mPreviousProcessVisibleTime: ");
11057            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11058            pw.println(sb);
11059        }
11060        if (mHeavyWeightProcess != null && (dumpPackage == null
11061                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11062            if (needSep) {
11063                pw.println();
11064                needSep = false;
11065            }
11066            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11067        }
11068        if (dumpPackage == null) {
11069            pw.println("  mConfiguration: " + mConfiguration);
11070        }
11071        if (dumpAll) {
11072            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11073            if (mCompatModePackages.getPackages().size() > 0) {
11074                boolean printed = false;
11075                for (Map.Entry<String, Integer> entry
11076                        : mCompatModePackages.getPackages().entrySet()) {
11077                    String pkg = entry.getKey();
11078                    int mode = entry.getValue();
11079                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11080                        continue;
11081                    }
11082                    if (!printed) {
11083                        pw.println("  mScreenCompatPackages:");
11084                        printed = true;
11085                    }
11086                    pw.print("    "); pw.print(pkg); pw.print(": ");
11087                            pw.print(mode); pw.println();
11088                }
11089            }
11090        }
11091        if (dumpPackage == null) {
11092            if (mSleeping || mWentToSleep || mLockScreenShown) {
11093                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11094                        + " mLockScreenShown " + mLockScreenShown);
11095            }
11096            if (mShuttingDown) {
11097                pw.println("  mShuttingDown=" + mShuttingDown);
11098            }
11099        }
11100        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11101                || mOrigWaitForDebugger) {
11102            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11103                    || dumpPackage.equals(mOrigDebugApp)) {
11104                if (needSep) {
11105                    pw.println();
11106                    needSep = false;
11107                }
11108                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11109                        + " mDebugTransient=" + mDebugTransient
11110                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11111            }
11112        }
11113        if (mOpenGlTraceApp != null) {
11114            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11115                if (needSep) {
11116                    pw.println();
11117                    needSep = false;
11118                }
11119                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11120            }
11121        }
11122        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11123                || mProfileFd != null) {
11124            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11125                if (needSep) {
11126                    pw.println();
11127                    needSep = false;
11128                }
11129                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11130                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11131                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11132                        + mAutoStopProfiler);
11133            }
11134        }
11135        if (dumpPackage == null) {
11136            if (mAlwaysFinishActivities || mController != null) {
11137                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11138                        + " mController=" + mController);
11139            }
11140            if (dumpAll) {
11141                pw.println("  Total persistent processes: " + numPers);
11142                pw.println("  mStartRunning=" + mStartRunning
11143                        + " mProcessesReady=" + mProcessesReady
11144                        + " mSystemReady=" + mSystemReady);
11145                pw.println("  mBooting=" + mBooting
11146                        + " mBooted=" + mBooted
11147                        + " mFactoryTest=" + mFactoryTest);
11148                pw.print("  mLastPowerCheckRealtime=");
11149                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11150                        pw.println("");
11151                pw.print("  mLastPowerCheckUptime=");
11152                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11153                        pw.println("");
11154                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11155                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11156                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11157                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11158                        + " (" + mLruProcesses.size() + " total)"
11159                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11160                        + " mNumServiceProcs=" + mNumServiceProcs
11161                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11162                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11163                        + " mLastMemoryLevel" + mLastMemoryLevel
11164                        + " mLastNumProcesses" + mLastNumProcesses);
11165                long now = SystemClock.uptimeMillis();
11166                pw.print("  mLastIdleTime=");
11167                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11168                        pw.print(" mLowRamSinceLastIdle=");
11169                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11170                        pw.println();
11171            }
11172        }
11173
11174        if (!printedAnything) {
11175            pw.println("  (nothing)");
11176        }
11177    }
11178
11179    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11180            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11181        if (mProcessesToGc.size() > 0) {
11182            boolean printed = false;
11183            long now = SystemClock.uptimeMillis();
11184            for (int i=0; i<mProcessesToGc.size(); i++) {
11185                ProcessRecord proc = mProcessesToGc.get(i);
11186                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11187                    continue;
11188                }
11189                if (!printed) {
11190                    if (needSep) pw.println();
11191                    needSep = true;
11192                    pw.println("  Processes that are waiting to GC:");
11193                    printed = true;
11194                }
11195                pw.print("    Process "); pw.println(proc);
11196                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11197                        pw.print(", last gced=");
11198                        pw.print(now-proc.lastRequestedGc);
11199                        pw.print(" ms ago, last lowMem=");
11200                        pw.print(now-proc.lastLowMemory);
11201                        pw.println(" ms ago");
11202
11203            }
11204        }
11205        return needSep;
11206    }
11207
11208    void printOomLevel(PrintWriter pw, String name, int adj) {
11209        pw.print("    ");
11210        if (adj >= 0) {
11211            pw.print(' ');
11212            if (adj < 10) pw.print(' ');
11213        } else {
11214            if (adj > -10) pw.print(' ');
11215        }
11216        pw.print(adj);
11217        pw.print(": ");
11218        pw.print(name);
11219        pw.print(" (");
11220        pw.print(mProcessList.getMemLevel(adj)/1024);
11221        pw.println(" kB)");
11222    }
11223
11224    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11225            int opti, boolean dumpAll) {
11226        boolean needSep = false;
11227
11228        if (mLruProcesses.size() > 0) {
11229            if (needSep) pw.println();
11230            needSep = true;
11231            pw.println("  OOM levels:");
11232            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11233            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11234            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11235            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11236            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11237            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11238            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11239            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11240            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11241            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11242            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11243            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11244            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11245
11246            if (needSep) pw.println();
11247            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11248                    pw.print(" total, non-act at ");
11249                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11250                    pw.print(", non-svc at ");
11251                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11252                    pw.println("):");
11253            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11254            needSep = true;
11255        }
11256
11257        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11258
11259        pw.println();
11260        pw.println("  mHomeProcess: " + mHomeProcess);
11261        pw.println("  mPreviousProcess: " + mPreviousProcess);
11262        if (mHeavyWeightProcess != null) {
11263            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11264        }
11265
11266        return true;
11267    }
11268
11269    /**
11270     * There are three ways to call this:
11271     *  - no provider specified: dump all the providers
11272     *  - a flattened component name that matched an existing provider was specified as the
11273     *    first arg: dump that one provider
11274     *  - the first arg isn't the flattened component name of an existing provider:
11275     *    dump all providers whose component contains the first arg as a substring
11276     */
11277    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11278            int opti, boolean dumpAll) {
11279        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11280    }
11281
11282    static class ItemMatcher {
11283        ArrayList<ComponentName> components;
11284        ArrayList<String> strings;
11285        ArrayList<Integer> objects;
11286        boolean all;
11287
11288        ItemMatcher() {
11289            all = true;
11290        }
11291
11292        void build(String name) {
11293            ComponentName componentName = ComponentName.unflattenFromString(name);
11294            if (componentName != null) {
11295                if (components == null) {
11296                    components = new ArrayList<ComponentName>();
11297                }
11298                components.add(componentName);
11299                all = false;
11300            } else {
11301                int objectId = 0;
11302                // Not a '/' separated full component name; maybe an object ID?
11303                try {
11304                    objectId = Integer.parseInt(name, 16);
11305                    if (objects == null) {
11306                        objects = new ArrayList<Integer>();
11307                    }
11308                    objects.add(objectId);
11309                    all = false;
11310                } catch (RuntimeException e) {
11311                    // Not an integer; just do string match.
11312                    if (strings == null) {
11313                        strings = new ArrayList<String>();
11314                    }
11315                    strings.add(name);
11316                    all = false;
11317                }
11318            }
11319        }
11320
11321        int build(String[] args, int opti) {
11322            for (; opti<args.length; opti++) {
11323                String name = args[opti];
11324                if ("--".equals(name)) {
11325                    return opti+1;
11326                }
11327                build(name);
11328            }
11329            return opti;
11330        }
11331
11332        boolean match(Object object, ComponentName comp) {
11333            if (all) {
11334                return true;
11335            }
11336            if (components != null) {
11337                for (int i=0; i<components.size(); i++) {
11338                    if (components.get(i).equals(comp)) {
11339                        return true;
11340                    }
11341                }
11342            }
11343            if (objects != null) {
11344                for (int i=0; i<objects.size(); i++) {
11345                    if (System.identityHashCode(object) == objects.get(i)) {
11346                        return true;
11347                    }
11348                }
11349            }
11350            if (strings != null) {
11351                String flat = comp.flattenToString();
11352                for (int i=0; i<strings.size(); i++) {
11353                    if (flat.contains(strings.get(i))) {
11354                        return true;
11355                    }
11356                }
11357            }
11358            return false;
11359        }
11360    }
11361
11362    /**
11363     * There are three things that cmd can be:
11364     *  - a flattened component name that matches an existing activity
11365     *  - the cmd arg isn't the flattened component name of an existing activity:
11366     *    dump all activity whose component contains the cmd as a substring
11367     *  - A hex number of the ActivityRecord object instance.
11368     */
11369    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11370            int opti, boolean dumpAll) {
11371        ArrayList<ActivityRecord> activities;
11372
11373        synchronized (this) {
11374            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11375        }
11376
11377        if (activities.size() <= 0) {
11378            return false;
11379        }
11380
11381        String[] newArgs = new String[args.length - opti];
11382        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11383
11384        TaskRecord lastTask = null;
11385        boolean needSep = false;
11386        for (int i=activities.size()-1; i>=0; i--) {
11387            ActivityRecord r = activities.get(i);
11388            if (needSep) {
11389                pw.println();
11390            }
11391            needSep = true;
11392            synchronized (this) {
11393                if (lastTask != r.task) {
11394                    lastTask = r.task;
11395                    pw.print("TASK "); pw.print(lastTask.affinity);
11396                            pw.print(" id="); pw.println(lastTask.taskId);
11397                    if (dumpAll) {
11398                        lastTask.dump(pw, "  ");
11399                    }
11400                }
11401            }
11402            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11403        }
11404        return true;
11405    }
11406
11407    /**
11408     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11409     * there is a thread associated with the activity.
11410     */
11411    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11412            final ActivityRecord r, String[] args, boolean dumpAll) {
11413        String innerPrefix = prefix + "  ";
11414        synchronized (this) {
11415            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11416                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11417                    pw.print(" pid=");
11418                    if (r.app != null) pw.println(r.app.pid);
11419                    else pw.println("(not running)");
11420            if (dumpAll) {
11421                r.dump(pw, innerPrefix);
11422            }
11423        }
11424        if (r.app != null && r.app.thread != null) {
11425            // flush anything that is already in the PrintWriter since the thread is going
11426            // to write to the file descriptor directly
11427            pw.flush();
11428            try {
11429                TransferPipe tp = new TransferPipe();
11430                try {
11431                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11432                            r.appToken, innerPrefix, args);
11433                    tp.go(fd);
11434                } finally {
11435                    tp.kill();
11436                }
11437            } catch (IOException e) {
11438                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11439            } catch (RemoteException e) {
11440                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11441            }
11442        }
11443    }
11444
11445    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11446            int opti, boolean dumpAll, String dumpPackage) {
11447        boolean needSep = false;
11448        boolean onlyHistory = false;
11449        boolean printedAnything = false;
11450
11451        if ("history".equals(dumpPackage)) {
11452            if (opti < args.length && "-s".equals(args[opti])) {
11453                dumpAll = false;
11454            }
11455            onlyHistory = true;
11456            dumpPackage = null;
11457        }
11458
11459        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11460        if (!onlyHistory && dumpAll) {
11461            if (mRegisteredReceivers.size() > 0) {
11462                boolean printed = false;
11463                Iterator it = mRegisteredReceivers.values().iterator();
11464                while (it.hasNext()) {
11465                    ReceiverList r = (ReceiverList)it.next();
11466                    if (dumpPackage != null && (r.app == null ||
11467                            !dumpPackage.equals(r.app.info.packageName))) {
11468                        continue;
11469                    }
11470                    if (!printed) {
11471                        pw.println("  Registered Receivers:");
11472                        needSep = true;
11473                        printed = true;
11474                        printedAnything = true;
11475                    }
11476                    pw.print("  * "); pw.println(r);
11477                    r.dump(pw, "    ");
11478                }
11479            }
11480
11481            if (mReceiverResolver.dump(pw, needSep ?
11482                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11483                    "    ", dumpPackage, false)) {
11484                needSep = true;
11485                printedAnything = true;
11486            }
11487        }
11488
11489        for (BroadcastQueue q : mBroadcastQueues) {
11490            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11491            printedAnything |= needSep;
11492        }
11493
11494        needSep = true;
11495
11496        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11497            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11498                if (needSep) {
11499                    pw.println();
11500                }
11501                needSep = true;
11502                printedAnything = true;
11503                pw.print("  Sticky broadcasts for user ");
11504                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11505                StringBuilder sb = new StringBuilder(128);
11506                for (Map.Entry<String, ArrayList<Intent>> ent
11507                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11508                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11509                    if (dumpAll) {
11510                        pw.println(":");
11511                        ArrayList<Intent> intents = ent.getValue();
11512                        final int N = intents.size();
11513                        for (int i=0; i<N; i++) {
11514                            sb.setLength(0);
11515                            sb.append("    Intent: ");
11516                            intents.get(i).toShortString(sb, false, true, false, false);
11517                            pw.println(sb.toString());
11518                            Bundle bundle = intents.get(i).getExtras();
11519                            if (bundle != null) {
11520                                pw.print("      ");
11521                                pw.println(bundle.toString());
11522                            }
11523                        }
11524                    } else {
11525                        pw.println("");
11526                    }
11527                }
11528            }
11529        }
11530
11531        if (!onlyHistory && dumpAll) {
11532            pw.println();
11533            for (BroadcastQueue queue : mBroadcastQueues) {
11534                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11535                        + queue.mBroadcastsScheduled);
11536            }
11537            pw.println("  mHandler:");
11538            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11539            needSep = true;
11540            printedAnything = true;
11541        }
11542
11543        if (!printedAnything) {
11544            pw.println("  (nothing)");
11545        }
11546    }
11547
11548    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11549            int opti, boolean dumpAll, String dumpPackage) {
11550        boolean needSep;
11551        boolean printedAnything = false;
11552
11553        ItemMatcher matcher = new ItemMatcher();
11554        matcher.build(args, opti);
11555
11556        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11557
11558        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11559        printedAnything |= needSep;
11560
11561        if (mLaunchingProviders.size() > 0) {
11562            boolean printed = false;
11563            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11564                ContentProviderRecord r = mLaunchingProviders.get(i);
11565                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11566                    continue;
11567                }
11568                if (!printed) {
11569                    if (needSep) pw.println();
11570                    needSep = true;
11571                    pw.println("  Launching content providers:");
11572                    printed = true;
11573                    printedAnything = true;
11574                }
11575                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11576                        pw.println(r);
11577            }
11578        }
11579
11580        if (mGrantedUriPermissions.size() > 0) {
11581            boolean printed = false;
11582            int dumpUid = -2;
11583            if (dumpPackage != null) {
11584                try {
11585                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11586                } catch (NameNotFoundException e) {
11587                    dumpUid = -1;
11588                }
11589            }
11590            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11591                int uid = mGrantedUriPermissions.keyAt(i);
11592                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11593                    continue;
11594                }
11595                ArrayMap<Uri, UriPermission> perms
11596                        = mGrantedUriPermissions.valueAt(i);
11597                if (!printed) {
11598                    if (needSep) pw.println();
11599                    needSep = true;
11600                    pw.println("  Granted Uri Permissions:");
11601                    printed = true;
11602                    printedAnything = true;
11603                }
11604                pw.print("  * UID "); pw.print(uid);
11605                        pw.println(" holds:");
11606                for (UriPermission perm : perms.values()) {
11607                    pw.print("    "); pw.println(perm);
11608                    if (dumpAll) {
11609                        perm.dump(pw, "      ");
11610                    }
11611                }
11612            }
11613        }
11614
11615        if (!printedAnything) {
11616            pw.println("  (nothing)");
11617        }
11618    }
11619
11620    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11621            int opti, boolean dumpAll, String dumpPackage) {
11622        boolean printed = false;
11623
11624        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11625
11626        if (mIntentSenderRecords.size() > 0) {
11627            Iterator<WeakReference<PendingIntentRecord>> it
11628                    = mIntentSenderRecords.values().iterator();
11629            while (it.hasNext()) {
11630                WeakReference<PendingIntentRecord> ref = it.next();
11631                PendingIntentRecord rec = ref != null ? ref.get(): null;
11632                if (dumpPackage != null && (rec == null
11633                        || !dumpPackage.equals(rec.key.packageName))) {
11634                    continue;
11635                }
11636                printed = true;
11637                if (rec != null) {
11638                    pw.print("  * "); pw.println(rec);
11639                    if (dumpAll) {
11640                        rec.dump(pw, "    ");
11641                    }
11642                } else {
11643                    pw.print("  * "); pw.println(ref);
11644                }
11645            }
11646        }
11647
11648        if (!printed) {
11649            pw.println("  (nothing)");
11650        }
11651    }
11652
11653    private static final int dumpProcessList(PrintWriter pw,
11654            ActivityManagerService service, List list,
11655            String prefix, String normalLabel, String persistentLabel,
11656            String dumpPackage) {
11657        int numPers = 0;
11658        final int N = list.size()-1;
11659        for (int i=N; i>=0; i--) {
11660            ProcessRecord r = (ProcessRecord)list.get(i);
11661            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11662                continue;
11663            }
11664            pw.println(String.format("%s%s #%2d: %s",
11665                    prefix, (r.persistent ? persistentLabel : normalLabel),
11666                    i, r.toString()));
11667            if (r.persistent) {
11668                numPers++;
11669            }
11670        }
11671        return numPers;
11672    }
11673
11674    private static final boolean dumpProcessOomList(PrintWriter pw,
11675            ActivityManagerService service, List<ProcessRecord> origList,
11676            String prefix, String normalLabel, String persistentLabel,
11677            boolean inclDetails, String dumpPackage) {
11678
11679        ArrayList<Pair<ProcessRecord, Integer>> list
11680                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11681        for (int i=0; i<origList.size(); i++) {
11682            ProcessRecord r = origList.get(i);
11683            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11684                continue;
11685            }
11686            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11687        }
11688
11689        if (list.size() <= 0) {
11690            return false;
11691        }
11692
11693        Comparator<Pair<ProcessRecord, Integer>> comparator
11694                = new Comparator<Pair<ProcessRecord, Integer>>() {
11695            @Override
11696            public int compare(Pair<ProcessRecord, Integer> object1,
11697                    Pair<ProcessRecord, Integer> object2) {
11698                if (object1.first.setAdj != object2.first.setAdj) {
11699                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11700                }
11701                if (object1.second.intValue() != object2.second.intValue()) {
11702                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11703                }
11704                return 0;
11705            }
11706        };
11707
11708        Collections.sort(list, comparator);
11709
11710        final long curRealtime = SystemClock.elapsedRealtime();
11711        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11712        final long curUptime = SystemClock.uptimeMillis();
11713        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11714
11715        for (int i=list.size()-1; i>=0; i--) {
11716            ProcessRecord r = list.get(i).first;
11717            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11718            char schedGroup;
11719            switch (r.setSchedGroup) {
11720                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11721                    schedGroup = 'B';
11722                    break;
11723                case Process.THREAD_GROUP_DEFAULT:
11724                    schedGroup = 'F';
11725                    break;
11726                default:
11727                    schedGroup = '?';
11728                    break;
11729            }
11730            char foreground;
11731            if (r.foregroundActivities) {
11732                foreground = 'A';
11733            } else if (r.foregroundServices) {
11734                foreground = 'S';
11735            } else {
11736                foreground = ' ';
11737            }
11738            String procState = ProcessList.makeProcStateString(r.curProcState);
11739            pw.print(prefix);
11740            pw.print(r.persistent ? persistentLabel : normalLabel);
11741            pw.print(" #");
11742            int num = (origList.size()-1)-list.get(i).second;
11743            if (num < 10) pw.print(' ');
11744            pw.print(num);
11745            pw.print(": ");
11746            pw.print(oomAdj);
11747            pw.print(' ');
11748            pw.print(schedGroup);
11749            pw.print('/');
11750            pw.print(foreground);
11751            pw.print('/');
11752            pw.print(procState);
11753            pw.print(" trm:");
11754            if (r.trimMemoryLevel < 10) pw.print(' ');
11755            pw.print(r.trimMemoryLevel);
11756            pw.print(' ');
11757            pw.print(r.toShortString());
11758            pw.print(" (");
11759            pw.print(r.adjType);
11760            pw.println(')');
11761            if (r.adjSource != null || r.adjTarget != null) {
11762                pw.print(prefix);
11763                pw.print("    ");
11764                if (r.adjTarget instanceof ComponentName) {
11765                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11766                } else if (r.adjTarget != null) {
11767                    pw.print(r.adjTarget.toString());
11768                } else {
11769                    pw.print("{null}");
11770                }
11771                pw.print("<=");
11772                if (r.adjSource instanceof ProcessRecord) {
11773                    pw.print("Proc{");
11774                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11775                    pw.println("}");
11776                } else if (r.adjSource != null) {
11777                    pw.println(r.adjSource.toString());
11778                } else {
11779                    pw.println("{null}");
11780                }
11781            }
11782            if (inclDetails) {
11783                pw.print(prefix);
11784                pw.print("    ");
11785                pw.print("oom: max="); pw.print(r.maxAdj);
11786                pw.print(" curRaw="); pw.print(r.curRawAdj);
11787                pw.print(" setRaw="); pw.print(r.setRawAdj);
11788                pw.print(" cur="); pw.print(r.curAdj);
11789                pw.print(" set="); pw.println(r.setAdj);
11790                pw.print(prefix);
11791                pw.print("    ");
11792                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11793                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11794                pw.print(" lastPss="); pw.print(r.lastPss);
11795                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11796                pw.print(prefix);
11797                pw.print("    ");
11798                pw.print("keeping="); pw.print(r.keeping);
11799                pw.print(" cached="); pw.print(r.cached);
11800                pw.print(" empty="); pw.print(r.empty);
11801                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11802
11803                if (!r.keeping) {
11804                    if (r.lastWakeTime != 0) {
11805                        long wtime;
11806                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11807                        synchronized (stats) {
11808                            wtime = stats.getProcessWakeTime(r.info.uid,
11809                                    r.pid, curRealtime);
11810                        }
11811                        long timeUsed = wtime - r.lastWakeTime;
11812                        pw.print(prefix);
11813                        pw.print("    ");
11814                        pw.print("keep awake over ");
11815                        TimeUtils.formatDuration(realtimeSince, pw);
11816                        pw.print(" used ");
11817                        TimeUtils.formatDuration(timeUsed, pw);
11818                        pw.print(" (");
11819                        pw.print((timeUsed*100)/realtimeSince);
11820                        pw.println("%)");
11821                    }
11822                    if (r.lastCpuTime != 0) {
11823                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11824                        pw.print(prefix);
11825                        pw.print("    ");
11826                        pw.print("run cpu over ");
11827                        TimeUtils.formatDuration(uptimeSince, pw);
11828                        pw.print(" used ");
11829                        TimeUtils.formatDuration(timeUsed, pw);
11830                        pw.print(" (");
11831                        pw.print((timeUsed*100)/uptimeSince);
11832                        pw.println("%)");
11833                    }
11834                }
11835            }
11836        }
11837        return true;
11838    }
11839
11840    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11841        ArrayList<ProcessRecord> procs;
11842        synchronized (this) {
11843            if (args != null && args.length > start
11844                    && args[start].charAt(0) != '-') {
11845                procs = new ArrayList<ProcessRecord>();
11846                int pid = -1;
11847                try {
11848                    pid = Integer.parseInt(args[start]);
11849                } catch (NumberFormatException e) {
11850                }
11851                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11852                    ProcessRecord proc = mLruProcesses.get(i);
11853                    if (proc.pid == pid) {
11854                        procs.add(proc);
11855                    } else if (proc.processName.equals(args[start])) {
11856                        procs.add(proc);
11857                    }
11858                }
11859                if (procs.size() <= 0) {
11860                    return null;
11861                }
11862            } else {
11863                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11864            }
11865        }
11866        return procs;
11867    }
11868
11869    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11870            PrintWriter pw, String[] args) {
11871        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11872        if (procs == null) {
11873            pw.println("No process found for: " + args[0]);
11874            return;
11875        }
11876
11877        long uptime = SystemClock.uptimeMillis();
11878        long realtime = SystemClock.elapsedRealtime();
11879        pw.println("Applications Graphics Acceleration Info:");
11880        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11881
11882        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11883            ProcessRecord r = procs.get(i);
11884            if (r.thread != null) {
11885                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11886                pw.flush();
11887                try {
11888                    TransferPipe tp = new TransferPipe();
11889                    try {
11890                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11891                        tp.go(fd);
11892                    } finally {
11893                        tp.kill();
11894                    }
11895                } catch (IOException e) {
11896                    pw.println("Failure while dumping the app: " + r);
11897                    pw.flush();
11898                } catch (RemoteException e) {
11899                    pw.println("Got a RemoteException while dumping the app " + r);
11900                    pw.flush();
11901                }
11902            }
11903        }
11904    }
11905
11906    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11907        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11908        if (procs == null) {
11909            pw.println("No process found for: " + args[0]);
11910            return;
11911        }
11912
11913        pw.println("Applications Database Info:");
11914
11915        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11916            ProcessRecord r = procs.get(i);
11917            if (r.thread != null) {
11918                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11919                pw.flush();
11920                try {
11921                    TransferPipe tp = new TransferPipe();
11922                    try {
11923                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11924                        tp.go(fd);
11925                    } finally {
11926                        tp.kill();
11927                    }
11928                } catch (IOException e) {
11929                    pw.println("Failure while dumping the app: " + r);
11930                    pw.flush();
11931                } catch (RemoteException e) {
11932                    pw.println("Got a RemoteException while dumping the app " + r);
11933                    pw.flush();
11934                }
11935            }
11936        }
11937    }
11938
11939    final static class MemItem {
11940        final boolean isProc;
11941        final String label;
11942        final String shortLabel;
11943        final long pss;
11944        final int id;
11945        final boolean hasActivities;
11946        ArrayList<MemItem> subitems;
11947
11948        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11949                boolean _hasActivities) {
11950            isProc = true;
11951            label = _label;
11952            shortLabel = _shortLabel;
11953            pss = _pss;
11954            id = _id;
11955            hasActivities = _hasActivities;
11956        }
11957
11958        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11959            isProc = false;
11960            label = _label;
11961            shortLabel = _shortLabel;
11962            pss = _pss;
11963            id = _id;
11964            hasActivities = false;
11965        }
11966    }
11967
11968    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11969            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11970        if (sort && !isCompact) {
11971            Collections.sort(items, new Comparator<MemItem>() {
11972                @Override
11973                public int compare(MemItem lhs, MemItem rhs) {
11974                    if (lhs.pss < rhs.pss) {
11975                        return 1;
11976                    } else if (lhs.pss > rhs.pss) {
11977                        return -1;
11978                    }
11979                    return 0;
11980                }
11981            });
11982        }
11983
11984        for (int i=0; i<items.size(); i++) {
11985            MemItem mi = items.get(i);
11986            if (!isCompact) {
11987                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11988            } else if (mi.isProc) {
11989                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11990                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11991                pw.println(mi.hasActivities ? ",a" : ",e");
11992            } else {
11993                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11994                pw.println(mi.pss);
11995            }
11996            if (mi.subitems != null) {
11997                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11998                        true, isCompact);
11999            }
12000        }
12001    }
12002
12003    // These are in KB.
12004    static final long[] DUMP_MEM_BUCKETS = new long[] {
12005        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12006        120*1024, 160*1024, 200*1024,
12007        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12008        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12009    };
12010
12011    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12012            boolean stackLike) {
12013        int start = label.lastIndexOf('.');
12014        if (start >= 0) start++;
12015        else start = 0;
12016        int end = label.length();
12017        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12018            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12019                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12020                out.append(bucket);
12021                out.append(stackLike ? "MB." : "MB ");
12022                out.append(label, start, end);
12023                return;
12024            }
12025        }
12026        out.append(memKB/1024);
12027        out.append(stackLike ? "MB." : "MB ");
12028        out.append(label, start, end);
12029    }
12030
12031    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12032            ProcessList.NATIVE_ADJ,
12033            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12034            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12035            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12036            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12037            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12038    };
12039    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12040            "Native",
12041            "System", "Persistent", "Foreground",
12042            "Visible", "Perceptible",
12043            "Heavy Weight", "Backup",
12044            "A Services", "Home",
12045            "Previous", "B Services", "Cached"
12046    };
12047    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12048            "native",
12049            "sys", "pers", "fore",
12050            "vis", "percept",
12051            "heavy", "backup",
12052            "servicea", "home",
12053            "prev", "serviceb", "cached"
12054    };
12055
12056    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12057            long realtime, boolean isCheckinRequest, boolean isCompact) {
12058        if (isCheckinRequest || isCompact) {
12059            // short checkin version
12060            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12061        } else {
12062            pw.println("Applications Memory Usage (kB):");
12063            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12064        }
12065    }
12066
12067    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12068            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12069        boolean dumpDetails = false;
12070        boolean dumpFullDetails = false;
12071        boolean dumpDalvik = false;
12072        boolean oomOnly = false;
12073        boolean isCompact = false;
12074        boolean localOnly = false;
12075
12076        int opti = 0;
12077        while (opti < args.length) {
12078            String opt = args[opti];
12079            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12080                break;
12081            }
12082            opti++;
12083            if ("-a".equals(opt)) {
12084                dumpDetails = true;
12085                dumpFullDetails = true;
12086                dumpDalvik = true;
12087            } else if ("-d".equals(opt)) {
12088                dumpDalvik = true;
12089            } else if ("-c".equals(opt)) {
12090                isCompact = true;
12091            } else if ("--oom".equals(opt)) {
12092                oomOnly = true;
12093            } else if ("--local".equals(opt)) {
12094                localOnly = true;
12095            } else if ("-h".equals(opt)) {
12096                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12097                pw.println("  -a: include all available information for each process.");
12098                pw.println("  -d: include dalvik details when dumping process details.");
12099                pw.println("  -c: dump in a compact machine-parseable representation.");
12100                pw.println("  --oom: only show processes organized by oom adj.");
12101                pw.println("  --local: only collect details locally, don't call process.");
12102                pw.println("If [process] is specified it can be the name or ");
12103                pw.println("pid of a specific process to dump.");
12104                return;
12105            } else {
12106                pw.println("Unknown argument: " + opt + "; use -h for help");
12107            }
12108        }
12109
12110        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12111        long uptime = SystemClock.uptimeMillis();
12112        long realtime = SystemClock.elapsedRealtime();
12113        final long[] tmpLong = new long[1];
12114
12115        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12116        if (procs == null) {
12117            // No Java processes.  Maybe they want to print a native process.
12118            if (args != null && args.length > opti
12119                    && args[opti].charAt(0) != '-') {
12120                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12121                        = new ArrayList<ProcessCpuTracker.Stats>();
12122                updateCpuStatsNow();
12123                int findPid = -1;
12124                try {
12125                    findPid = Integer.parseInt(args[opti]);
12126                } catch (NumberFormatException e) {
12127                }
12128                synchronized (mProcessCpuThread) {
12129                    final int N = mProcessCpuTracker.countStats();
12130                    for (int i=0; i<N; i++) {
12131                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12132                        if (st.pid == findPid || (st.baseName != null
12133                                && st.baseName.equals(args[opti]))) {
12134                            nativeProcs.add(st);
12135                        }
12136                    }
12137                }
12138                if (nativeProcs.size() > 0) {
12139                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12140                            isCompact);
12141                    Debug.MemoryInfo mi = null;
12142                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12143                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12144                        final int pid = r.pid;
12145                        if (!isCheckinRequest && dumpDetails) {
12146                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12147                        }
12148                        if (mi == null) {
12149                            mi = new Debug.MemoryInfo();
12150                        }
12151                        if (dumpDetails || (!brief && !oomOnly)) {
12152                            Debug.getMemoryInfo(pid, mi);
12153                        } else {
12154                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12155                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12156                        }
12157                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12158                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12159                        if (isCheckinRequest) {
12160                            pw.println();
12161                        }
12162                    }
12163                    return;
12164                }
12165            }
12166            pw.println("No process found for: " + args[opti]);
12167            return;
12168        }
12169
12170        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12171            dumpDetails = true;
12172        }
12173
12174        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12175
12176        String[] innerArgs = new String[args.length-opti];
12177        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12178
12179        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12180        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12181        long nativePss=0, dalvikPss=0, otherPss=0;
12182        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12183
12184        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12185        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12186                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12187
12188        long totalPss = 0;
12189        long cachedPss = 0;
12190
12191        Debug.MemoryInfo mi = null;
12192        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12193            final ProcessRecord r = procs.get(i);
12194            final IApplicationThread thread;
12195            final int pid;
12196            final int oomAdj;
12197            final boolean hasActivities;
12198            synchronized (this) {
12199                thread = r.thread;
12200                pid = r.pid;
12201                oomAdj = r.getSetAdjWithServices();
12202                hasActivities = r.activities.size() > 0;
12203            }
12204            if (thread != null) {
12205                if (!isCheckinRequest && dumpDetails) {
12206                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12207                }
12208                if (mi == null) {
12209                    mi = new Debug.MemoryInfo();
12210                }
12211                if (dumpDetails || (!brief && !oomOnly)) {
12212                    Debug.getMemoryInfo(pid, mi);
12213                } else {
12214                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12215                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12216                }
12217                if (dumpDetails) {
12218                    if (localOnly) {
12219                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12220                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12221                        if (isCheckinRequest) {
12222                            pw.println();
12223                        }
12224                    } else {
12225                        try {
12226                            pw.flush();
12227                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12228                                    dumpDalvik, innerArgs);
12229                        } catch (RemoteException e) {
12230                            if (!isCheckinRequest) {
12231                                pw.println("Got RemoteException!");
12232                                pw.flush();
12233                            }
12234                        }
12235                    }
12236                }
12237
12238                final long myTotalPss = mi.getTotalPss();
12239                final long myTotalUss = mi.getTotalUss();
12240
12241                synchronized (this) {
12242                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12243                        // Record this for posterity if the process has been stable.
12244                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12245                    }
12246                }
12247
12248                if (!isCheckinRequest && mi != null) {
12249                    totalPss += myTotalPss;
12250                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12251                            (hasActivities ? " / activities)" : ")"),
12252                            r.processName, myTotalPss, pid, hasActivities);
12253                    procMems.add(pssItem);
12254                    procMemsMap.put(pid, pssItem);
12255
12256                    nativePss += mi.nativePss;
12257                    dalvikPss += mi.dalvikPss;
12258                    otherPss += mi.otherPss;
12259                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12260                        long mem = mi.getOtherPss(j);
12261                        miscPss[j] += mem;
12262                        otherPss -= mem;
12263                    }
12264
12265                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12266                        cachedPss += myTotalPss;
12267                    }
12268
12269                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12270                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12271                                || oomIndex == (oomPss.length-1)) {
12272                            oomPss[oomIndex] += myTotalPss;
12273                            if (oomProcs[oomIndex] == null) {
12274                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12275                            }
12276                            oomProcs[oomIndex].add(pssItem);
12277                            break;
12278                        }
12279                    }
12280                }
12281            }
12282        }
12283
12284        if (!isCheckinRequest && procs.size() > 1) {
12285            // If we are showing aggregations, also look for native processes to
12286            // include so that our aggregations are more accurate.
12287            updateCpuStatsNow();
12288            synchronized (mProcessCpuThread) {
12289                final int N = mProcessCpuTracker.countStats();
12290                for (int i=0; i<N; i++) {
12291                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12292                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12293                        if (mi == null) {
12294                            mi = new Debug.MemoryInfo();
12295                        }
12296                        if (!brief && !oomOnly) {
12297                            Debug.getMemoryInfo(st.pid, mi);
12298                        } else {
12299                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12300                            mi.nativePrivateDirty = (int)tmpLong[0];
12301                        }
12302
12303                        final long myTotalPss = mi.getTotalPss();
12304                        totalPss += myTotalPss;
12305
12306                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12307                                st.name, myTotalPss, st.pid, false);
12308                        procMems.add(pssItem);
12309
12310                        nativePss += mi.nativePss;
12311                        dalvikPss += mi.dalvikPss;
12312                        otherPss += mi.otherPss;
12313                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12314                            long mem = mi.getOtherPss(j);
12315                            miscPss[j] += mem;
12316                            otherPss -= mem;
12317                        }
12318                        oomPss[0] += myTotalPss;
12319                        if (oomProcs[0] == null) {
12320                            oomProcs[0] = new ArrayList<MemItem>();
12321                        }
12322                        oomProcs[0].add(pssItem);
12323                    }
12324                }
12325            }
12326
12327            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12328
12329            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12330            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12331            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12332            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12333                String label = Debug.MemoryInfo.getOtherLabel(j);
12334                catMems.add(new MemItem(label, label, miscPss[j], j));
12335            }
12336
12337            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12338            for (int j=0; j<oomPss.length; j++) {
12339                if (oomPss[j] != 0) {
12340                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12341                            : DUMP_MEM_OOM_LABEL[j];
12342                    MemItem item = new MemItem(label, label, oomPss[j],
12343                            DUMP_MEM_OOM_ADJ[j]);
12344                    item.subitems = oomProcs[j];
12345                    oomMems.add(item);
12346                }
12347            }
12348
12349            if (!brief && !oomOnly && !isCompact) {
12350                pw.println();
12351                pw.println("Total PSS by process:");
12352                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12353                pw.println();
12354            }
12355            if (!isCompact) {
12356                pw.println("Total PSS by OOM adjustment:");
12357            }
12358            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12359            if (!brief && !oomOnly) {
12360                PrintWriter out = categoryPw != null ? categoryPw : pw;
12361                if (!isCompact) {
12362                    out.println();
12363                    out.println("Total PSS by category:");
12364                }
12365                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12366            }
12367            if (!isCompact) {
12368                pw.println();
12369            }
12370            MemInfoReader memInfo = new MemInfoReader();
12371            memInfo.readMemInfo();
12372            if (!brief) {
12373                if (!isCompact) {
12374                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12375                    pw.print(" kB (status ");
12376                    switch (mLastMemoryLevel) {
12377                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12378                            pw.println("normal)");
12379                            break;
12380                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12381                            pw.println("moderate)");
12382                            break;
12383                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12384                            pw.println("low)");
12385                            break;
12386                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12387                            pw.println("critical)");
12388                            break;
12389                        default:
12390                            pw.print(mLastMemoryLevel);
12391                            pw.println(")");
12392                            break;
12393                    }
12394                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12395                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12396                            pw.print(cachedPss); pw.print(" cached pss + ");
12397                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12398                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12399                } else {
12400                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12401                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12402                            + memInfo.getFreeSizeKb()); pw.print(",");
12403                    pw.println(totalPss - cachedPss);
12404                }
12405            }
12406            if (!isCompact) {
12407                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12408                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12409                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12410                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12411                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12412                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12413                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12414                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12415                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12416                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12417                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12418            }
12419            if (!brief) {
12420                if (memInfo.getZramTotalSizeKb() != 0) {
12421                    if (!isCompact) {
12422                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12423                                pw.print(" kB physical used for ");
12424                                pw.print(memInfo.getSwapTotalSizeKb()
12425                                        - memInfo.getSwapFreeSizeKb());
12426                                pw.print(" kB in swap (");
12427                                pw.print(memInfo.getSwapTotalSizeKb());
12428                                pw.println(" kB total swap)");
12429                    } else {
12430                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12431                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12432                                pw.println(memInfo.getSwapFreeSizeKb());
12433                    }
12434                }
12435                final int[] SINGLE_LONG_FORMAT = new int[] {
12436                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12437                };
12438                long[] longOut = new long[1];
12439                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12440                        SINGLE_LONG_FORMAT, null, longOut, null);
12441                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12442                longOut[0] = 0;
12443                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12444                        SINGLE_LONG_FORMAT, null, longOut, null);
12445                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12446                longOut[0] = 0;
12447                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12448                        SINGLE_LONG_FORMAT, null, longOut, null);
12449                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12450                longOut[0] = 0;
12451                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12452                        SINGLE_LONG_FORMAT, null, longOut, null);
12453                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12454                if (!isCompact) {
12455                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12456                        pw.print("      KSM: "); pw.print(sharing);
12457                                pw.print(" kB saved from shared ");
12458                                pw.print(shared); pw.println(" kB");
12459                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12460                                pw.print(voltile); pw.println(" kB volatile");
12461                    }
12462                    pw.print("   Tuning: ");
12463                    pw.print(ActivityManager.staticGetMemoryClass());
12464                    pw.print(" (large ");
12465                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12466                    pw.print("), oom ");
12467                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12468                    pw.print(" kB");
12469                    pw.print(", restore limit ");
12470                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12471                    pw.print(" kB");
12472                    if (ActivityManager.isLowRamDeviceStatic()) {
12473                        pw.print(" (low-ram)");
12474                    }
12475                    if (ActivityManager.isHighEndGfx()) {
12476                        pw.print(" (high-end-gfx)");
12477                    }
12478                    pw.println();
12479                } else {
12480                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12481                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12482                    pw.println(voltile);
12483                    pw.print("tuning,");
12484                    pw.print(ActivityManager.staticGetMemoryClass());
12485                    pw.print(',');
12486                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12487                    pw.print(',');
12488                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12489                    if (ActivityManager.isLowRamDeviceStatic()) {
12490                        pw.print(",low-ram");
12491                    }
12492                    if (ActivityManager.isHighEndGfx()) {
12493                        pw.print(",high-end-gfx");
12494                    }
12495                    pw.println();
12496                }
12497            }
12498        }
12499    }
12500
12501    /**
12502     * Searches array of arguments for the specified string
12503     * @param args array of argument strings
12504     * @param value value to search for
12505     * @return true if the value is contained in the array
12506     */
12507    private static boolean scanArgs(String[] args, String value) {
12508        if (args != null) {
12509            for (String arg : args) {
12510                if (value.equals(arg)) {
12511                    return true;
12512                }
12513            }
12514        }
12515        return false;
12516    }
12517
12518    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12519            ContentProviderRecord cpr, boolean always) {
12520        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12521
12522        if (!inLaunching || always) {
12523            synchronized (cpr) {
12524                cpr.launchingApp = null;
12525                cpr.notifyAll();
12526            }
12527            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12528            String names[] = cpr.info.authority.split(";");
12529            for (int j = 0; j < names.length; j++) {
12530                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12531            }
12532        }
12533
12534        for (int i=0; i<cpr.connections.size(); i++) {
12535            ContentProviderConnection conn = cpr.connections.get(i);
12536            if (conn.waiting) {
12537                // If this connection is waiting for the provider, then we don't
12538                // need to mess with its process unless we are always removing
12539                // or for some reason the provider is not currently launching.
12540                if (inLaunching && !always) {
12541                    continue;
12542                }
12543            }
12544            ProcessRecord capp = conn.client;
12545            conn.dead = true;
12546            if (conn.stableCount > 0) {
12547                if (!capp.persistent && capp.thread != null
12548                        && capp.pid != 0
12549                        && capp.pid != MY_PID) {
12550                    killUnneededProcessLocked(capp, "depends on provider "
12551                            + cpr.name.flattenToShortString()
12552                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12553                }
12554            } else if (capp.thread != null && conn.provider.provider != null) {
12555                try {
12556                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12557                } catch (RemoteException e) {
12558                }
12559                // In the protocol here, we don't expect the client to correctly
12560                // clean up this connection, we'll just remove it.
12561                cpr.connections.remove(i);
12562                conn.client.conProviders.remove(conn);
12563            }
12564        }
12565
12566        if (inLaunching && always) {
12567            mLaunchingProviders.remove(cpr);
12568        }
12569        return inLaunching;
12570    }
12571
12572    /**
12573     * Main code for cleaning up a process when it has gone away.  This is
12574     * called both as a result of the process dying, or directly when stopping
12575     * a process when running in single process mode.
12576     */
12577    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12578            boolean restarting, boolean allowRestart, int index) {
12579        if (index >= 0) {
12580            removeLruProcessLocked(app);
12581            ProcessList.remove(app.pid);
12582        }
12583
12584        mProcessesToGc.remove(app);
12585        mPendingPssProcesses.remove(app);
12586
12587        // Dismiss any open dialogs.
12588        if (app.crashDialog != null && !app.forceCrashReport) {
12589            app.crashDialog.dismiss();
12590            app.crashDialog = null;
12591        }
12592        if (app.anrDialog != null) {
12593            app.anrDialog.dismiss();
12594            app.anrDialog = null;
12595        }
12596        if (app.waitDialog != null) {
12597            app.waitDialog.dismiss();
12598            app.waitDialog = null;
12599        }
12600
12601        app.crashing = false;
12602        app.notResponding = false;
12603
12604        app.resetPackageList(mProcessStats);
12605        app.unlinkDeathRecipient();
12606        app.makeInactive(mProcessStats);
12607        app.forcingToForeground = null;
12608        updateProcessForegroundLocked(app, false, false);
12609        app.foregroundActivities = false;
12610        app.hasShownUi = false;
12611        app.treatLikeActivity = false;
12612        app.hasAboveClient = false;
12613        app.hasClientActivities = false;
12614
12615        mServices.killServicesLocked(app, allowRestart);
12616
12617        boolean restart = false;
12618
12619        // Remove published content providers.
12620        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12621            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12622            final boolean always = app.bad || !allowRestart;
12623            if (removeDyingProviderLocked(app, cpr, always) || always) {
12624                // We left the provider in the launching list, need to
12625                // restart it.
12626                restart = true;
12627            }
12628
12629            cpr.provider = null;
12630            cpr.proc = null;
12631        }
12632        app.pubProviders.clear();
12633
12634        // Take care of any launching providers waiting for this process.
12635        if (checkAppInLaunchingProvidersLocked(app, false)) {
12636            restart = true;
12637        }
12638
12639        // Unregister from connected content providers.
12640        if (!app.conProviders.isEmpty()) {
12641            for (int i=0; i<app.conProviders.size(); i++) {
12642                ContentProviderConnection conn = app.conProviders.get(i);
12643                conn.provider.connections.remove(conn);
12644            }
12645            app.conProviders.clear();
12646        }
12647
12648        // At this point there may be remaining entries in mLaunchingProviders
12649        // where we were the only one waiting, so they are no longer of use.
12650        // Look for these and clean up if found.
12651        // XXX Commented out for now.  Trying to figure out a way to reproduce
12652        // the actual situation to identify what is actually going on.
12653        if (false) {
12654            for (int i=0; i<mLaunchingProviders.size(); i++) {
12655                ContentProviderRecord cpr = (ContentProviderRecord)
12656                        mLaunchingProviders.get(i);
12657                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12658                    synchronized (cpr) {
12659                        cpr.launchingApp = null;
12660                        cpr.notifyAll();
12661                    }
12662                }
12663            }
12664        }
12665
12666        skipCurrentReceiverLocked(app);
12667
12668        // Unregister any receivers.
12669        for (int i=app.receivers.size()-1; i>=0; i--) {
12670            removeReceiverLocked(app.receivers.valueAt(i));
12671        }
12672        app.receivers.clear();
12673
12674        // If the app is undergoing backup, tell the backup manager about it
12675        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12676            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12677                    + mBackupTarget.appInfo + " died during backup");
12678            try {
12679                IBackupManager bm = IBackupManager.Stub.asInterface(
12680                        ServiceManager.getService(Context.BACKUP_SERVICE));
12681                bm.agentDisconnected(app.info.packageName);
12682            } catch (RemoteException e) {
12683                // can't happen; backup manager is local
12684            }
12685        }
12686
12687        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12688            ProcessChangeItem item = mPendingProcessChanges.get(i);
12689            if (item.pid == app.pid) {
12690                mPendingProcessChanges.remove(i);
12691                mAvailProcessChanges.add(item);
12692            }
12693        }
12694        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12695
12696        // If the caller is restarting this app, then leave it in its
12697        // current lists and let the caller take care of it.
12698        if (restarting) {
12699            return;
12700        }
12701
12702        if (!app.persistent || app.isolated) {
12703            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12704                    "Removing non-persistent process during cleanup: " + app);
12705            mProcessNames.remove(app.processName, app.uid);
12706            mIsolatedProcesses.remove(app.uid);
12707            if (mHeavyWeightProcess == app) {
12708                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12709                        mHeavyWeightProcess.userId, 0));
12710                mHeavyWeightProcess = null;
12711            }
12712        } else if (!app.removed) {
12713            // This app is persistent, so we need to keep its record around.
12714            // If it is not already on the pending app list, add it there
12715            // and start a new process for it.
12716            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12717                mPersistentStartingProcesses.add(app);
12718                restart = true;
12719            }
12720        }
12721        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12722                "Clean-up removing on hold: " + app);
12723        mProcessesOnHold.remove(app);
12724
12725        if (app == mHomeProcess) {
12726            mHomeProcess = null;
12727        }
12728        if (app == mPreviousProcess) {
12729            mPreviousProcess = null;
12730        }
12731
12732        if (restart && !app.isolated) {
12733            // We have components that still need to be running in the
12734            // process, so re-launch it.
12735            mProcessNames.put(app.processName, app.uid, app);
12736            startProcessLocked(app, "restart", app.processName);
12737        } else if (app.pid > 0 && app.pid != MY_PID) {
12738            // Goodbye!
12739            boolean removed;
12740            synchronized (mPidsSelfLocked) {
12741                mPidsSelfLocked.remove(app.pid);
12742                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12743            }
12744            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12745                    app.processName, app.info.uid);
12746            if (app.isolated) {
12747                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12748            }
12749            app.setPid(0);
12750        }
12751    }
12752
12753    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12754        // Look through the content providers we are waiting to have launched,
12755        // and if any run in this process then either schedule a restart of
12756        // the process or kill the client waiting for it if this process has
12757        // gone bad.
12758        int NL = mLaunchingProviders.size();
12759        boolean restart = false;
12760        for (int i=0; i<NL; i++) {
12761            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12762            if (cpr.launchingApp == app) {
12763                if (!alwaysBad && !app.bad) {
12764                    restart = true;
12765                } else {
12766                    removeDyingProviderLocked(app, cpr, true);
12767                    // cpr should have been removed from mLaunchingProviders
12768                    NL = mLaunchingProviders.size();
12769                    i--;
12770                }
12771            }
12772        }
12773        return restart;
12774    }
12775
12776    // =========================================================
12777    // SERVICES
12778    // =========================================================
12779
12780    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12781            int flags) {
12782        enforceNotIsolatedCaller("getServices");
12783        synchronized (this) {
12784            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12785        }
12786    }
12787
12788    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12789        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12790        synchronized (this) {
12791            return mServices.getRunningServiceControlPanelLocked(name);
12792        }
12793    }
12794
12795    public ComponentName startService(IApplicationThread caller, Intent service,
12796            String resolvedType, int userId) {
12797        enforceNotIsolatedCaller("startService");
12798        // Refuse possible leaked file descriptors
12799        if (service != null && service.hasFileDescriptors() == true) {
12800            throw new IllegalArgumentException("File descriptors passed in Intent");
12801        }
12802
12803        if (DEBUG_SERVICE)
12804            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12805        synchronized(this) {
12806            final int callingPid = Binder.getCallingPid();
12807            final int callingUid = Binder.getCallingUid();
12808            final long origId = Binder.clearCallingIdentity();
12809            ComponentName res = mServices.startServiceLocked(caller, service,
12810                    resolvedType, callingPid, callingUid, userId);
12811            Binder.restoreCallingIdentity(origId);
12812            return res;
12813        }
12814    }
12815
12816    ComponentName startServiceInPackage(int uid,
12817            Intent service, String resolvedType, int userId) {
12818        synchronized(this) {
12819            if (DEBUG_SERVICE)
12820                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12821            final long origId = Binder.clearCallingIdentity();
12822            ComponentName res = mServices.startServiceLocked(null, service,
12823                    resolvedType, -1, uid, userId);
12824            Binder.restoreCallingIdentity(origId);
12825            return res;
12826        }
12827    }
12828
12829    public int stopService(IApplicationThread caller, Intent service,
12830            String resolvedType, int userId) {
12831        enforceNotIsolatedCaller("stopService");
12832        // Refuse possible leaked file descriptors
12833        if (service != null && service.hasFileDescriptors() == true) {
12834            throw new IllegalArgumentException("File descriptors passed in Intent");
12835        }
12836
12837        synchronized(this) {
12838            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12839        }
12840    }
12841
12842    public IBinder peekService(Intent service, String resolvedType) {
12843        enforceNotIsolatedCaller("peekService");
12844        // Refuse possible leaked file descriptors
12845        if (service != null && service.hasFileDescriptors() == true) {
12846            throw new IllegalArgumentException("File descriptors passed in Intent");
12847        }
12848        synchronized(this) {
12849            return mServices.peekServiceLocked(service, resolvedType);
12850        }
12851    }
12852
12853    public boolean stopServiceToken(ComponentName className, IBinder token,
12854            int startId) {
12855        synchronized(this) {
12856            return mServices.stopServiceTokenLocked(className, token, startId);
12857        }
12858    }
12859
12860    public void setServiceForeground(ComponentName className, IBinder token,
12861            int id, Notification notification, boolean removeNotification) {
12862        synchronized(this) {
12863            mServices.setServiceForegroundLocked(className, token, id, notification,
12864                    removeNotification);
12865        }
12866    }
12867
12868    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12869            boolean requireFull, String name, String callerPackage) {
12870        final int callingUserId = UserHandle.getUserId(callingUid);
12871        if (callingUserId != userId) {
12872            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12873                if ((requireFull || checkComponentPermission(
12874                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12875                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12876                        && checkComponentPermission(
12877                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12878                                callingPid, callingUid, -1, true)
12879                                != PackageManager.PERMISSION_GRANTED) {
12880                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12881                        // In this case, they would like to just execute as their
12882                        // owner user instead of failing.
12883                        userId = callingUserId;
12884                    } else {
12885                        StringBuilder builder = new StringBuilder(128);
12886                        builder.append("Permission Denial: ");
12887                        builder.append(name);
12888                        if (callerPackage != null) {
12889                            builder.append(" from ");
12890                            builder.append(callerPackage);
12891                        }
12892                        builder.append(" asks to run as user ");
12893                        builder.append(userId);
12894                        builder.append(" but is calling from user ");
12895                        builder.append(UserHandle.getUserId(callingUid));
12896                        builder.append("; this requires ");
12897                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12898                        if (!requireFull) {
12899                            builder.append(" or ");
12900                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12901                        }
12902                        String msg = builder.toString();
12903                        Slog.w(TAG, msg);
12904                        throw new SecurityException(msg);
12905                    }
12906                }
12907            }
12908            if (userId == UserHandle.USER_CURRENT
12909                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12910                // Note that we may be accessing this outside of a lock...
12911                // shouldn't be a big deal, if this is being called outside
12912                // of a locked context there is intrinsically a race with
12913                // the value the caller will receive and someone else changing it.
12914                userId = mCurrentUserId;
12915            }
12916            if (!allowAll && userId < 0) {
12917                throw new IllegalArgumentException(
12918                        "Call does not support special user #" + userId);
12919            }
12920        }
12921        return userId;
12922    }
12923
12924    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12925            String className, int flags) {
12926        boolean result = false;
12927        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12928            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12929                if (ActivityManager.checkUidPermission(
12930                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12931                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12932                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12933                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12934                            + " requests FLAG_SINGLE_USER, but app does not hold "
12935                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12936                    Slog.w(TAG, msg);
12937                    throw new SecurityException(msg);
12938                }
12939                result = true;
12940            }
12941        } else if (componentProcessName == aInfo.packageName) {
12942            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12943        } else if ("system".equals(componentProcessName)) {
12944            result = true;
12945        }
12946        if (DEBUG_MU) {
12947            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12948                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12949        }
12950        return result;
12951    }
12952
12953    public int bindService(IApplicationThread caller, IBinder token,
12954            Intent service, String resolvedType,
12955            IServiceConnection connection, int flags, int userId) {
12956        enforceNotIsolatedCaller("bindService");
12957        // Refuse possible leaked file descriptors
12958        if (service != null && service.hasFileDescriptors() == true) {
12959            throw new IllegalArgumentException("File descriptors passed in Intent");
12960        }
12961
12962        synchronized(this) {
12963            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12964                    connection, flags, userId);
12965        }
12966    }
12967
12968    public boolean unbindService(IServiceConnection connection) {
12969        synchronized (this) {
12970            return mServices.unbindServiceLocked(connection);
12971        }
12972    }
12973
12974    public void publishService(IBinder token, Intent intent, IBinder service) {
12975        // Refuse possible leaked file descriptors
12976        if (intent != null && intent.hasFileDescriptors() == true) {
12977            throw new IllegalArgumentException("File descriptors passed in Intent");
12978        }
12979
12980        synchronized(this) {
12981            if (!(token instanceof ServiceRecord)) {
12982                throw new IllegalArgumentException("Invalid service token");
12983            }
12984            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12985        }
12986    }
12987
12988    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12989        // Refuse possible leaked file descriptors
12990        if (intent != null && intent.hasFileDescriptors() == true) {
12991            throw new IllegalArgumentException("File descriptors passed in Intent");
12992        }
12993
12994        synchronized(this) {
12995            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12996        }
12997    }
12998
12999    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13000        synchronized(this) {
13001            if (!(token instanceof ServiceRecord)) {
13002                throw new IllegalArgumentException("Invalid service token");
13003            }
13004            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13005        }
13006    }
13007
13008    // =========================================================
13009    // BACKUP AND RESTORE
13010    // =========================================================
13011
13012    // Cause the target app to be launched if necessary and its backup agent
13013    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13014    // activity manager to announce its creation.
13015    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13016        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13017        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13018
13019        synchronized(this) {
13020            // !!! TODO: currently no check here that we're already bound
13021            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13022            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13023            synchronized (stats) {
13024                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13025            }
13026
13027            // Backup agent is now in use, its package can't be stopped.
13028            try {
13029                AppGlobals.getPackageManager().setPackageStoppedState(
13030                        app.packageName, false, UserHandle.getUserId(app.uid));
13031            } catch (RemoteException e) {
13032            } catch (IllegalArgumentException e) {
13033                Slog.w(TAG, "Failed trying to unstop package "
13034                        + app.packageName + ": " + e);
13035            }
13036
13037            BackupRecord r = new BackupRecord(ss, app, backupMode);
13038            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13039                    ? new ComponentName(app.packageName, app.backupAgentName)
13040                    : new ComponentName("android", "FullBackupAgent");
13041            // startProcessLocked() returns existing proc's record if it's already running
13042            ProcessRecord proc = startProcessLocked(app.processName, app,
13043                    false, 0, "backup", hostingName, false, false, false);
13044            if (proc == null) {
13045                Slog.e(TAG, "Unable to start backup agent process " + r);
13046                return false;
13047            }
13048
13049            r.app = proc;
13050            mBackupTarget = r;
13051            mBackupAppName = app.packageName;
13052
13053            // Try not to kill the process during backup
13054            updateOomAdjLocked(proc);
13055
13056            // If the process is already attached, schedule the creation of the backup agent now.
13057            // If it is not yet live, this will be done when it attaches to the framework.
13058            if (proc.thread != null) {
13059                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13060                try {
13061                    proc.thread.scheduleCreateBackupAgent(app,
13062                            compatibilityInfoForPackageLocked(app), backupMode);
13063                } catch (RemoteException e) {
13064                    // Will time out on the backup manager side
13065                }
13066            } else {
13067                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13068            }
13069            // Invariants: at this point, the target app process exists and the application
13070            // is either already running or in the process of coming up.  mBackupTarget and
13071            // mBackupAppName describe the app, so that when it binds back to the AM we
13072            // know that it's scheduled for a backup-agent operation.
13073        }
13074
13075        return true;
13076    }
13077
13078    @Override
13079    public void clearPendingBackup() {
13080        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13081        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13082
13083        synchronized (this) {
13084            mBackupTarget = null;
13085            mBackupAppName = null;
13086        }
13087    }
13088
13089    // A backup agent has just come up
13090    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13091        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13092                + " = " + agent);
13093
13094        synchronized(this) {
13095            if (!agentPackageName.equals(mBackupAppName)) {
13096                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13097                return;
13098            }
13099        }
13100
13101        long oldIdent = Binder.clearCallingIdentity();
13102        try {
13103            IBackupManager bm = IBackupManager.Stub.asInterface(
13104                    ServiceManager.getService(Context.BACKUP_SERVICE));
13105            bm.agentConnected(agentPackageName, agent);
13106        } catch (RemoteException e) {
13107            // can't happen; the backup manager service is local
13108        } catch (Exception e) {
13109            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13110            e.printStackTrace();
13111        } finally {
13112            Binder.restoreCallingIdentity(oldIdent);
13113        }
13114    }
13115
13116    // done with this agent
13117    public void unbindBackupAgent(ApplicationInfo appInfo) {
13118        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13119        if (appInfo == null) {
13120            Slog.w(TAG, "unbind backup agent for null app");
13121            return;
13122        }
13123
13124        synchronized(this) {
13125            try {
13126                if (mBackupAppName == null) {
13127                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13128                    return;
13129                }
13130
13131                if (!mBackupAppName.equals(appInfo.packageName)) {
13132                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13133                    return;
13134                }
13135
13136                // Not backing this app up any more; reset its OOM adjustment
13137                final ProcessRecord proc = mBackupTarget.app;
13138                updateOomAdjLocked(proc);
13139
13140                // If the app crashed during backup, 'thread' will be null here
13141                if (proc.thread != null) {
13142                    try {
13143                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13144                                compatibilityInfoForPackageLocked(appInfo));
13145                    } catch (Exception e) {
13146                        Slog.e(TAG, "Exception when unbinding backup agent:");
13147                        e.printStackTrace();
13148                    }
13149                }
13150            } finally {
13151                mBackupTarget = null;
13152                mBackupAppName = null;
13153            }
13154        }
13155    }
13156    // =========================================================
13157    // BROADCASTS
13158    // =========================================================
13159
13160    private final List getStickiesLocked(String action, IntentFilter filter,
13161            List cur, int userId) {
13162        final ContentResolver resolver = mContext.getContentResolver();
13163        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13164        if (stickies == null) {
13165            return cur;
13166        }
13167        final ArrayList<Intent> list = stickies.get(action);
13168        if (list == null) {
13169            return cur;
13170        }
13171        int N = list.size();
13172        for (int i=0; i<N; i++) {
13173            Intent intent = list.get(i);
13174            if (filter.match(resolver, intent, true, TAG) >= 0) {
13175                if (cur == null) {
13176                    cur = new ArrayList<Intent>();
13177                }
13178                cur.add(intent);
13179            }
13180        }
13181        return cur;
13182    }
13183
13184    boolean isPendingBroadcastProcessLocked(int pid) {
13185        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13186                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13187    }
13188
13189    void skipPendingBroadcastLocked(int pid) {
13190            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13191            for (BroadcastQueue queue : mBroadcastQueues) {
13192                queue.skipPendingBroadcastLocked(pid);
13193            }
13194    }
13195
13196    // The app just attached; send any pending broadcasts that it should receive
13197    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13198        boolean didSomething = false;
13199        for (BroadcastQueue queue : mBroadcastQueues) {
13200            didSomething |= queue.sendPendingBroadcastsLocked(app);
13201        }
13202        return didSomething;
13203    }
13204
13205    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13206            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13207        enforceNotIsolatedCaller("registerReceiver");
13208        int callingUid;
13209        int callingPid;
13210        synchronized(this) {
13211            ProcessRecord callerApp = null;
13212            if (caller != null) {
13213                callerApp = getRecordForAppLocked(caller);
13214                if (callerApp == null) {
13215                    throw new SecurityException(
13216                            "Unable to find app for caller " + caller
13217                            + " (pid=" + Binder.getCallingPid()
13218                            + ") when registering receiver " + receiver);
13219                }
13220                if (callerApp.info.uid != Process.SYSTEM_UID &&
13221                        !callerApp.pkgList.containsKey(callerPackage) &&
13222                        !"android".equals(callerPackage)) {
13223                    throw new SecurityException("Given caller package " + callerPackage
13224                            + " is not running in process " + callerApp);
13225                }
13226                callingUid = callerApp.info.uid;
13227                callingPid = callerApp.pid;
13228            } else {
13229                callerPackage = null;
13230                callingUid = Binder.getCallingUid();
13231                callingPid = Binder.getCallingPid();
13232            }
13233
13234            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13235                    true, true, "registerReceiver", callerPackage);
13236
13237            List allSticky = null;
13238
13239            // Look for any matching sticky broadcasts...
13240            Iterator actions = filter.actionsIterator();
13241            if (actions != null) {
13242                while (actions.hasNext()) {
13243                    String action = (String)actions.next();
13244                    allSticky = getStickiesLocked(action, filter, allSticky,
13245                            UserHandle.USER_ALL);
13246                    allSticky = getStickiesLocked(action, filter, allSticky,
13247                            UserHandle.getUserId(callingUid));
13248                }
13249            } else {
13250                allSticky = getStickiesLocked(null, filter, allSticky,
13251                        UserHandle.USER_ALL);
13252                allSticky = getStickiesLocked(null, filter, allSticky,
13253                        UserHandle.getUserId(callingUid));
13254            }
13255
13256            // The first sticky in the list is returned directly back to
13257            // the client.
13258            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13259
13260            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13261                    + ": " + sticky);
13262
13263            if (receiver == null) {
13264                return sticky;
13265            }
13266
13267            ReceiverList rl
13268                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13269            if (rl == null) {
13270                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13271                        userId, receiver);
13272                if (rl.app != null) {
13273                    rl.app.receivers.add(rl);
13274                } else {
13275                    try {
13276                        receiver.asBinder().linkToDeath(rl, 0);
13277                    } catch (RemoteException e) {
13278                        return sticky;
13279                    }
13280                    rl.linkedToDeath = true;
13281                }
13282                mRegisteredReceivers.put(receiver.asBinder(), rl);
13283            } else if (rl.uid != callingUid) {
13284                throw new IllegalArgumentException(
13285                        "Receiver requested to register for uid " + callingUid
13286                        + " was previously registered for uid " + rl.uid);
13287            } else if (rl.pid != callingPid) {
13288                throw new IllegalArgumentException(
13289                        "Receiver requested to register for pid " + callingPid
13290                        + " was previously registered for pid " + rl.pid);
13291            } else if (rl.userId != userId) {
13292                throw new IllegalArgumentException(
13293                        "Receiver requested to register for user " + userId
13294                        + " was previously registered for user " + rl.userId);
13295            }
13296            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13297                    permission, callingUid, userId);
13298            rl.add(bf);
13299            if (!bf.debugCheck()) {
13300                Slog.w(TAG, "==> For Dynamic broadast");
13301            }
13302            mReceiverResolver.addFilter(bf);
13303
13304            // Enqueue broadcasts for all existing stickies that match
13305            // this filter.
13306            if (allSticky != null) {
13307                ArrayList receivers = new ArrayList();
13308                receivers.add(bf);
13309
13310                int N = allSticky.size();
13311                for (int i=0; i<N; i++) {
13312                    Intent intent = (Intent)allSticky.get(i);
13313                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13314                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13315                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13316                            null, null, false, true, true, -1);
13317                    queue.enqueueParallelBroadcastLocked(r);
13318                    queue.scheduleBroadcastsLocked();
13319                }
13320            }
13321
13322            return sticky;
13323        }
13324    }
13325
13326    public void unregisterReceiver(IIntentReceiver receiver) {
13327        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13328
13329        final long origId = Binder.clearCallingIdentity();
13330        try {
13331            boolean doTrim = false;
13332
13333            synchronized(this) {
13334                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13335                if (rl != null) {
13336                    if (rl.curBroadcast != null) {
13337                        BroadcastRecord r = rl.curBroadcast;
13338                        final boolean doNext = finishReceiverLocked(
13339                                receiver.asBinder(), r.resultCode, r.resultData,
13340                                r.resultExtras, r.resultAbort);
13341                        if (doNext) {
13342                            doTrim = true;
13343                            r.queue.processNextBroadcast(false);
13344                        }
13345                    }
13346
13347                    if (rl.app != null) {
13348                        rl.app.receivers.remove(rl);
13349                    }
13350                    removeReceiverLocked(rl);
13351                    if (rl.linkedToDeath) {
13352                        rl.linkedToDeath = false;
13353                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13354                    }
13355                }
13356            }
13357
13358            // If we actually concluded any broadcasts, we might now be able
13359            // to trim the recipients' apps from our working set
13360            if (doTrim) {
13361                trimApplications();
13362                return;
13363            }
13364
13365        } finally {
13366            Binder.restoreCallingIdentity(origId);
13367        }
13368    }
13369
13370    void removeReceiverLocked(ReceiverList rl) {
13371        mRegisteredReceivers.remove(rl.receiver.asBinder());
13372        int N = rl.size();
13373        for (int i=0; i<N; i++) {
13374            mReceiverResolver.removeFilter(rl.get(i));
13375        }
13376    }
13377
13378    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13379        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13380            ProcessRecord r = mLruProcesses.get(i);
13381            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13382                try {
13383                    r.thread.dispatchPackageBroadcast(cmd, packages);
13384                } catch (RemoteException ex) {
13385                }
13386            }
13387        }
13388    }
13389
13390    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13391            int[] users) {
13392        List<ResolveInfo> receivers = null;
13393        try {
13394            HashSet<ComponentName> singleUserReceivers = null;
13395            boolean scannedFirstReceivers = false;
13396            for (int user : users) {
13397                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13398                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13399                if (user != 0 && newReceivers != null) {
13400                    // If this is not the primary user, we need to check for
13401                    // any receivers that should be filtered out.
13402                    for (int i=0; i<newReceivers.size(); i++) {
13403                        ResolveInfo ri = newReceivers.get(i);
13404                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13405                            newReceivers.remove(i);
13406                            i--;
13407                        }
13408                    }
13409                }
13410                if (newReceivers != null && newReceivers.size() == 0) {
13411                    newReceivers = null;
13412                }
13413                if (receivers == null) {
13414                    receivers = newReceivers;
13415                } else if (newReceivers != null) {
13416                    // We need to concatenate the additional receivers
13417                    // found with what we have do far.  This would be easy,
13418                    // but we also need to de-dup any receivers that are
13419                    // singleUser.
13420                    if (!scannedFirstReceivers) {
13421                        // Collect any single user receivers we had already retrieved.
13422                        scannedFirstReceivers = true;
13423                        for (int i=0; i<receivers.size(); i++) {
13424                            ResolveInfo ri = receivers.get(i);
13425                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13426                                ComponentName cn = new ComponentName(
13427                                        ri.activityInfo.packageName, ri.activityInfo.name);
13428                                if (singleUserReceivers == null) {
13429                                    singleUserReceivers = new HashSet<ComponentName>();
13430                                }
13431                                singleUserReceivers.add(cn);
13432                            }
13433                        }
13434                    }
13435                    // Add the new results to the existing results, tracking
13436                    // and de-dupping single user receivers.
13437                    for (int i=0; i<newReceivers.size(); i++) {
13438                        ResolveInfo ri = newReceivers.get(i);
13439                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13440                            ComponentName cn = new ComponentName(
13441                                    ri.activityInfo.packageName, ri.activityInfo.name);
13442                            if (singleUserReceivers == null) {
13443                                singleUserReceivers = new HashSet<ComponentName>();
13444                            }
13445                            if (!singleUserReceivers.contains(cn)) {
13446                                singleUserReceivers.add(cn);
13447                                receivers.add(ri);
13448                            }
13449                        } else {
13450                            receivers.add(ri);
13451                        }
13452                    }
13453                }
13454            }
13455        } catch (RemoteException ex) {
13456            // pm is in same process, this will never happen.
13457        }
13458        return receivers;
13459    }
13460
13461    private final int broadcastIntentLocked(ProcessRecord callerApp,
13462            String callerPackage, Intent intent, String resolvedType,
13463            IIntentReceiver resultTo, int resultCode, String resultData,
13464            Bundle map, String requiredPermission, int appOp,
13465            boolean ordered, boolean sticky, int callingPid, int callingUid,
13466            int userId) {
13467        intent = new Intent(intent);
13468
13469        // By default broadcasts do not go to stopped apps.
13470        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13471
13472        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13473            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13474            + " ordered=" + ordered + " userid=" + userId);
13475        if ((resultTo != null) && !ordered) {
13476            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13477        }
13478
13479        userId = handleIncomingUser(callingPid, callingUid, userId,
13480                true, false, "broadcast", callerPackage);
13481
13482        // Make sure that the user who is receiving this broadcast is started.
13483        // If not, we will just skip it.
13484        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13485            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13486                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13487                Slog.w(TAG, "Skipping broadcast of " + intent
13488                        + ": user " + userId + " is stopped");
13489                return ActivityManager.BROADCAST_SUCCESS;
13490            }
13491        }
13492
13493        /*
13494         * Prevent non-system code (defined here to be non-persistent
13495         * processes) from sending protected broadcasts.
13496         */
13497        int callingAppId = UserHandle.getAppId(callingUid);
13498        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13499            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13500            callingUid == 0) {
13501            // Always okay.
13502        } else if (callerApp == null || !callerApp.persistent) {
13503            try {
13504                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13505                        intent.getAction())) {
13506                    String msg = "Permission Denial: not allowed to send broadcast "
13507                            + intent.getAction() + " from pid="
13508                            + callingPid + ", uid=" + callingUid;
13509                    Slog.w(TAG, msg);
13510                    throw new SecurityException(msg);
13511                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13512                    // Special case for compatibility: we don't want apps to send this,
13513                    // but historically it has not been protected and apps may be using it
13514                    // to poke their own app widget.  So, instead of making it protected,
13515                    // just limit it to the caller.
13516                    if (callerApp == null) {
13517                        String msg = "Permission Denial: not allowed to send broadcast "
13518                                + intent.getAction() + " from unknown caller.";
13519                        Slog.w(TAG, msg);
13520                        throw new SecurityException(msg);
13521                    } else if (intent.getComponent() != null) {
13522                        // They are good enough to send to an explicit component...  verify
13523                        // it is being sent to the calling app.
13524                        if (!intent.getComponent().getPackageName().equals(
13525                                callerApp.info.packageName)) {
13526                            String msg = "Permission Denial: not allowed to send broadcast "
13527                                    + intent.getAction() + " to "
13528                                    + intent.getComponent().getPackageName() + " from "
13529                                    + callerApp.info.packageName;
13530                            Slog.w(TAG, msg);
13531                            throw new SecurityException(msg);
13532                        }
13533                    } else {
13534                        // Limit broadcast to their own package.
13535                        intent.setPackage(callerApp.info.packageName);
13536                    }
13537                }
13538            } catch (RemoteException e) {
13539                Slog.w(TAG, "Remote exception", e);
13540                return ActivityManager.BROADCAST_SUCCESS;
13541            }
13542        }
13543
13544        // Handle special intents: if this broadcast is from the package
13545        // manager about a package being removed, we need to remove all of
13546        // its activities from the history stack.
13547        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13548                intent.getAction());
13549        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13550                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13551                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13552                || uidRemoved) {
13553            if (checkComponentPermission(
13554                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13555                    callingPid, callingUid, -1, true)
13556                    == PackageManager.PERMISSION_GRANTED) {
13557                if (uidRemoved) {
13558                    final Bundle intentExtras = intent.getExtras();
13559                    final int uid = intentExtras != null
13560                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13561                    if (uid >= 0) {
13562                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13563                        synchronized (bs) {
13564                            bs.removeUidStatsLocked(uid);
13565                        }
13566                        mAppOpsService.uidRemoved(uid);
13567                    }
13568                } else {
13569                    // If resources are unavailable just force stop all
13570                    // those packages and flush the attribute cache as well.
13571                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13572                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13573                        if (list != null && (list.length > 0)) {
13574                            for (String pkg : list) {
13575                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13576                                        "storage unmount");
13577                            }
13578                            sendPackageBroadcastLocked(
13579                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13580                        }
13581                    } else {
13582                        Uri data = intent.getData();
13583                        String ssp;
13584                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13585                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13586                                    intent.getAction());
13587                            boolean fullUninstall = removed &&
13588                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13589                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13590                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13591                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13592                                        false, fullUninstall, userId,
13593                                        removed ? "pkg removed" : "pkg changed");
13594                            }
13595                            if (removed) {
13596                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13597                                        new String[] {ssp}, userId);
13598                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13599                                    mAppOpsService.packageRemoved(
13600                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13601
13602                                    // Remove all permissions granted from/to this package
13603                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13604                                }
13605                            }
13606                        }
13607                    }
13608                }
13609            } else {
13610                String msg = "Permission Denial: " + intent.getAction()
13611                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13612                        + ", uid=" + callingUid + ")"
13613                        + " requires "
13614                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13615                Slog.w(TAG, msg);
13616                throw new SecurityException(msg);
13617            }
13618
13619        // Special case for adding a package: by default turn on compatibility
13620        // mode.
13621        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13622            Uri data = intent.getData();
13623            String ssp;
13624            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13625                mCompatModePackages.handlePackageAddedLocked(ssp,
13626                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13627            }
13628        }
13629
13630        /*
13631         * If this is the time zone changed action, queue up a message that will reset the timezone
13632         * of all currently running processes. This message will get queued up before the broadcast
13633         * happens.
13634         */
13635        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13636            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13637        }
13638
13639        /*
13640         * If the user set the time, let all running processes know.
13641         */
13642        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13643            final int is24Hour = intent.getBooleanExtra(
13644                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13645            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13646        }
13647
13648        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13649            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13650        }
13651
13652        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13653            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13654            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13655        }
13656
13657        // Add to the sticky list if requested.
13658        if (sticky) {
13659            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13660                    callingPid, callingUid)
13661                    != PackageManager.PERMISSION_GRANTED) {
13662                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13663                        + callingPid + ", uid=" + callingUid
13664                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13665                Slog.w(TAG, msg);
13666                throw new SecurityException(msg);
13667            }
13668            if (requiredPermission != null) {
13669                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13670                        + " and enforce permission " + requiredPermission);
13671                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13672            }
13673            if (intent.getComponent() != null) {
13674                throw new SecurityException(
13675                        "Sticky broadcasts can't target a specific component");
13676            }
13677            // We use userId directly here, since the "all" target is maintained
13678            // as a separate set of sticky broadcasts.
13679            if (userId != UserHandle.USER_ALL) {
13680                // But first, if this is not a broadcast to all users, then
13681                // make sure it doesn't conflict with an existing broadcast to
13682                // all users.
13683                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13684                        UserHandle.USER_ALL);
13685                if (stickies != null) {
13686                    ArrayList<Intent> list = stickies.get(intent.getAction());
13687                    if (list != null) {
13688                        int N = list.size();
13689                        int i;
13690                        for (i=0; i<N; i++) {
13691                            if (intent.filterEquals(list.get(i))) {
13692                                throw new IllegalArgumentException(
13693                                        "Sticky broadcast " + intent + " for user "
13694                                        + userId + " conflicts with existing global broadcast");
13695                            }
13696                        }
13697                    }
13698                }
13699            }
13700            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13701            if (stickies == null) {
13702                stickies = new ArrayMap<String, ArrayList<Intent>>();
13703                mStickyBroadcasts.put(userId, stickies);
13704            }
13705            ArrayList<Intent> list = stickies.get(intent.getAction());
13706            if (list == null) {
13707                list = new ArrayList<Intent>();
13708                stickies.put(intent.getAction(), list);
13709            }
13710            int N = list.size();
13711            int i;
13712            for (i=0; i<N; i++) {
13713                if (intent.filterEquals(list.get(i))) {
13714                    // This sticky already exists, replace it.
13715                    list.set(i, new Intent(intent));
13716                    break;
13717                }
13718            }
13719            if (i >= N) {
13720                list.add(new Intent(intent));
13721            }
13722        }
13723
13724        int[] users;
13725        if (userId == UserHandle.USER_ALL) {
13726            // Caller wants broadcast to go to all started users.
13727            users = mStartedUserArray;
13728        } else {
13729            // Caller wants broadcast to go to one specific user.
13730            users = new int[] {userId};
13731        }
13732
13733        // Figure out who all will receive this broadcast.
13734        List receivers = null;
13735        List<BroadcastFilter> registeredReceivers = null;
13736        // Need to resolve the intent to interested receivers...
13737        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13738                 == 0) {
13739            receivers = collectReceiverComponents(intent, resolvedType, users);
13740        }
13741        if (intent.getComponent() == null) {
13742            registeredReceivers = mReceiverResolver.queryIntent(intent,
13743                    resolvedType, false, userId);
13744        }
13745
13746        final boolean replacePending =
13747                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13748
13749        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13750                + " replacePending=" + replacePending);
13751
13752        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13753        if (!ordered && NR > 0) {
13754            // If we are not serializing this broadcast, then send the
13755            // registered receivers separately so they don't wait for the
13756            // components to be launched.
13757            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13758            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13759                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13760                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13761                    ordered, sticky, false, userId);
13762            if (DEBUG_BROADCAST) Slog.v(
13763                    TAG, "Enqueueing parallel broadcast " + r);
13764            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13765            if (!replaced) {
13766                queue.enqueueParallelBroadcastLocked(r);
13767                queue.scheduleBroadcastsLocked();
13768            }
13769            registeredReceivers = null;
13770            NR = 0;
13771        }
13772
13773        // Merge into one list.
13774        int ir = 0;
13775        if (receivers != null) {
13776            // A special case for PACKAGE_ADDED: do not allow the package
13777            // being added to see this broadcast.  This prevents them from
13778            // using this as a back door to get run as soon as they are
13779            // installed.  Maybe in the future we want to have a special install
13780            // broadcast or such for apps, but we'd like to deliberately make
13781            // this decision.
13782            String skipPackages[] = null;
13783            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13784                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13785                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13786                Uri data = intent.getData();
13787                if (data != null) {
13788                    String pkgName = data.getSchemeSpecificPart();
13789                    if (pkgName != null) {
13790                        skipPackages = new String[] { pkgName };
13791                    }
13792                }
13793            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13794                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13795            }
13796            if (skipPackages != null && (skipPackages.length > 0)) {
13797                for (String skipPackage : skipPackages) {
13798                    if (skipPackage != null) {
13799                        int NT = receivers.size();
13800                        for (int it=0; it<NT; it++) {
13801                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13802                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13803                                receivers.remove(it);
13804                                it--;
13805                                NT--;
13806                            }
13807                        }
13808                    }
13809                }
13810            }
13811
13812            int NT = receivers != null ? receivers.size() : 0;
13813            int it = 0;
13814            ResolveInfo curt = null;
13815            BroadcastFilter curr = null;
13816            while (it < NT && ir < NR) {
13817                if (curt == null) {
13818                    curt = (ResolveInfo)receivers.get(it);
13819                }
13820                if (curr == null) {
13821                    curr = registeredReceivers.get(ir);
13822                }
13823                if (curr.getPriority() >= curt.priority) {
13824                    // Insert this broadcast record into the final list.
13825                    receivers.add(it, curr);
13826                    ir++;
13827                    curr = null;
13828                    it++;
13829                    NT++;
13830                } else {
13831                    // Skip to the next ResolveInfo in the final list.
13832                    it++;
13833                    curt = null;
13834                }
13835            }
13836        }
13837        while (ir < NR) {
13838            if (receivers == null) {
13839                receivers = new ArrayList();
13840            }
13841            receivers.add(registeredReceivers.get(ir));
13842            ir++;
13843        }
13844
13845        if ((receivers != null && receivers.size() > 0)
13846                || resultTo != null) {
13847            BroadcastQueue queue = broadcastQueueForIntent(intent);
13848            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13849                    callerPackage, callingPid, callingUid, resolvedType,
13850                    requiredPermission, appOp, receivers, resultTo, resultCode,
13851                    resultData, map, ordered, sticky, false, userId);
13852            if (DEBUG_BROADCAST) Slog.v(
13853                    TAG, "Enqueueing ordered broadcast " + r
13854                    + ": prev had " + queue.mOrderedBroadcasts.size());
13855            if (DEBUG_BROADCAST) {
13856                int seq = r.intent.getIntExtra("seq", -1);
13857                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13858            }
13859            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13860            if (!replaced) {
13861                queue.enqueueOrderedBroadcastLocked(r);
13862                queue.scheduleBroadcastsLocked();
13863            }
13864        }
13865
13866        return ActivityManager.BROADCAST_SUCCESS;
13867    }
13868
13869    final Intent verifyBroadcastLocked(Intent intent) {
13870        // Refuse possible leaked file descriptors
13871        if (intent != null && intent.hasFileDescriptors() == true) {
13872            throw new IllegalArgumentException("File descriptors passed in Intent");
13873        }
13874
13875        int flags = intent.getFlags();
13876
13877        if (!mProcessesReady) {
13878            // if the caller really truly claims to know what they're doing, go
13879            // ahead and allow the broadcast without launching any receivers
13880            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13881                intent = new Intent(intent);
13882                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13883            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13884                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13885                        + " before boot completion");
13886                throw new IllegalStateException("Cannot broadcast before boot completed");
13887            }
13888        }
13889
13890        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13891            throw new IllegalArgumentException(
13892                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13893        }
13894
13895        return intent;
13896    }
13897
13898    public final int broadcastIntent(IApplicationThread caller,
13899            Intent intent, String resolvedType, IIntentReceiver resultTo,
13900            int resultCode, String resultData, Bundle map,
13901            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13902        enforceNotIsolatedCaller("broadcastIntent");
13903        synchronized(this) {
13904            intent = verifyBroadcastLocked(intent);
13905
13906            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13907            final int callingPid = Binder.getCallingPid();
13908            final int callingUid = Binder.getCallingUid();
13909            final long origId = Binder.clearCallingIdentity();
13910            int res = broadcastIntentLocked(callerApp,
13911                    callerApp != null ? callerApp.info.packageName : null,
13912                    intent, resolvedType, resultTo,
13913                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13914                    callingPid, callingUid, userId);
13915            Binder.restoreCallingIdentity(origId);
13916            return res;
13917        }
13918    }
13919
13920    int broadcastIntentInPackage(String packageName, int uid,
13921            Intent intent, String resolvedType, IIntentReceiver resultTo,
13922            int resultCode, String resultData, Bundle map,
13923            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13924        synchronized(this) {
13925            intent = verifyBroadcastLocked(intent);
13926
13927            final long origId = Binder.clearCallingIdentity();
13928            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13929                    resultTo, resultCode, resultData, map, requiredPermission,
13930                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13931            Binder.restoreCallingIdentity(origId);
13932            return res;
13933        }
13934    }
13935
13936    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13937        // Refuse possible leaked file descriptors
13938        if (intent != null && intent.hasFileDescriptors() == true) {
13939            throw new IllegalArgumentException("File descriptors passed in Intent");
13940        }
13941
13942        userId = handleIncomingUser(Binder.getCallingPid(),
13943                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13944
13945        synchronized(this) {
13946            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13947                    != PackageManager.PERMISSION_GRANTED) {
13948                String msg = "Permission Denial: unbroadcastIntent() from pid="
13949                        + Binder.getCallingPid()
13950                        + ", uid=" + Binder.getCallingUid()
13951                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13952                Slog.w(TAG, msg);
13953                throw new SecurityException(msg);
13954            }
13955            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13956            if (stickies != null) {
13957                ArrayList<Intent> list = stickies.get(intent.getAction());
13958                if (list != null) {
13959                    int N = list.size();
13960                    int i;
13961                    for (i=0; i<N; i++) {
13962                        if (intent.filterEquals(list.get(i))) {
13963                            list.remove(i);
13964                            break;
13965                        }
13966                    }
13967                    if (list.size() <= 0) {
13968                        stickies.remove(intent.getAction());
13969                    }
13970                }
13971                if (stickies.size() <= 0) {
13972                    mStickyBroadcasts.remove(userId);
13973                }
13974            }
13975        }
13976    }
13977
13978    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13979            String resultData, Bundle resultExtras, boolean resultAbort) {
13980        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13981        if (r == null) {
13982            Slog.w(TAG, "finishReceiver called but not found on queue");
13983            return false;
13984        }
13985
13986        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13987    }
13988
13989    void backgroundServicesFinishedLocked(int userId) {
13990        for (BroadcastQueue queue : mBroadcastQueues) {
13991            queue.backgroundServicesFinishedLocked(userId);
13992        }
13993    }
13994
13995    public void finishReceiver(IBinder who, int resultCode, String resultData,
13996            Bundle resultExtras, boolean resultAbort) {
13997        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13998
13999        // Refuse possible leaked file descriptors
14000        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14001            throw new IllegalArgumentException("File descriptors passed in Bundle");
14002        }
14003
14004        final long origId = Binder.clearCallingIdentity();
14005        try {
14006            boolean doNext = false;
14007            BroadcastRecord r;
14008
14009            synchronized(this) {
14010                r = broadcastRecordForReceiverLocked(who);
14011                if (r != null) {
14012                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14013                        resultData, resultExtras, resultAbort, true);
14014                }
14015            }
14016
14017            if (doNext) {
14018                r.queue.processNextBroadcast(false);
14019            }
14020            trimApplications();
14021        } finally {
14022            Binder.restoreCallingIdentity(origId);
14023        }
14024    }
14025
14026    // =========================================================
14027    // INSTRUMENTATION
14028    // =========================================================
14029
14030    public boolean startInstrumentation(ComponentName className,
14031            String profileFile, int flags, Bundle arguments,
14032            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14033            int userId) {
14034        enforceNotIsolatedCaller("startInstrumentation");
14035        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14036                userId, false, true, "startInstrumentation", null);
14037        // Refuse possible leaked file descriptors
14038        if (arguments != null && arguments.hasFileDescriptors()) {
14039            throw new IllegalArgumentException("File descriptors passed in Bundle");
14040        }
14041
14042        synchronized(this) {
14043            InstrumentationInfo ii = null;
14044            ApplicationInfo ai = null;
14045            try {
14046                ii = mContext.getPackageManager().getInstrumentationInfo(
14047                    className, STOCK_PM_FLAGS);
14048                ai = AppGlobals.getPackageManager().getApplicationInfo(
14049                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14050            } catch (PackageManager.NameNotFoundException e) {
14051            } catch (RemoteException e) {
14052            }
14053            if (ii == null) {
14054                reportStartInstrumentationFailure(watcher, className,
14055                        "Unable to find instrumentation info for: " + className);
14056                return false;
14057            }
14058            if (ai == null) {
14059                reportStartInstrumentationFailure(watcher, className,
14060                        "Unable to find instrumentation target package: " + ii.targetPackage);
14061                return false;
14062            }
14063
14064            int match = mContext.getPackageManager().checkSignatures(
14065                    ii.targetPackage, ii.packageName);
14066            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14067                String msg = "Permission Denial: starting instrumentation "
14068                        + className + " from pid="
14069                        + Binder.getCallingPid()
14070                        + ", uid=" + Binder.getCallingPid()
14071                        + " not allowed because package " + ii.packageName
14072                        + " does not have a signature matching the target "
14073                        + ii.targetPackage;
14074                reportStartInstrumentationFailure(watcher, className, msg);
14075                throw new SecurityException(msg);
14076            }
14077
14078            final long origId = Binder.clearCallingIdentity();
14079            // Instrumentation can kill and relaunch even persistent processes
14080            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14081                    "start instr");
14082            ProcessRecord app = addAppLocked(ai, false);
14083            app.instrumentationClass = className;
14084            app.instrumentationInfo = ai;
14085            app.instrumentationProfileFile = profileFile;
14086            app.instrumentationArguments = arguments;
14087            app.instrumentationWatcher = watcher;
14088            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14089            app.instrumentationResultClass = className;
14090            Binder.restoreCallingIdentity(origId);
14091        }
14092
14093        return true;
14094    }
14095
14096    /**
14097     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14098     * error to the logs, but if somebody is watching, send the report there too.  This enables
14099     * the "am" command to report errors with more information.
14100     *
14101     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14102     * @param cn The component name of the instrumentation.
14103     * @param report The error report.
14104     */
14105    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14106            ComponentName cn, String report) {
14107        Slog.w(TAG, report);
14108        try {
14109            if (watcher != null) {
14110                Bundle results = new Bundle();
14111                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14112                results.putString("Error", report);
14113                watcher.instrumentationStatus(cn, -1, results);
14114            }
14115        } catch (RemoteException e) {
14116            Slog.w(TAG, e);
14117        }
14118    }
14119
14120    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14121        if (app.instrumentationWatcher != null) {
14122            try {
14123                // NOTE:  IInstrumentationWatcher *must* be oneway here
14124                app.instrumentationWatcher.instrumentationFinished(
14125                    app.instrumentationClass,
14126                    resultCode,
14127                    results);
14128            } catch (RemoteException e) {
14129            }
14130        }
14131        if (app.instrumentationUiAutomationConnection != null) {
14132            try {
14133                app.instrumentationUiAutomationConnection.shutdown();
14134            } catch (RemoteException re) {
14135                /* ignore */
14136            }
14137            // Only a UiAutomation can set this flag and now that
14138            // it is finished we make sure it is reset to its default.
14139            mUserIsMonkey = false;
14140        }
14141        app.instrumentationWatcher = null;
14142        app.instrumentationUiAutomationConnection = null;
14143        app.instrumentationClass = null;
14144        app.instrumentationInfo = null;
14145        app.instrumentationProfileFile = null;
14146        app.instrumentationArguments = null;
14147
14148        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14149                "finished inst");
14150    }
14151
14152    public void finishInstrumentation(IApplicationThread target,
14153            int resultCode, Bundle results) {
14154        int userId = UserHandle.getCallingUserId();
14155        // Refuse possible leaked file descriptors
14156        if (results != null && results.hasFileDescriptors()) {
14157            throw new IllegalArgumentException("File descriptors passed in Intent");
14158        }
14159
14160        synchronized(this) {
14161            ProcessRecord app = getRecordForAppLocked(target);
14162            if (app == null) {
14163                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14164                return;
14165            }
14166            final long origId = Binder.clearCallingIdentity();
14167            finishInstrumentationLocked(app, resultCode, results);
14168            Binder.restoreCallingIdentity(origId);
14169        }
14170    }
14171
14172    // =========================================================
14173    // CONFIGURATION
14174    // =========================================================
14175
14176    public ConfigurationInfo getDeviceConfigurationInfo() {
14177        ConfigurationInfo config = new ConfigurationInfo();
14178        synchronized (this) {
14179            config.reqTouchScreen = mConfiguration.touchscreen;
14180            config.reqKeyboardType = mConfiguration.keyboard;
14181            config.reqNavigation = mConfiguration.navigation;
14182            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14183                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14184                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14185            }
14186            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14187                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14188                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14189            }
14190            config.reqGlEsVersion = GL_ES_VERSION;
14191        }
14192        return config;
14193    }
14194
14195    ActivityStack getFocusedStack() {
14196        return mStackSupervisor.getFocusedStack();
14197    }
14198
14199    public Configuration getConfiguration() {
14200        Configuration ci;
14201        synchronized(this) {
14202            ci = new Configuration(mConfiguration);
14203        }
14204        return ci;
14205    }
14206
14207    public void updatePersistentConfiguration(Configuration values) {
14208        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14209                "updateConfiguration()");
14210        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14211                "updateConfiguration()");
14212        if (values == null) {
14213            throw new NullPointerException("Configuration must not be null");
14214        }
14215
14216        synchronized(this) {
14217            final long origId = Binder.clearCallingIdentity();
14218            updateConfigurationLocked(values, null, true, false);
14219            Binder.restoreCallingIdentity(origId);
14220        }
14221    }
14222
14223    public void updateConfiguration(Configuration values) {
14224        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14225                "updateConfiguration()");
14226
14227        synchronized(this) {
14228            if (values == null && mWindowManager != null) {
14229                // sentinel: fetch the current configuration from the window manager
14230                values = mWindowManager.computeNewConfiguration();
14231            }
14232
14233            if (mWindowManager != null) {
14234                mProcessList.applyDisplaySize(mWindowManager);
14235            }
14236
14237            final long origId = Binder.clearCallingIdentity();
14238            if (values != null) {
14239                Settings.System.clearConfiguration(values);
14240            }
14241            updateConfigurationLocked(values, null, false, false);
14242            Binder.restoreCallingIdentity(origId);
14243        }
14244    }
14245
14246    /**
14247     * Do either or both things: (1) change the current configuration, and (2)
14248     * make sure the given activity is running with the (now) current
14249     * configuration.  Returns true if the activity has been left running, or
14250     * false if <var>starting</var> is being destroyed to match the new
14251     * configuration.
14252     * @param persistent TODO
14253     */
14254    boolean updateConfigurationLocked(Configuration values,
14255            ActivityRecord starting, boolean persistent, boolean initLocale) {
14256        int changes = 0;
14257
14258        if (values != null) {
14259            Configuration newConfig = new Configuration(mConfiguration);
14260            changes = newConfig.updateFrom(values);
14261            if (changes != 0) {
14262                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14263                    Slog.i(TAG, "Updating configuration to: " + values);
14264                }
14265
14266                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14267
14268                if (values.locale != null && !initLocale) {
14269                    saveLocaleLocked(values.locale,
14270                                     !values.locale.equals(mConfiguration.locale),
14271                                     values.userSetLocale);
14272                }
14273
14274                mConfigurationSeq++;
14275                if (mConfigurationSeq <= 0) {
14276                    mConfigurationSeq = 1;
14277                }
14278                newConfig.seq = mConfigurationSeq;
14279                mConfiguration = newConfig;
14280                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14281
14282                final Configuration configCopy = new Configuration(mConfiguration);
14283
14284                // TODO: If our config changes, should we auto dismiss any currently
14285                // showing dialogs?
14286                mShowDialogs = shouldShowDialogs(newConfig);
14287
14288                AttributeCache ac = AttributeCache.instance();
14289                if (ac != null) {
14290                    ac.updateConfiguration(configCopy);
14291                }
14292
14293                // Make sure all resources in our process are updated
14294                // right now, so that anyone who is going to retrieve
14295                // resource values after we return will be sure to get
14296                // the new ones.  This is especially important during
14297                // boot, where the first config change needs to guarantee
14298                // all resources have that config before following boot
14299                // code is executed.
14300                mSystemThread.applyConfigurationToResources(configCopy);
14301
14302                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14303                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14304                    msg.obj = new Configuration(configCopy);
14305                    mHandler.sendMessage(msg);
14306                }
14307
14308                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14309                    ProcessRecord app = mLruProcesses.get(i);
14310                    try {
14311                        if (app.thread != null) {
14312                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14313                                    + app.processName + " new config " + mConfiguration);
14314                            app.thread.scheduleConfigurationChanged(configCopy);
14315                        }
14316                    } catch (Exception e) {
14317                    }
14318                }
14319                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14320                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14321                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14322                        | Intent.FLAG_RECEIVER_FOREGROUND);
14323                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14324                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14325                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14326                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14327                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14328                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14329                    broadcastIntentLocked(null, null, intent,
14330                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14331                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14332                }
14333            }
14334        }
14335
14336        boolean kept = true;
14337        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14338        // mainStack is null during startup.
14339        if (mainStack != null) {
14340            if (changes != 0 && starting == null) {
14341                // If the configuration changed, and the caller is not already
14342                // in the process of starting an activity, then find the top
14343                // activity to check if its configuration needs to change.
14344                starting = mainStack.topRunningActivityLocked(null);
14345            }
14346
14347            if (starting != null) {
14348                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14349                // And we need to make sure at this point that all other activities
14350                // are made visible with the correct configuration.
14351                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14352            }
14353        }
14354
14355        if (values != null && mWindowManager != null) {
14356            mWindowManager.setNewConfiguration(mConfiguration);
14357        }
14358
14359        return kept;
14360    }
14361
14362    /**
14363     * Decide based on the configuration whether we should shouw the ANR,
14364     * crash, etc dialogs.  The idea is that if there is no affordnace to
14365     * press the on-screen buttons, we shouldn't show the dialog.
14366     *
14367     * A thought: SystemUI might also want to get told about this, the Power
14368     * dialog / global actions also might want different behaviors.
14369     */
14370    private static final boolean shouldShowDialogs(Configuration config) {
14371        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14372                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14373    }
14374
14375    /**
14376     * Save the locale.  You must be inside a synchronized (this) block.
14377     */
14378    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14379        if(isDiff) {
14380            SystemProperties.set("user.language", l.getLanguage());
14381            SystemProperties.set("user.region", l.getCountry());
14382        }
14383
14384        if(isPersist) {
14385            SystemProperties.set("persist.sys.language", l.getLanguage());
14386            SystemProperties.set("persist.sys.country", l.getCountry());
14387            SystemProperties.set("persist.sys.localevar", l.getVariant());
14388        }
14389    }
14390
14391    @Override
14392    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14393        ActivityRecord srec = ActivityRecord.forToken(token);
14394        return srec != null && srec.task.affinity != null &&
14395                srec.task.affinity.equals(destAffinity);
14396    }
14397
14398    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14399            Intent resultData) {
14400
14401        synchronized (this) {
14402            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14403            if (stack != null) {
14404                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14405            }
14406            return false;
14407        }
14408    }
14409
14410    public int getLaunchedFromUid(IBinder activityToken) {
14411        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14412        if (srec == null) {
14413            return -1;
14414        }
14415        return srec.launchedFromUid;
14416    }
14417
14418    public String getLaunchedFromPackage(IBinder activityToken) {
14419        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14420        if (srec == null) {
14421            return null;
14422        }
14423        return srec.launchedFromPackage;
14424    }
14425
14426    // =========================================================
14427    // LIFETIME MANAGEMENT
14428    // =========================================================
14429
14430    // Returns which broadcast queue the app is the current [or imminent] receiver
14431    // on, or 'null' if the app is not an active broadcast recipient.
14432    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14433        BroadcastRecord r = app.curReceiver;
14434        if (r != null) {
14435            return r.queue;
14436        }
14437
14438        // It's not the current receiver, but it might be starting up to become one
14439        synchronized (this) {
14440            for (BroadcastQueue queue : mBroadcastQueues) {
14441                r = queue.mPendingBroadcast;
14442                if (r != null && r.curApp == app) {
14443                    // found it; report which queue it's in
14444                    return queue;
14445                }
14446            }
14447        }
14448
14449        return null;
14450    }
14451
14452    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14453            boolean doingAll, long now) {
14454        if (mAdjSeq == app.adjSeq) {
14455            // This adjustment has already been computed.
14456            return app.curRawAdj;
14457        }
14458
14459        if (app.thread == null) {
14460            app.adjSeq = mAdjSeq;
14461            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14462            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14463            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14464        }
14465
14466        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14467        app.adjSource = null;
14468        app.adjTarget = null;
14469        app.empty = false;
14470        app.cached = false;
14471
14472        final int activitiesSize = app.activities.size();
14473
14474        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14475            // The max adjustment doesn't allow this app to be anything
14476            // below foreground, so it is not worth doing work for it.
14477            app.adjType = "fixed";
14478            app.adjSeq = mAdjSeq;
14479            app.curRawAdj = app.maxAdj;
14480            app.foregroundActivities = false;
14481            app.keeping = true;
14482            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14483            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14484            // System process can do UI, and when they do we want to have
14485            // them trim their memory after the user leaves the UI.  To
14486            // facilitate this, here we need to determine whether or not it
14487            // is currently showing UI.
14488            app.systemNoUi = true;
14489            if (app == TOP_APP) {
14490                app.systemNoUi = false;
14491            } else if (activitiesSize > 0) {
14492                for (int j = 0; j < activitiesSize; j++) {
14493                    final ActivityRecord r = app.activities.get(j);
14494                    if (r.visible) {
14495                        app.systemNoUi = false;
14496                    }
14497                }
14498            }
14499            if (!app.systemNoUi) {
14500                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14501            }
14502            return (app.curAdj=app.maxAdj);
14503        }
14504
14505        app.keeping = false;
14506        app.systemNoUi = false;
14507
14508        // Determine the importance of the process, starting with most
14509        // important to least, and assign an appropriate OOM adjustment.
14510        int adj;
14511        int schedGroup;
14512        int procState;
14513        boolean foregroundActivities = false;
14514        boolean interesting = false;
14515        BroadcastQueue queue;
14516        if (app == TOP_APP) {
14517            // The last app on the list is the foreground app.
14518            adj = ProcessList.FOREGROUND_APP_ADJ;
14519            schedGroup = Process.THREAD_GROUP_DEFAULT;
14520            app.adjType = "top-activity";
14521            foregroundActivities = true;
14522            interesting = true;
14523            procState = ActivityManager.PROCESS_STATE_TOP;
14524        } else if (app.instrumentationClass != null) {
14525            // Don't want to kill running instrumentation.
14526            adj = ProcessList.FOREGROUND_APP_ADJ;
14527            schedGroup = Process.THREAD_GROUP_DEFAULT;
14528            app.adjType = "instrumentation";
14529            interesting = true;
14530            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14531        } else if ((queue = isReceivingBroadcast(app)) != null) {
14532            // An app that is currently receiving a broadcast also
14533            // counts as being in the foreground for OOM killer purposes.
14534            // It's placed in a sched group based on the nature of the
14535            // broadcast as reflected by which queue it's active in.
14536            adj = ProcessList.FOREGROUND_APP_ADJ;
14537            schedGroup = (queue == mFgBroadcastQueue)
14538                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14539            app.adjType = "broadcast";
14540            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14541        } else if (app.executingServices.size() > 0) {
14542            // An app that is currently executing a service callback also
14543            // counts as being in the foreground.
14544            adj = ProcessList.FOREGROUND_APP_ADJ;
14545            schedGroup = app.execServicesFg ?
14546                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14547            app.adjType = "exec-service";
14548            procState = ActivityManager.PROCESS_STATE_SERVICE;
14549            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14550        } else {
14551            // As far as we know the process is empty.  We may change our mind later.
14552            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14553            // At this point we don't actually know the adjustment.  Use the cached adj
14554            // value that the caller wants us to.
14555            adj = cachedAdj;
14556            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14557            app.cached = true;
14558            app.empty = true;
14559            app.adjType = "cch-empty";
14560        }
14561
14562        // Examine all activities if not already foreground.
14563        if (!foregroundActivities && activitiesSize > 0) {
14564            for (int j = 0; j < activitiesSize; j++) {
14565                final ActivityRecord r = app.activities.get(j);
14566                if (r.app != app) {
14567                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14568                            + app + "?!?");
14569                    continue;
14570                }
14571                if (r.visible) {
14572                    // App has a visible activity; only upgrade adjustment.
14573                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14574                        adj = ProcessList.VISIBLE_APP_ADJ;
14575                        app.adjType = "visible";
14576                    }
14577                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14578                        procState = ActivityManager.PROCESS_STATE_TOP;
14579                    }
14580                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14581                    app.cached = false;
14582                    app.empty = false;
14583                    foregroundActivities = true;
14584                    break;
14585                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14586                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14587                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14588                        app.adjType = "pausing";
14589                    }
14590                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14591                        procState = ActivityManager.PROCESS_STATE_TOP;
14592                    }
14593                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14594                    app.cached = false;
14595                    app.empty = false;
14596                    foregroundActivities = true;
14597                } else if (r.state == ActivityState.STOPPING) {
14598                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14599                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14600                        app.adjType = "stopping";
14601                    }
14602                    // For the process state, we will at this point consider the
14603                    // process to be cached.  It will be cached either as an activity
14604                    // or empty depending on whether the activity is finishing.  We do
14605                    // this so that we can treat the process as cached for purposes of
14606                    // memory trimming (determing current memory level, trim command to
14607                    // send to process) since there can be an arbitrary number of stopping
14608                    // processes and they should soon all go into the cached state.
14609                    if (!r.finishing) {
14610                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14611                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14612                        }
14613                    }
14614                    app.cached = false;
14615                    app.empty = false;
14616                    foregroundActivities = true;
14617                } else {
14618                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14619                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14620                        app.adjType = "cch-act";
14621                    }
14622                }
14623            }
14624        }
14625
14626        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14627            if (app.foregroundServices) {
14628                // The user is aware of this app, so make it visible.
14629                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14630                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14631                app.cached = false;
14632                app.adjType = "fg-service";
14633                schedGroup = Process.THREAD_GROUP_DEFAULT;
14634            } else if (app.forcingToForeground != null) {
14635                // The user is aware of this app, so make it visible.
14636                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14637                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14638                app.cached = false;
14639                app.adjType = "force-fg";
14640                app.adjSource = app.forcingToForeground;
14641                schedGroup = Process.THREAD_GROUP_DEFAULT;
14642            }
14643        }
14644
14645        if (app.foregroundServices) {
14646            interesting = true;
14647        }
14648
14649        if (app == mHeavyWeightProcess) {
14650            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14651                // We don't want to kill the current heavy-weight process.
14652                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14653                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14654                app.cached = false;
14655                app.adjType = "heavy";
14656            }
14657            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14658                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14659            }
14660        }
14661
14662        if (app == mHomeProcess) {
14663            if (adj > ProcessList.HOME_APP_ADJ) {
14664                // This process is hosting what we currently consider to be the
14665                // home app, so we don't want to let it go into the background.
14666                adj = ProcessList.HOME_APP_ADJ;
14667                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14668                app.cached = false;
14669                app.adjType = "home";
14670            }
14671            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14672                procState = ActivityManager.PROCESS_STATE_HOME;
14673            }
14674        }
14675
14676        if (app == mPreviousProcess && app.activities.size() > 0) {
14677            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14678                // This was the previous process that showed UI to the user.
14679                // We want to try to keep it around more aggressively, to give
14680                // a good experience around switching between two apps.
14681                adj = ProcessList.PREVIOUS_APP_ADJ;
14682                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14683                app.cached = false;
14684                app.adjType = "previous";
14685            }
14686            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14687                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14688            }
14689        }
14690
14691        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14692                + " reason=" + app.adjType);
14693
14694        // By default, we use the computed adjustment.  It may be changed if
14695        // there are applications dependent on our services or providers, but
14696        // this gives us a baseline and makes sure we don't get into an
14697        // infinite recursion.
14698        app.adjSeq = mAdjSeq;
14699        app.curRawAdj = adj;
14700        app.hasStartedServices = false;
14701
14702        if (mBackupTarget != null && app == mBackupTarget.app) {
14703            // If possible we want to avoid killing apps while they're being backed up
14704            if (adj > ProcessList.BACKUP_APP_ADJ) {
14705                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14706                adj = ProcessList.BACKUP_APP_ADJ;
14707                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14708                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14709                }
14710                app.adjType = "backup";
14711                app.cached = false;
14712            }
14713            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14714                procState = ActivityManager.PROCESS_STATE_BACKUP;
14715            }
14716        }
14717
14718        boolean mayBeTop = false;
14719
14720        for (int is = app.services.size()-1;
14721                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14722                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14723                        || procState > ActivityManager.PROCESS_STATE_TOP);
14724                is--) {
14725            ServiceRecord s = app.services.valueAt(is);
14726            if (s.startRequested) {
14727                app.hasStartedServices = true;
14728                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14729                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14730                }
14731                if (app.hasShownUi && app != mHomeProcess) {
14732                    // If this process has shown some UI, let it immediately
14733                    // go to the LRU list because it may be pretty heavy with
14734                    // UI stuff.  We'll tag it with a label just to help
14735                    // debug and understand what is going on.
14736                    if (adj > ProcessList.SERVICE_ADJ) {
14737                        app.adjType = "cch-started-ui-services";
14738                    }
14739                } else {
14740                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14741                        // This service has seen some activity within
14742                        // recent memory, so we will keep its process ahead
14743                        // of the background processes.
14744                        if (adj > ProcessList.SERVICE_ADJ) {
14745                            adj = ProcessList.SERVICE_ADJ;
14746                            app.adjType = "started-services";
14747                            app.cached = false;
14748                        }
14749                    }
14750                    // If we have let the service slide into the background
14751                    // state, still have some text describing what it is doing
14752                    // even though the service no longer has an impact.
14753                    if (adj > ProcessList.SERVICE_ADJ) {
14754                        app.adjType = "cch-started-services";
14755                    }
14756                }
14757                // Don't kill this process because it is doing work; it
14758                // has said it is doing work.
14759                app.keeping = true;
14760            }
14761            for (int conni = s.connections.size()-1;
14762                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14763                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14764                            || procState > ActivityManager.PROCESS_STATE_TOP);
14765                    conni--) {
14766                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14767                for (int i = 0;
14768                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14769                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14770                                || procState > ActivityManager.PROCESS_STATE_TOP);
14771                        i++) {
14772                    // XXX should compute this based on the max of
14773                    // all connected clients.
14774                    ConnectionRecord cr = clist.get(i);
14775                    if (cr.binding.client == app) {
14776                        // Binding to ourself is not interesting.
14777                        continue;
14778                    }
14779                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14780                        ProcessRecord client = cr.binding.client;
14781                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14782                                TOP_APP, doingAll, now);
14783                        int clientProcState = client.curProcState;
14784                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14785                            // If the other app is cached for any reason, for purposes here
14786                            // we are going to consider it empty.  The specific cached state
14787                            // doesn't propagate except under certain conditions.
14788                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14789                        }
14790                        String adjType = null;
14791                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14792                            // Not doing bind OOM management, so treat
14793                            // this guy more like a started service.
14794                            if (app.hasShownUi && app != mHomeProcess) {
14795                                // If this process has shown some UI, let it immediately
14796                                // go to the LRU list because it may be pretty heavy with
14797                                // UI stuff.  We'll tag it with a label just to help
14798                                // debug and understand what is going on.
14799                                if (adj > clientAdj) {
14800                                    adjType = "cch-bound-ui-services";
14801                                }
14802                                app.cached = false;
14803                                clientAdj = adj;
14804                                clientProcState = procState;
14805                            } else {
14806                                if (now >= (s.lastActivity
14807                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14808                                    // This service has not seen activity within
14809                                    // recent memory, so allow it to drop to the
14810                                    // LRU list if there is no other reason to keep
14811                                    // it around.  We'll also tag it with a label just
14812                                    // to help debug and undertand what is going on.
14813                                    if (adj > clientAdj) {
14814                                        adjType = "cch-bound-services";
14815                                    }
14816                                    clientAdj = adj;
14817                                }
14818                            }
14819                        }
14820                        if (adj > clientAdj) {
14821                            // If this process has recently shown UI, and
14822                            // the process that is binding to it is less
14823                            // important than being visible, then we don't
14824                            // care about the binding as much as we care
14825                            // about letting this process get into the LRU
14826                            // list to be killed and restarted if needed for
14827                            // memory.
14828                            if (app.hasShownUi && app != mHomeProcess
14829                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14830                                adjType = "cch-bound-ui-services";
14831                            } else {
14832                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14833                                        |Context.BIND_IMPORTANT)) != 0) {
14834                                    adj = clientAdj;
14835                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14836                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14837                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14838                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14839                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14840                                    adj = clientAdj;
14841                                } else {
14842                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14843                                        adj = ProcessList.VISIBLE_APP_ADJ;
14844                                    }
14845                                }
14846                                if (!client.cached) {
14847                                    app.cached = false;
14848                                }
14849                                if (client.keeping) {
14850                                    app.keeping = true;
14851                                }
14852                                adjType = "service";
14853                            }
14854                        }
14855                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14856                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14857                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14858                            }
14859                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14860                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14861                                    // Special handling of clients who are in the top state.
14862                                    // We *may* want to consider this process to be in the
14863                                    // top state as well, but only if there is not another
14864                                    // reason for it to be running.  Being on the top is a
14865                                    // special state, meaning you are specifically running
14866                                    // for the current top app.  If the process is already
14867                                    // running in the background for some other reason, it
14868                                    // is more important to continue considering it to be
14869                                    // in the background state.
14870                                    mayBeTop = true;
14871                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14872                                } else {
14873                                    // Special handling for above-top states (persistent
14874                                    // processes).  These should not bring the current process
14875                                    // into the top state, since they are not on top.  Instead
14876                                    // give them the best state after that.
14877                                    clientProcState =
14878                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14879                                }
14880                            }
14881                        } else {
14882                            if (clientProcState <
14883                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14884                                clientProcState =
14885                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14886                            }
14887                        }
14888                        if (procState > clientProcState) {
14889                            procState = clientProcState;
14890                        }
14891                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14892                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14893                            app.pendingUiClean = true;
14894                        }
14895                        if (adjType != null) {
14896                            app.adjType = adjType;
14897                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14898                                    .REASON_SERVICE_IN_USE;
14899                            app.adjSource = cr.binding.client;
14900                            app.adjSourceOom = clientAdj;
14901                            app.adjTarget = s.name;
14902                        }
14903                    }
14904                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14905                        app.treatLikeActivity = true;
14906                    }
14907                    final ActivityRecord a = cr.activity;
14908                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14909                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14910                                (a.visible || a.state == ActivityState.RESUMED
14911                                 || a.state == ActivityState.PAUSING)) {
14912                            adj = ProcessList.FOREGROUND_APP_ADJ;
14913                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14914                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14915                            }
14916                            app.cached = false;
14917                            app.adjType = "service";
14918                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14919                                    .REASON_SERVICE_IN_USE;
14920                            app.adjSource = a;
14921                            app.adjSourceOom = adj;
14922                            app.adjTarget = s.name;
14923                        }
14924                    }
14925                }
14926            }
14927        }
14928
14929        for (int provi = app.pubProviders.size()-1;
14930                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14931                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14932                        || procState > ActivityManager.PROCESS_STATE_TOP);
14933                provi--) {
14934            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14935            for (int i = cpr.connections.size()-1;
14936                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14937                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14938                            || procState > ActivityManager.PROCESS_STATE_TOP);
14939                    i--) {
14940                ContentProviderConnection conn = cpr.connections.get(i);
14941                ProcessRecord client = conn.client;
14942                if (client == app) {
14943                    // Being our own client is not interesting.
14944                    continue;
14945                }
14946                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14947                int clientProcState = client.curProcState;
14948                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14949                    // If the other app is cached for any reason, for purposes here
14950                    // we are going to consider it empty.
14951                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14952                }
14953                if (adj > clientAdj) {
14954                    if (app.hasShownUi && app != mHomeProcess
14955                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14956                        app.adjType = "cch-ui-provider";
14957                    } else {
14958                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14959                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14960                        app.adjType = "provider";
14961                    }
14962                    app.cached &= client.cached;
14963                    app.keeping |= client.keeping;
14964                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14965                            .REASON_PROVIDER_IN_USE;
14966                    app.adjSource = client;
14967                    app.adjSourceOom = clientAdj;
14968                    app.adjTarget = cpr.name;
14969                }
14970                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14971                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14972                        // Special handling of clients who are in the top state.
14973                        // We *may* want to consider this process to be in the
14974                        // top state as well, but only if there is not another
14975                        // reason for it to be running.  Being on the top is a
14976                        // special state, meaning you are specifically running
14977                        // for the current top app.  If the process is already
14978                        // running in the background for some other reason, it
14979                        // is more important to continue considering it to be
14980                        // in the background state.
14981                        mayBeTop = true;
14982                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14983                    } else {
14984                        // Special handling for above-top states (persistent
14985                        // processes).  These should not bring the current process
14986                        // into the top state, since they are not on top.  Instead
14987                        // give them the best state after that.
14988                        clientProcState =
14989                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14990                    }
14991                }
14992                if (procState > clientProcState) {
14993                    procState = clientProcState;
14994                }
14995                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14996                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14997                }
14998            }
14999            // If the provider has external (non-framework) process
15000            // dependencies, ensure that its adjustment is at least
15001            // FOREGROUND_APP_ADJ.
15002            if (cpr.hasExternalProcessHandles()) {
15003                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15004                    adj = ProcessList.FOREGROUND_APP_ADJ;
15005                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15006                    app.cached = false;
15007                    app.keeping = true;
15008                    app.adjType = "provider";
15009                    app.adjTarget = cpr.name;
15010                }
15011                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15012                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15013                }
15014            }
15015        }
15016
15017        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15018            // A client of one of our services or providers is in the top state.  We
15019            // *may* want to be in the top state, but not if we are already running in
15020            // the background for some other reason.  For the decision here, we are going
15021            // to pick out a few specific states that we want to remain in when a client
15022            // is top (states that tend to be longer-term) and otherwise allow it to go
15023            // to the top state.
15024            switch (procState) {
15025                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15026                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15027                case ActivityManager.PROCESS_STATE_SERVICE:
15028                    // These all are longer-term states, so pull them up to the top
15029                    // of the background states, but not all the way to the top state.
15030                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15031                    break;
15032                default:
15033                    // Otherwise, top is a better choice, so take it.
15034                    procState = ActivityManager.PROCESS_STATE_TOP;
15035                    break;
15036            }
15037        }
15038
15039        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15040            if (app.hasClientActivities) {
15041                // This is a cached process, but with client activities.  Mark it so.
15042                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15043                app.adjType = "cch-client-act";
15044            } else if (app.treatLikeActivity) {
15045                // This is a cached process, but somebody wants us to treat it like it has
15046                // an activity, okay!
15047                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15048                app.adjType = "cch-as-act";
15049            }
15050        }
15051
15052        if (adj == ProcessList.SERVICE_ADJ) {
15053            if (doingAll) {
15054                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15055                mNewNumServiceProcs++;
15056                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15057                if (!app.serviceb) {
15058                    // This service isn't far enough down on the LRU list to
15059                    // normally be a B service, but if we are low on RAM and it
15060                    // is large we want to force it down since we would prefer to
15061                    // keep launcher over it.
15062                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15063                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15064                        app.serviceHighRam = true;
15065                        app.serviceb = true;
15066                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15067                    } else {
15068                        mNewNumAServiceProcs++;
15069                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15070                    }
15071                } else {
15072                    app.serviceHighRam = false;
15073                }
15074            }
15075            if (app.serviceb) {
15076                adj = ProcessList.SERVICE_B_ADJ;
15077            }
15078        }
15079
15080        app.curRawAdj = adj;
15081
15082        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15083        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15084        if (adj > app.maxAdj) {
15085            adj = app.maxAdj;
15086            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15087                schedGroup = Process.THREAD_GROUP_DEFAULT;
15088            }
15089        }
15090        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15091            app.keeping = true;
15092        }
15093
15094        // Do final modification to adj.  Everything we do between here and applying
15095        // the final setAdj must be done in this function, because we will also use
15096        // it when computing the final cached adj later.  Note that we don't need to
15097        // worry about this for max adj above, since max adj will always be used to
15098        // keep it out of the cached vaues.
15099        adj = app.modifyRawOomAdj(adj);
15100
15101        app.curProcState = procState;
15102
15103        int importance = app.memImportance;
15104        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15105            app.curAdj = adj;
15106            app.curSchedGroup = schedGroup;
15107            if (!interesting) {
15108                // For this reporting, if there is not something explicitly
15109                // interesting in this process then we will push it to the
15110                // background importance.
15111                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15112            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15113                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15114            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15115                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15116            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15117                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15118            } else if (adj >= ProcessList.SERVICE_ADJ) {
15119                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15120            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15121                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15122            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15123                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15124            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15125                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15126            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15127                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15128            } else {
15129                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15130            }
15131        }
15132
15133        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15134        if (foregroundActivities != app.foregroundActivities) {
15135            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15136        }
15137        if (changes != 0) {
15138            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15139            app.memImportance = importance;
15140            app.foregroundActivities = foregroundActivities;
15141            int i = mPendingProcessChanges.size()-1;
15142            ProcessChangeItem item = null;
15143            while (i >= 0) {
15144                item = mPendingProcessChanges.get(i);
15145                if (item.pid == app.pid) {
15146                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15147                    break;
15148                }
15149                i--;
15150            }
15151            if (i < 0) {
15152                // No existing item in pending changes; need a new one.
15153                final int NA = mAvailProcessChanges.size();
15154                if (NA > 0) {
15155                    item = mAvailProcessChanges.remove(NA-1);
15156                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15157                } else {
15158                    item = new ProcessChangeItem();
15159                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15160                }
15161                item.changes = 0;
15162                item.pid = app.pid;
15163                item.uid = app.info.uid;
15164                if (mPendingProcessChanges.size() == 0) {
15165                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15166                            "*** Enqueueing dispatch processes changed!");
15167                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15168                }
15169                mPendingProcessChanges.add(item);
15170            }
15171            item.changes |= changes;
15172            item.importance = importance;
15173            item.foregroundActivities = foregroundActivities;
15174            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15175                    + Integer.toHexString(System.identityHashCode(item))
15176                    + " " + app.toShortString() + ": changes=" + item.changes
15177                    + " importance=" + item.importance
15178                    + " foreground=" + item.foregroundActivities
15179                    + " type=" + app.adjType + " source=" + app.adjSource
15180                    + " target=" + app.adjTarget);
15181        }
15182
15183        return app.curRawAdj;
15184    }
15185
15186    /**
15187     * Schedule PSS collection of a process.
15188     */
15189    void requestPssLocked(ProcessRecord proc, int procState) {
15190        if (mPendingPssProcesses.contains(proc)) {
15191            return;
15192        }
15193        if (mPendingPssProcesses.size() == 0) {
15194            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15195        }
15196        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15197        proc.pssProcState = procState;
15198        mPendingPssProcesses.add(proc);
15199    }
15200
15201    /**
15202     * Schedule PSS collection of all processes.
15203     */
15204    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15205        if (!always) {
15206            if (now < (mLastFullPssTime +
15207                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15208                return;
15209            }
15210        }
15211        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15212        mLastFullPssTime = now;
15213        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15214        mPendingPssProcesses.clear();
15215        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15216            ProcessRecord app = mLruProcesses.get(i);
15217            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15218                app.pssProcState = app.setProcState;
15219                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15220                        mSleeping, now);
15221                mPendingPssProcesses.add(app);
15222            }
15223        }
15224        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15225    }
15226
15227    /**
15228     * Ask a given process to GC right now.
15229     */
15230    final void performAppGcLocked(ProcessRecord app) {
15231        try {
15232            app.lastRequestedGc = SystemClock.uptimeMillis();
15233            if (app.thread != null) {
15234                if (app.reportLowMemory) {
15235                    app.reportLowMemory = false;
15236                    app.thread.scheduleLowMemory();
15237                } else {
15238                    app.thread.processInBackground();
15239                }
15240            }
15241        } catch (Exception e) {
15242            // whatever.
15243        }
15244    }
15245
15246    /**
15247     * Returns true if things are idle enough to perform GCs.
15248     */
15249    private final boolean canGcNowLocked() {
15250        boolean processingBroadcasts = false;
15251        for (BroadcastQueue q : mBroadcastQueues) {
15252            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15253                processingBroadcasts = true;
15254            }
15255        }
15256        return !processingBroadcasts
15257                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15258    }
15259
15260    /**
15261     * Perform GCs on all processes that are waiting for it, but only
15262     * if things are idle.
15263     */
15264    final void performAppGcsLocked() {
15265        final int N = mProcessesToGc.size();
15266        if (N <= 0) {
15267            return;
15268        }
15269        if (canGcNowLocked()) {
15270            while (mProcessesToGc.size() > 0) {
15271                ProcessRecord proc = mProcessesToGc.remove(0);
15272                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15273                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15274                            <= SystemClock.uptimeMillis()) {
15275                        // To avoid spamming the system, we will GC processes one
15276                        // at a time, waiting a few seconds between each.
15277                        performAppGcLocked(proc);
15278                        scheduleAppGcsLocked();
15279                        return;
15280                    } else {
15281                        // It hasn't been long enough since we last GCed this
15282                        // process...  put it in the list to wait for its time.
15283                        addProcessToGcListLocked(proc);
15284                        break;
15285                    }
15286                }
15287            }
15288
15289            scheduleAppGcsLocked();
15290        }
15291    }
15292
15293    /**
15294     * If all looks good, perform GCs on all processes waiting for them.
15295     */
15296    final void performAppGcsIfAppropriateLocked() {
15297        if (canGcNowLocked()) {
15298            performAppGcsLocked();
15299            return;
15300        }
15301        // Still not idle, wait some more.
15302        scheduleAppGcsLocked();
15303    }
15304
15305    /**
15306     * Schedule the execution of all pending app GCs.
15307     */
15308    final void scheduleAppGcsLocked() {
15309        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15310
15311        if (mProcessesToGc.size() > 0) {
15312            // Schedule a GC for the time to the next process.
15313            ProcessRecord proc = mProcessesToGc.get(0);
15314            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15315
15316            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15317            long now = SystemClock.uptimeMillis();
15318            if (when < (now+GC_TIMEOUT)) {
15319                when = now + GC_TIMEOUT;
15320            }
15321            mHandler.sendMessageAtTime(msg, when);
15322        }
15323    }
15324
15325    /**
15326     * Add a process to the array of processes waiting to be GCed.  Keeps the
15327     * list in sorted order by the last GC time.  The process can't already be
15328     * on the list.
15329     */
15330    final void addProcessToGcListLocked(ProcessRecord proc) {
15331        boolean added = false;
15332        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15333            if (mProcessesToGc.get(i).lastRequestedGc <
15334                    proc.lastRequestedGc) {
15335                added = true;
15336                mProcessesToGc.add(i+1, proc);
15337                break;
15338            }
15339        }
15340        if (!added) {
15341            mProcessesToGc.add(0, proc);
15342        }
15343    }
15344
15345    /**
15346     * Set up to ask a process to GC itself.  This will either do it
15347     * immediately, or put it on the list of processes to gc the next
15348     * time things are idle.
15349     */
15350    final void scheduleAppGcLocked(ProcessRecord app) {
15351        long now = SystemClock.uptimeMillis();
15352        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15353            return;
15354        }
15355        if (!mProcessesToGc.contains(app)) {
15356            addProcessToGcListLocked(app);
15357            scheduleAppGcsLocked();
15358        }
15359    }
15360
15361    final void checkExcessivePowerUsageLocked(boolean doKills) {
15362        updateCpuStatsNow();
15363
15364        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15365        boolean doWakeKills = doKills;
15366        boolean doCpuKills = doKills;
15367        if (mLastPowerCheckRealtime == 0) {
15368            doWakeKills = false;
15369        }
15370        if (mLastPowerCheckUptime == 0) {
15371            doCpuKills = false;
15372        }
15373        if (stats.isScreenOn()) {
15374            doWakeKills = false;
15375        }
15376        final long curRealtime = SystemClock.elapsedRealtime();
15377        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15378        final long curUptime = SystemClock.uptimeMillis();
15379        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15380        mLastPowerCheckRealtime = curRealtime;
15381        mLastPowerCheckUptime = curUptime;
15382        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15383            doWakeKills = false;
15384        }
15385        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15386            doCpuKills = false;
15387        }
15388        int i = mLruProcesses.size();
15389        while (i > 0) {
15390            i--;
15391            ProcessRecord app = mLruProcesses.get(i);
15392            if (!app.keeping) {
15393                long wtime;
15394                synchronized (stats) {
15395                    wtime = stats.getProcessWakeTime(app.info.uid,
15396                            app.pid, curRealtime);
15397                }
15398                long wtimeUsed = wtime - app.lastWakeTime;
15399                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15400                if (DEBUG_POWER) {
15401                    StringBuilder sb = new StringBuilder(128);
15402                    sb.append("Wake for ");
15403                    app.toShortString(sb);
15404                    sb.append(": over ");
15405                    TimeUtils.formatDuration(realtimeSince, sb);
15406                    sb.append(" used ");
15407                    TimeUtils.formatDuration(wtimeUsed, sb);
15408                    sb.append(" (");
15409                    sb.append((wtimeUsed*100)/realtimeSince);
15410                    sb.append("%)");
15411                    Slog.i(TAG, sb.toString());
15412                    sb.setLength(0);
15413                    sb.append("CPU for ");
15414                    app.toShortString(sb);
15415                    sb.append(": over ");
15416                    TimeUtils.formatDuration(uptimeSince, sb);
15417                    sb.append(" used ");
15418                    TimeUtils.formatDuration(cputimeUsed, sb);
15419                    sb.append(" (");
15420                    sb.append((cputimeUsed*100)/uptimeSince);
15421                    sb.append("%)");
15422                    Slog.i(TAG, sb.toString());
15423                }
15424                // If a process has held a wake lock for more
15425                // than 50% of the time during this period,
15426                // that sounds bad.  Kill!
15427                if (doWakeKills && realtimeSince > 0
15428                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15429                    synchronized (stats) {
15430                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15431                                realtimeSince, wtimeUsed);
15432                    }
15433                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15434                            + " during " + realtimeSince);
15435                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15436                } else if (doCpuKills && uptimeSince > 0
15437                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15438                    synchronized (stats) {
15439                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15440                                uptimeSince, cputimeUsed);
15441                    }
15442                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15443                            + " during " + uptimeSince);
15444                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15445                } else {
15446                    app.lastWakeTime = wtime;
15447                    app.lastCpuTime = app.curCpuTime;
15448                }
15449            }
15450        }
15451    }
15452
15453    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15454            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15455        boolean success = true;
15456
15457        if (app.curRawAdj != app.setRawAdj) {
15458            if (wasKeeping && !app.keeping) {
15459                // This app is no longer something we want to keep.  Note
15460                // its current wake lock time to later know to kill it if
15461                // it is not behaving well.
15462                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15463                synchronized (stats) {
15464                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15465                            app.pid, SystemClock.elapsedRealtime());
15466                }
15467                app.lastCpuTime = app.curCpuTime;
15468            }
15469
15470            app.setRawAdj = app.curRawAdj;
15471        }
15472
15473        if (app.curAdj != app.setAdj) {
15474            ProcessList.setOomAdj(app.pid, app.curAdj);
15475            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15476                TAG, "Set " + app.pid + " " + app.processName +
15477                " adj " + app.curAdj + ": " + app.adjType);
15478            app.setAdj = app.curAdj;
15479        }
15480
15481        if (app.setSchedGroup != app.curSchedGroup) {
15482            app.setSchedGroup = app.curSchedGroup;
15483            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15484                    "Setting process group of " + app.processName
15485                    + " to " + app.curSchedGroup);
15486            if (app.waitingToKill != null &&
15487                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15488                killUnneededProcessLocked(app, app.waitingToKill);
15489                success = false;
15490            } else {
15491                if (true) {
15492                    long oldId = Binder.clearCallingIdentity();
15493                    try {
15494                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15495                    } catch (Exception e) {
15496                        Slog.w(TAG, "Failed setting process group of " + app.pid
15497                                + " to " + app.curSchedGroup);
15498                        e.printStackTrace();
15499                    } finally {
15500                        Binder.restoreCallingIdentity(oldId);
15501                    }
15502                } else {
15503                    if (app.thread != null) {
15504                        try {
15505                            app.thread.setSchedulingGroup(app.curSchedGroup);
15506                        } catch (RemoteException e) {
15507                        }
15508                    }
15509                }
15510                Process.setSwappiness(app.pid,
15511                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15512            }
15513        }
15514        if (app.repProcState != app.curProcState) {
15515            app.repProcState = app.curProcState;
15516            if (!reportingProcessState && app.thread != null) {
15517                try {
15518                    if (false) {
15519                        //RuntimeException h = new RuntimeException("here");
15520                        Slog.i(TAG, "Sending new process state " + app.repProcState
15521                                + " to " + app /*, h*/);
15522                    }
15523                    app.thread.setProcessState(app.repProcState);
15524                } catch (RemoteException e) {
15525                }
15526            }
15527        }
15528        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15529                app.setProcState)) {
15530            app.lastStateTime = now;
15531            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15532                    mSleeping, now);
15533            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15534                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15535                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15536                    + (app.nextPssTime-now) + ": " + app);
15537        } else {
15538            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15539                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15540                requestPssLocked(app, app.setProcState);
15541                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15542                        mSleeping, now);
15543            } else if (false && DEBUG_PSS) {
15544                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15545            }
15546        }
15547        if (app.setProcState != app.curProcState) {
15548            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15549                    "Proc state change of " + app.processName
15550                    + " to " + app.curProcState);
15551            app.setProcState = app.curProcState;
15552            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15553                app.notCachedSinceIdle = false;
15554            }
15555            if (!doingAll) {
15556                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15557            } else {
15558                app.procStateChanged = true;
15559            }
15560        }
15561        return success;
15562    }
15563
15564    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15565        if (proc.thread != null && proc.baseProcessTracker != null) {
15566            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15567        }
15568    }
15569
15570    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15571            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15572        if (app.thread == null) {
15573            return false;
15574        }
15575
15576        final boolean wasKeeping = app.keeping;
15577
15578        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15579
15580        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15581                reportingProcessState, now);
15582    }
15583
15584    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15585            boolean oomAdj) {
15586        if (isForeground != proc.foregroundServices) {
15587            proc.foregroundServices = isForeground;
15588            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15589                    proc.info.uid);
15590            if (isForeground) {
15591                if (curProcs == null) {
15592                    curProcs = new ArrayList<ProcessRecord>();
15593                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15594                }
15595                if (!curProcs.contains(proc)) {
15596                    curProcs.add(proc);
15597                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15598                            proc.info.packageName, proc.info.uid);
15599                }
15600            } else {
15601                if (curProcs != null) {
15602                    if (curProcs.remove(proc)) {
15603                        mBatteryStatsService.noteEvent(
15604                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15605                                proc.info.packageName, proc.info.uid);
15606                        if (curProcs.size() <= 0) {
15607                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15608                        }
15609                    }
15610                }
15611            }
15612            if (oomAdj) {
15613                updateOomAdjLocked();
15614            }
15615        }
15616    }
15617
15618    private final ActivityRecord resumedAppLocked() {
15619        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15620        String pkg;
15621        int uid;
15622        if (act != null && !act.sleeping) {
15623            pkg = act.packageName;
15624            uid = act.info.applicationInfo.uid;
15625        } else {
15626            pkg = null;
15627            uid = -1;
15628        }
15629        // Has the UID or resumed package name changed?
15630        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15631                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15632            if (mCurResumedPackage != null) {
15633                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15634                        mCurResumedPackage, mCurResumedUid);
15635            }
15636            mCurResumedPackage = pkg;
15637            mCurResumedUid = uid;
15638            if (mCurResumedPackage != null) {
15639                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15640                        mCurResumedPackage, mCurResumedUid);
15641            }
15642        }
15643        return act;
15644    }
15645
15646    final boolean updateOomAdjLocked(ProcessRecord app) {
15647        return updateOomAdjLocked(app, false);
15648    }
15649
15650    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15651        final ActivityRecord TOP_ACT = resumedAppLocked();
15652        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15653        final boolean wasCached = app.cached;
15654
15655        mAdjSeq++;
15656
15657        // This is the desired cached adjusment we want to tell it to use.
15658        // If our app is currently cached, we know it, and that is it.  Otherwise,
15659        // we don't know it yet, and it needs to now be cached we will then
15660        // need to do a complete oom adj.
15661        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15662                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15663        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15664                SystemClock.uptimeMillis());
15665        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15666            // Changed to/from cached state, so apps after it in the LRU
15667            // list may also be changed.
15668            updateOomAdjLocked();
15669        }
15670        return success;
15671    }
15672
15673    final void updateOomAdjLocked() {
15674        final ActivityRecord TOP_ACT = resumedAppLocked();
15675        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15676        final long now = SystemClock.uptimeMillis();
15677        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15678        final int N = mLruProcesses.size();
15679
15680        if (false) {
15681            RuntimeException e = new RuntimeException();
15682            e.fillInStackTrace();
15683            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15684        }
15685
15686        mAdjSeq++;
15687        mNewNumServiceProcs = 0;
15688        mNewNumAServiceProcs = 0;
15689
15690        final int emptyProcessLimit;
15691        final int cachedProcessLimit;
15692        if (mProcessLimit <= 0) {
15693            emptyProcessLimit = cachedProcessLimit = 0;
15694        } else if (mProcessLimit == 1) {
15695            emptyProcessLimit = 1;
15696            cachedProcessLimit = 0;
15697        } else {
15698            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15699            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15700        }
15701
15702        // Let's determine how many processes we have running vs.
15703        // how many slots we have for background processes; we may want
15704        // to put multiple processes in a slot of there are enough of
15705        // them.
15706        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15707                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15708        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15709        if (numEmptyProcs > cachedProcessLimit) {
15710            // If there are more empty processes than our limit on cached
15711            // processes, then use the cached process limit for the factor.
15712            // This ensures that the really old empty processes get pushed
15713            // down to the bottom, so if we are running low on memory we will
15714            // have a better chance at keeping around more cached processes
15715            // instead of a gazillion empty processes.
15716            numEmptyProcs = cachedProcessLimit;
15717        }
15718        int emptyFactor = numEmptyProcs/numSlots;
15719        if (emptyFactor < 1) emptyFactor = 1;
15720        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15721        if (cachedFactor < 1) cachedFactor = 1;
15722        int stepCached = 0;
15723        int stepEmpty = 0;
15724        int numCached = 0;
15725        int numEmpty = 0;
15726        int numTrimming = 0;
15727
15728        mNumNonCachedProcs = 0;
15729        mNumCachedHiddenProcs = 0;
15730
15731        // First update the OOM adjustment for each of the
15732        // application processes based on their current state.
15733        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15734        int nextCachedAdj = curCachedAdj+1;
15735        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15736        int nextEmptyAdj = curEmptyAdj+2;
15737        for (int i=N-1; i>=0; i--) {
15738            ProcessRecord app = mLruProcesses.get(i);
15739            if (!app.killedByAm && app.thread != null) {
15740                app.procStateChanged = false;
15741                final boolean wasKeeping = app.keeping;
15742                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15743
15744                // If we haven't yet assigned the final cached adj
15745                // to the process, do that now.
15746                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15747                    switch (app.curProcState) {
15748                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15749                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15750                            // This process is a cached process holding activities...
15751                            // assign it the next cached value for that type, and then
15752                            // step that cached level.
15753                            app.curRawAdj = curCachedAdj;
15754                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15755                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15756                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15757                                    + ")");
15758                            if (curCachedAdj != nextCachedAdj) {
15759                                stepCached++;
15760                                if (stepCached >= cachedFactor) {
15761                                    stepCached = 0;
15762                                    curCachedAdj = nextCachedAdj;
15763                                    nextCachedAdj += 2;
15764                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15765                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15766                                    }
15767                                }
15768                            }
15769                            break;
15770                        default:
15771                            // For everything else, assign next empty cached process
15772                            // level and bump that up.  Note that this means that
15773                            // long-running services that have dropped down to the
15774                            // cached level will be treated as empty (since their process
15775                            // state is still as a service), which is what we want.
15776                            app.curRawAdj = curEmptyAdj;
15777                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15778                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15779                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15780                                    + ")");
15781                            if (curEmptyAdj != nextEmptyAdj) {
15782                                stepEmpty++;
15783                                if (stepEmpty >= emptyFactor) {
15784                                    stepEmpty = 0;
15785                                    curEmptyAdj = nextEmptyAdj;
15786                                    nextEmptyAdj += 2;
15787                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15788                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15789                                    }
15790                                }
15791                            }
15792                            break;
15793                    }
15794                }
15795
15796                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15797
15798                // Count the number of process types.
15799                switch (app.curProcState) {
15800                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15801                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15802                        mNumCachedHiddenProcs++;
15803                        numCached++;
15804                        if (numCached > cachedProcessLimit) {
15805                            killUnneededProcessLocked(app, "cached #" + numCached);
15806                        }
15807                        break;
15808                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15809                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15810                                && app.lastActivityTime < oldTime) {
15811                            killUnneededProcessLocked(app, "empty for "
15812                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15813                                    / 1000) + "s");
15814                        } else {
15815                            numEmpty++;
15816                            if (numEmpty > emptyProcessLimit) {
15817                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15818                            }
15819                        }
15820                        break;
15821                    default:
15822                        mNumNonCachedProcs++;
15823                        break;
15824                }
15825
15826                if (app.isolated && app.services.size() <= 0) {
15827                    // If this is an isolated process, and there are no
15828                    // services running in it, then the process is no longer
15829                    // needed.  We agressively kill these because we can by
15830                    // definition not re-use the same process again, and it is
15831                    // good to avoid having whatever code was running in them
15832                    // left sitting around after no longer needed.
15833                    killUnneededProcessLocked(app, "isolated not needed");
15834                }
15835
15836                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15837                        && !app.killedByAm) {
15838                    numTrimming++;
15839                }
15840            }
15841        }
15842
15843        mNumServiceProcs = mNewNumServiceProcs;
15844
15845        // Now determine the memory trimming level of background processes.
15846        // Unfortunately we need to start at the back of the list to do this
15847        // properly.  We only do this if the number of background apps we
15848        // are managing to keep around is less than half the maximum we desire;
15849        // if we are keeping a good number around, we'll let them use whatever
15850        // memory they want.
15851        final int numCachedAndEmpty = numCached + numEmpty;
15852        int memFactor;
15853        if (numCached <= ProcessList.TRIM_CACHED_APPS
15854                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15855            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15856                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15857            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15858                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15859            } else {
15860                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15861            }
15862        } else {
15863            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15864        }
15865        // We always allow the memory level to go up (better).  We only allow it to go
15866        // down if we are in a state where that is allowed, *and* the total number of processes
15867        // has gone down since last time.
15868        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15869                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15870                + " last=" + mLastNumProcesses);
15871        if (memFactor > mLastMemoryLevel) {
15872            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15873                memFactor = mLastMemoryLevel;
15874                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15875            }
15876        }
15877        mLastMemoryLevel = memFactor;
15878        mLastNumProcesses = mLruProcesses.size();
15879        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15880        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15881        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15882            if (mLowRamStartTime == 0) {
15883                mLowRamStartTime = now;
15884            }
15885            int step = 0;
15886            int fgTrimLevel;
15887            switch (memFactor) {
15888                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15889                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15890                    break;
15891                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15892                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15893                    break;
15894                default:
15895                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15896                    break;
15897            }
15898            int factor = numTrimming/3;
15899            int minFactor = 2;
15900            if (mHomeProcess != null) minFactor++;
15901            if (mPreviousProcess != null) minFactor++;
15902            if (factor < minFactor) factor = minFactor;
15903            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15904            for (int i=N-1; i>=0; i--) {
15905                ProcessRecord app = mLruProcesses.get(i);
15906                if (allChanged || app.procStateChanged) {
15907                    setProcessTrackerState(app, trackerMemFactor, now);
15908                    app.procStateChanged = false;
15909                }
15910                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15911                        && !app.killedByAm) {
15912                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15913                        try {
15914                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15915                                    "Trimming memory of " + app.processName
15916                                    + " to " + curLevel);
15917                            app.thread.scheduleTrimMemory(curLevel);
15918                        } catch (RemoteException e) {
15919                        }
15920                        if (false) {
15921                            // For now we won't do this; our memory trimming seems
15922                            // to be good enough at this point that destroying
15923                            // activities causes more harm than good.
15924                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15925                                    && app != mHomeProcess && app != mPreviousProcess) {
15926                                // Need to do this on its own message because the stack may not
15927                                // be in a consistent state at this point.
15928                                // For these apps we will also finish their activities
15929                                // to help them free memory.
15930                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15931                            }
15932                        }
15933                    }
15934                    app.trimMemoryLevel = curLevel;
15935                    step++;
15936                    if (step >= factor) {
15937                        step = 0;
15938                        switch (curLevel) {
15939                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15940                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15941                                break;
15942                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15943                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15944                                break;
15945                        }
15946                    }
15947                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15948                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15949                            && app.thread != null) {
15950                        try {
15951                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15952                                    "Trimming memory of heavy-weight " + app.processName
15953                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15954                            app.thread.scheduleTrimMemory(
15955                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15956                        } catch (RemoteException e) {
15957                        }
15958                    }
15959                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15960                } else {
15961                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15962                            || app.systemNoUi) && app.pendingUiClean) {
15963                        // If this application is now in the background and it
15964                        // had done UI, then give it the special trim level to
15965                        // have it free UI resources.
15966                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15967                        if (app.trimMemoryLevel < level && app.thread != null) {
15968                            try {
15969                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15970                                        "Trimming memory of bg-ui " + app.processName
15971                                        + " to " + level);
15972                                app.thread.scheduleTrimMemory(level);
15973                            } catch (RemoteException e) {
15974                            }
15975                        }
15976                        app.pendingUiClean = false;
15977                    }
15978                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15979                        try {
15980                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15981                                    "Trimming memory of fg " + app.processName
15982                                    + " to " + fgTrimLevel);
15983                            app.thread.scheduleTrimMemory(fgTrimLevel);
15984                        } catch (RemoteException e) {
15985                        }
15986                    }
15987                    app.trimMemoryLevel = fgTrimLevel;
15988                }
15989            }
15990        } else {
15991            if (mLowRamStartTime != 0) {
15992                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15993                mLowRamStartTime = 0;
15994            }
15995            for (int i=N-1; i>=0; i--) {
15996                ProcessRecord app = mLruProcesses.get(i);
15997                if (allChanged || app.procStateChanged) {
15998                    setProcessTrackerState(app, trackerMemFactor, now);
15999                    app.procStateChanged = false;
16000                }
16001                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16002                        || app.systemNoUi) && app.pendingUiClean) {
16003                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16004                            && app.thread != null) {
16005                        try {
16006                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16007                                    "Trimming memory of ui hidden " + app.processName
16008                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16009                            app.thread.scheduleTrimMemory(
16010                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16011                        } catch (RemoteException e) {
16012                        }
16013                    }
16014                    app.pendingUiClean = false;
16015                }
16016                app.trimMemoryLevel = 0;
16017            }
16018        }
16019
16020        if (mAlwaysFinishActivities) {
16021            // Need to do this on its own message because the stack may not
16022            // be in a consistent state at this point.
16023            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16024        }
16025
16026        if (allChanged) {
16027            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16028        }
16029
16030        if (mProcessStats.shouldWriteNowLocked(now)) {
16031            mHandler.post(new Runnable() {
16032                @Override public void run() {
16033                    synchronized (ActivityManagerService.this) {
16034                        mProcessStats.writeStateAsyncLocked();
16035                    }
16036                }
16037            });
16038        }
16039
16040        if (DEBUG_OOM_ADJ) {
16041            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16042        }
16043    }
16044
16045    final void trimApplications() {
16046        synchronized (this) {
16047            int i;
16048
16049            // First remove any unused application processes whose package
16050            // has been removed.
16051            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16052                final ProcessRecord app = mRemovedProcesses.get(i);
16053                if (app.activities.size() == 0
16054                        && app.curReceiver == null && app.services.size() == 0) {
16055                    Slog.i(
16056                        TAG, "Exiting empty application process "
16057                        + app.processName + " ("
16058                        + (app.thread != null ? app.thread.asBinder() : null)
16059                        + ")\n");
16060                    if (app.pid > 0 && app.pid != MY_PID) {
16061                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16062                                app.processName, app.setAdj, "empty");
16063                        app.killedByAm = true;
16064                        Process.killProcessQuiet(app.pid);
16065                    } else {
16066                        try {
16067                            app.thread.scheduleExit();
16068                        } catch (Exception e) {
16069                            // Ignore exceptions.
16070                        }
16071                    }
16072                    cleanUpApplicationRecordLocked(app, false, true, -1);
16073                    mRemovedProcesses.remove(i);
16074
16075                    if (app.persistent) {
16076                        if (app.persistent) {
16077                            addAppLocked(app.info, false);
16078                        }
16079                    }
16080                }
16081            }
16082
16083            // Now update the oom adj for all processes.
16084            updateOomAdjLocked();
16085        }
16086    }
16087
16088    /** This method sends the specified signal to each of the persistent apps */
16089    public void signalPersistentProcesses(int sig) throws RemoteException {
16090        if (sig != Process.SIGNAL_USR1) {
16091            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16092        }
16093
16094        synchronized (this) {
16095            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16096                    != PackageManager.PERMISSION_GRANTED) {
16097                throw new SecurityException("Requires permission "
16098                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16099            }
16100
16101            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16102                ProcessRecord r = mLruProcesses.get(i);
16103                if (r.thread != null && r.persistent) {
16104                    Process.sendSignal(r.pid, sig);
16105                }
16106            }
16107        }
16108    }
16109
16110    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16111        if (proc == null || proc == mProfileProc) {
16112            proc = mProfileProc;
16113            path = mProfileFile;
16114            profileType = mProfileType;
16115            clearProfilerLocked();
16116        }
16117        if (proc == null) {
16118            return;
16119        }
16120        try {
16121            proc.thread.profilerControl(false, path, null, profileType);
16122        } catch (RemoteException e) {
16123            throw new IllegalStateException("Process disappeared");
16124        }
16125    }
16126
16127    private void clearProfilerLocked() {
16128        if (mProfileFd != null) {
16129            try {
16130                mProfileFd.close();
16131            } catch (IOException e) {
16132            }
16133        }
16134        mProfileApp = null;
16135        mProfileProc = null;
16136        mProfileFile = null;
16137        mProfileType = 0;
16138        mAutoStopProfiler = false;
16139    }
16140
16141    public boolean profileControl(String process, int userId, boolean start,
16142            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16143
16144        try {
16145            synchronized (this) {
16146                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16147                // its own permission.
16148                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16149                        != PackageManager.PERMISSION_GRANTED) {
16150                    throw new SecurityException("Requires permission "
16151                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16152                }
16153
16154                if (start && fd == null) {
16155                    throw new IllegalArgumentException("null fd");
16156                }
16157
16158                ProcessRecord proc = null;
16159                if (process != null) {
16160                    proc = findProcessLocked(process, userId, "profileControl");
16161                }
16162
16163                if (start && (proc == null || proc.thread == null)) {
16164                    throw new IllegalArgumentException("Unknown process: " + process);
16165                }
16166
16167                if (start) {
16168                    stopProfilerLocked(null, null, 0);
16169                    setProfileApp(proc.info, proc.processName, path, fd, false);
16170                    mProfileProc = proc;
16171                    mProfileType = profileType;
16172                    try {
16173                        fd = fd.dup();
16174                    } catch (IOException e) {
16175                        fd = null;
16176                    }
16177                    proc.thread.profilerControl(start, path, fd, profileType);
16178                    fd = null;
16179                    mProfileFd = null;
16180                } else {
16181                    stopProfilerLocked(proc, path, profileType);
16182                    if (fd != null) {
16183                        try {
16184                            fd.close();
16185                        } catch (IOException e) {
16186                        }
16187                    }
16188                }
16189
16190                return true;
16191            }
16192        } catch (RemoteException e) {
16193            throw new IllegalStateException("Process disappeared");
16194        } finally {
16195            if (fd != null) {
16196                try {
16197                    fd.close();
16198                } catch (IOException e) {
16199                }
16200            }
16201        }
16202    }
16203
16204    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16205        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16206                userId, true, true, callName, null);
16207        ProcessRecord proc = null;
16208        try {
16209            int pid = Integer.parseInt(process);
16210            synchronized (mPidsSelfLocked) {
16211                proc = mPidsSelfLocked.get(pid);
16212            }
16213        } catch (NumberFormatException e) {
16214        }
16215
16216        if (proc == null) {
16217            ArrayMap<String, SparseArray<ProcessRecord>> all
16218                    = mProcessNames.getMap();
16219            SparseArray<ProcessRecord> procs = all.get(process);
16220            if (procs != null && procs.size() > 0) {
16221                proc = procs.valueAt(0);
16222                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16223                    for (int i=1; i<procs.size(); i++) {
16224                        ProcessRecord thisProc = procs.valueAt(i);
16225                        if (thisProc.userId == userId) {
16226                            proc = thisProc;
16227                            break;
16228                        }
16229                    }
16230                }
16231            }
16232        }
16233
16234        return proc;
16235    }
16236
16237    public boolean dumpHeap(String process, int userId, boolean managed,
16238            String path, ParcelFileDescriptor fd) throws RemoteException {
16239
16240        try {
16241            synchronized (this) {
16242                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16243                // its own permission (same as profileControl).
16244                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16245                        != PackageManager.PERMISSION_GRANTED) {
16246                    throw new SecurityException("Requires permission "
16247                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16248                }
16249
16250                if (fd == null) {
16251                    throw new IllegalArgumentException("null fd");
16252                }
16253
16254                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16255                if (proc == null || proc.thread == null) {
16256                    throw new IllegalArgumentException("Unknown process: " + process);
16257                }
16258
16259                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16260                if (!isDebuggable) {
16261                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16262                        throw new SecurityException("Process not debuggable: " + proc);
16263                    }
16264                }
16265
16266                proc.thread.dumpHeap(managed, path, fd);
16267                fd = null;
16268                return true;
16269            }
16270        } catch (RemoteException e) {
16271            throw new IllegalStateException("Process disappeared");
16272        } finally {
16273            if (fd != null) {
16274                try {
16275                    fd.close();
16276                } catch (IOException e) {
16277                }
16278            }
16279        }
16280    }
16281
16282    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16283    public void monitor() {
16284        synchronized (this) { }
16285    }
16286
16287    void onCoreSettingsChange(Bundle settings) {
16288        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16289            ProcessRecord processRecord = mLruProcesses.get(i);
16290            try {
16291                if (processRecord.thread != null) {
16292                    processRecord.thread.setCoreSettings(settings);
16293                }
16294            } catch (RemoteException re) {
16295                /* ignore */
16296            }
16297        }
16298    }
16299
16300    // Multi-user methods
16301
16302    /**
16303     * Start user, if its not already running, but don't bring it to foreground.
16304     */
16305    @Override
16306    public boolean startUserInBackground(final int userId) {
16307        return startUser(userId, /* foreground */ false);
16308    }
16309
16310    /**
16311     * Refreshes the list of users related to the current user when either a
16312     * user switch happens or when a new related user is started in the
16313     * background.
16314     */
16315    private void updateRelatedUserIdsLocked() {
16316        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16317        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16318        for (int i = 0; i < relatedUserIds.length; i++) {
16319            relatedUserIds[i] = relatedUsers.get(i).id;
16320        }
16321        mRelatedUserIds = relatedUserIds;
16322    }
16323
16324    private Set getRelatedUsersLocked(int userId) {
16325        Set userIds = new HashSet<Integer>();
16326        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId);
16327        for (UserInfo user : relatedUsers) {
16328            userIds.add(Integer.valueOf(user.id));
16329        }
16330        return userIds;
16331    }
16332
16333    @Override
16334    public boolean switchUser(final int userId) {
16335        return startUser(userId, /* foregound */ true);
16336    }
16337
16338    private boolean startUser(final int userId, boolean foreground) {
16339        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16340                != PackageManager.PERMISSION_GRANTED) {
16341            String msg = "Permission Denial: switchUser() from pid="
16342                    + Binder.getCallingPid()
16343                    + ", uid=" + Binder.getCallingUid()
16344                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16345            Slog.w(TAG, msg);
16346            throw new SecurityException(msg);
16347        }
16348
16349        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16350
16351        final long ident = Binder.clearCallingIdentity();
16352        try {
16353            synchronized (this) {
16354                final int oldUserId = mCurrentUserId;
16355                if (oldUserId == userId) {
16356                    return true;
16357                }
16358
16359                mStackSupervisor.setLockTaskModeLocked(null);
16360
16361                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16362                if (userInfo == null) {
16363                    Slog.w(TAG, "No user info for user #" + userId);
16364                    return false;
16365                }
16366
16367                if (foreground) {
16368                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16369                            R.anim.screen_user_enter);
16370                }
16371
16372                boolean needStart = false;
16373
16374                // If the user we are switching to is not currently started, then
16375                // we need to start it now.
16376                if (mStartedUsers.get(userId) == null) {
16377                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16378                    updateStartedUserArrayLocked();
16379                    needStart = true;
16380                }
16381
16382                final Integer userIdInt = Integer.valueOf(userId);
16383                mUserLru.remove(userIdInt);
16384                mUserLru.add(userIdInt);
16385
16386                if (foreground) {
16387                    mCurrentUserId = userId;
16388                    updateRelatedUserIdsLocked();
16389                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16390                    // Once the internal notion of the active user has switched, we lock the device
16391                    // with the option to show the user switcher on the keyguard.
16392                    mWindowManager.lockNow(null);
16393                } else {
16394                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16395                    updateRelatedUserIdsLocked();
16396                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16397                    mUserLru.remove(currentUserIdInt);
16398                    mUserLru.add(currentUserIdInt);
16399                }
16400
16401                final UserStartedState uss = mStartedUsers.get(userId);
16402
16403                // Make sure user is in the started state.  If it is currently
16404                // stopping, we need to knock that off.
16405                if (uss.mState == UserStartedState.STATE_STOPPING) {
16406                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16407                    // so we can just fairly silently bring the user back from
16408                    // the almost-dead.
16409                    uss.mState = UserStartedState.STATE_RUNNING;
16410                    updateStartedUserArrayLocked();
16411                    needStart = true;
16412                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16413                    // This means ACTION_SHUTDOWN has been sent, so we will
16414                    // need to treat this as a new boot of the user.
16415                    uss.mState = UserStartedState.STATE_BOOTING;
16416                    updateStartedUserArrayLocked();
16417                    needStart = true;
16418                }
16419
16420                if (foreground) {
16421                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16422                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16423                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16424                            oldUserId, userId, uss));
16425                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16426                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16427                }
16428
16429                if (needStart) {
16430                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16431                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16432                            | Intent.FLAG_RECEIVER_FOREGROUND);
16433                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16434                    broadcastIntentLocked(null, null, intent,
16435                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16436                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16437                }
16438
16439                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16440                    if (userId != 0) {
16441                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16442                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16443                        broadcastIntentLocked(null, null, intent, null,
16444                                new IIntentReceiver.Stub() {
16445                                    public void performReceive(Intent intent, int resultCode,
16446                                            String data, Bundle extras, boolean ordered,
16447                                            boolean sticky, int sendingUser) {
16448                                        userInitialized(uss, userId);
16449                                    }
16450                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16451                                true, false, MY_PID, Process.SYSTEM_UID,
16452                                userId);
16453                        uss.initializing = true;
16454                    } else {
16455                        getUserManagerLocked().makeInitialized(userInfo.id);
16456                    }
16457                }
16458
16459                if (foreground) {
16460                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16461                    if (homeInFront) {
16462                        startHomeActivityLocked(userId);
16463                    } else {
16464                        mStackSupervisor.resumeTopActivitiesLocked();
16465                    }
16466                    EventLogTags.writeAmSwitchUser(userId);
16467                    getUserManagerLocked().userForeground(userId);
16468                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16469                }
16470
16471                if (needStart) {
16472                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16473                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16474                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16475                    broadcastIntentLocked(null, null, intent,
16476                            null, new IIntentReceiver.Stub() {
16477                                @Override
16478                                public void performReceive(Intent intent, int resultCode, String data,
16479                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16480                                        throws RemoteException {
16481                                }
16482                            }, 0, null, null,
16483                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16484                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16485                }
16486            }
16487        } finally {
16488            Binder.restoreCallingIdentity(ident);
16489        }
16490
16491        return true;
16492    }
16493
16494    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16495        long ident = Binder.clearCallingIdentity();
16496        try {
16497            Intent intent;
16498            if (oldUserId >= 0) {
16499                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16500                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16501                        | Intent.FLAG_RECEIVER_FOREGROUND);
16502                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16503                broadcastIntentLocked(null, null, intent,
16504                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16505                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16506            }
16507            if (newUserId >= 0) {
16508                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16509                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16510                        | Intent.FLAG_RECEIVER_FOREGROUND);
16511                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16512                broadcastIntentLocked(null, null, intent,
16513                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16514                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16515                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16516                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16517                        | Intent.FLAG_RECEIVER_FOREGROUND);
16518                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16519                broadcastIntentLocked(null, null, intent,
16520                        null, null, 0, null, null,
16521                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16522                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16523            }
16524        } finally {
16525            Binder.restoreCallingIdentity(ident);
16526        }
16527    }
16528
16529    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16530            final int newUserId) {
16531        final int N = mUserSwitchObservers.beginBroadcast();
16532        if (N > 0) {
16533            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16534                int mCount = 0;
16535                @Override
16536                public void sendResult(Bundle data) throws RemoteException {
16537                    synchronized (ActivityManagerService.this) {
16538                        if (mCurUserSwitchCallback == this) {
16539                            mCount++;
16540                            if (mCount == N) {
16541                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16542                            }
16543                        }
16544                    }
16545                }
16546            };
16547            synchronized (this) {
16548                uss.switching = true;
16549                mCurUserSwitchCallback = callback;
16550            }
16551            for (int i=0; i<N; i++) {
16552                try {
16553                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16554                            newUserId, callback);
16555                } catch (RemoteException e) {
16556                }
16557            }
16558        } else {
16559            synchronized (this) {
16560                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16561            }
16562        }
16563        mUserSwitchObservers.finishBroadcast();
16564    }
16565
16566    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16567        synchronized (this) {
16568            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16569            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16570        }
16571    }
16572
16573    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16574        mCurUserSwitchCallback = null;
16575        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16576        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16577                oldUserId, newUserId, uss));
16578    }
16579
16580    void userInitialized(UserStartedState uss, int newUserId) {
16581        completeSwitchAndInitalize(uss, newUserId, true, false);
16582    }
16583
16584    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16585        completeSwitchAndInitalize(uss, newUserId, false, true);
16586    }
16587
16588    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16589            boolean clearInitializing, boolean clearSwitching) {
16590        boolean unfrozen = false;
16591        synchronized (this) {
16592            if (clearInitializing) {
16593                uss.initializing = false;
16594                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16595            }
16596            if (clearSwitching) {
16597                uss.switching = false;
16598            }
16599            if (!uss.switching && !uss.initializing) {
16600                mWindowManager.stopFreezingScreen();
16601                unfrozen = true;
16602            }
16603        }
16604        if (unfrozen) {
16605            final int N = mUserSwitchObservers.beginBroadcast();
16606            for (int i=0; i<N; i++) {
16607                try {
16608                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16609                } catch (RemoteException e) {
16610                }
16611            }
16612            mUserSwitchObservers.finishBroadcast();
16613        }
16614    }
16615
16616    void scheduleStartRelatedUsersLocked() {
16617        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16618            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16619                    DateUtils.SECOND_IN_MILLIS);
16620        }
16621    }
16622
16623    void startRelatedUsersLocked() {
16624        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16625        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16626        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16627        for (UserInfo relatedUser : relatedUsers) {
16628            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16629                toStart.add(relatedUser);
16630            }
16631        }
16632        final int n = toStart.size();
16633        int i = 0;
16634        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16635            startUserInBackground(toStart.get(i).id);
16636        }
16637        if (i < n) {
16638            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16639        }
16640    }
16641
16642    void finishUserSwitch(UserStartedState uss) {
16643        synchronized (this) {
16644            if (uss.mState == UserStartedState.STATE_BOOTING
16645                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16646                uss.mState = UserStartedState.STATE_RUNNING;
16647                final int userId = uss.mHandle.getIdentifier();
16648                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16649                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16650                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16651                broadcastIntentLocked(null, null, intent,
16652                        null, null, 0, null, null,
16653                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16654                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16655            }
16656
16657            startRelatedUsersLocked();
16658
16659            int num = mUserLru.size();
16660            int i = 0;
16661            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16662                Integer oldUserId = mUserLru.get(i);
16663                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16664                if (oldUss == null) {
16665                    // Shouldn't happen, but be sane if it does.
16666                    mUserLru.remove(i);
16667                    num--;
16668                    continue;
16669                }
16670                if (oldUss.mState == UserStartedState.STATE_STOPPING
16671                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16672                    // This user is already stopping, doesn't count.
16673                    num--;
16674                    i++;
16675                    continue;
16676                }
16677                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16678                    // Owner and current can't be stopped, but count as running.
16679                    i++;
16680                    continue;
16681                }
16682                // This is a user to be stopped.
16683                stopUserLocked(oldUserId, null);
16684                num--;
16685                i++;
16686            }
16687        }
16688    }
16689
16690    @Override
16691    public int stopUser(final int userId, final IStopUserCallback callback) {
16692        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16693                != PackageManager.PERMISSION_GRANTED) {
16694            String msg = "Permission Denial: switchUser() from pid="
16695                    + Binder.getCallingPid()
16696                    + ", uid=" + Binder.getCallingUid()
16697                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16698            Slog.w(TAG, msg);
16699            throw new SecurityException(msg);
16700        }
16701        if (userId <= 0) {
16702            throw new IllegalArgumentException("Can't stop primary user " + userId);
16703        }
16704        synchronized (this) {
16705            return stopUserLocked(userId, callback);
16706        }
16707    }
16708
16709    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16710        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16711        if (mCurrentUserId == userId) {
16712            return ActivityManager.USER_OP_IS_CURRENT;
16713        }
16714
16715        final UserStartedState uss = mStartedUsers.get(userId);
16716        if (uss == null) {
16717            // User is not started, nothing to do...  but we do need to
16718            // callback if requested.
16719            if (callback != null) {
16720                mHandler.post(new Runnable() {
16721                    @Override
16722                    public void run() {
16723                        try {
16724                            callback.userStopped(userId);
16725                        } catch (RemoteException e) {
16726                        }
16727                    }
16728                });
16729            }
16730            return ActivityManager.USER_OP_SUCCESS;
16731        }
16732
16733        if (callback != null) {
16734            uss.mStopCallbacks.add(callback);
16735        }
16736
16737        if (uss.mState != UserStartedState.STATE_STOPPING
16738                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16739            uss.mState = UserStartedState.STATE_STOPPING;
16740            updateStartedUserArrayLocked();
16741
16742            long ident = Binder.clearCallingIdentity();
16743            try {
16744                // We are going to broadcast ACTION_USER_STOPPING and then
16745                // once that is done send a final ACTION_SHUTDOWN and then
16746                // stop the user.
16747                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16748                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16749                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16750                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16751                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16752                // This is the result receiver for the final shutdown broadcast.
16753                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16754                    @Override
16755                    public void performReceive(Intent intent, int resultCode, String data,
16756                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16757                        finishUserStop(uss);
16758                    }
16759                };
16760                // This is the result receiver for the initial stopping broadcast.
16761                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16762                    @Override
16763                    public void performReceive(Intent intent, int resultCode, String data,
16764                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16765                        // On to the next.
16766                        synchronized (ActivityManagerService.this) {
16767                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16768                                // Whoops, we are being started back up.  Abort, abort!
16769                                return;
16770                            }
16771                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16772                        }
16773                        broadcastIntentLocked(null, null, shutdownIntent,
16774                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16775                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16776                    }
16777                };
16778                // Kick things off.
16779                broadcastIntentLocked(null, null, stoppingIntent,
16780                        null, stoppingReceiver, 0, null, null,
16781                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16782                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16783            } finally {
16784                Binder.restoreCallingIdentity(ident);
16785            }
16786        }
16787
16788        return ActivityManager.USER_OP_SUCCESS;
16789    }
16790
16791    void finishUserStop(UserStartedState uss) {
16792        final int userId = uss.mHandle.getIdentifier();
16793        boolean stopped;
16794        ArrayList<IStopUserCallback> callbacks;
16795        synchronized (this) {
16796            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16797            if (mStartedUsers.get(userId) != uss) {
16798                stopped = false;
16799            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16800                stopped = false;
16801            } else {
16802                stopped = true;
16803                // User can no longer run.
16804                mStartedUsers.remove(userId);
16805                mUserLru.remove(Integer.valueOf(userId));
16806                updateStartedUserArrayLocked();
16807
16808                // Clean up all state and processes associated with the user.
16809                // Kill all the processes for the user.
16810                forceStopUserLocked(userId, "finish user");
16811            }
16812        }
16813
16814        for (int i=0; i<callbacks.size(); i++) {
16815            try {
16816                if (stopped) callbacks.get(i).userStopped(userId);
16817                else callbacks.get(i).userStopAborted(userId);
16818            } catch (RemoteException e) {
16819            }
16820        }
16821
16822        mStackSupervisor.removeUserLocked(userId);
16823    }
16824
16825    @Override
16826    public UserInfo getCurrentUser() {
16827        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16828                != PackageManager.PERMISSION_GRANTED) && (
16829                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16830                != PackageManager.PERMISSION_GRANTED)) {
16831            String msg = "Permission Denial: getCurrentUser() from pid="
16832                    + Binder.getCallingPid()
16833                    + ", uid=" + Binder.getCallingUid()
16834                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16835            Slog.w(TAG, msg);
16836            throw new SecurityException(msg);
16837        }
16838        synchronized (this) {
16839            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16840        }
16841    }
16842
16843    int getCurrentUserIdLocked() {
16844        return mCurrentUserId;
16845    }
16846
16847    @Override
16848    public boolean isUserRunning(int userId, boolean orStopped) {
16849        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16850                != PackageManager.PERMISSION_GRANTED) {
16851            String msg = "Permission Denial: isUserRunning() from pid="
16852                    + Binder.getCallingPid()
16853                    + ", uid=" + Binder.getCallingUid()
16854                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16855            Slog.w(TAG, msg);
16856            throw new SecurityException(msg);
16857        }
16858        synchronized (this) {
16859            return isUserRunningLocked(userId, orStopped);
16860        }
16861    }
16862
16863    boolean isUserRunningLocked(int userId, boolean orStopped) {
16864        UserStartedState state = mStartedUsers.get(userId);
16865        if (state == null) {
16866            return false;
16867        }
16868        if (orStopped) {
16869            return true;
16870        }
16871        return state.mState != UserStartedState.STATE_STOPPING
16872                && state.mState != UserStartedState.STATE_SHUTDOWN;
16873    }
16874
16875    @Override
16876    public int[] getRunningUserIds() {
16877        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16878                != PackageManager.PERMISSION_GRANTED) {
16879            String msg = "Permission Denial: isUserRunning() from pid="
16880                    + Binder.getCallingPid()
16881                    + ", uid=" + Binder.getCallingUid()
16882                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16883            Slog.w(TAG, msg);
16884            throw new SecurityException(msg);
16885        }
16886        synchronized (this) {
16887            return mStartedUserArray;
16888        }
16889    }
16890
16891    private void updateStartedUserArrayLocked() {
16892        int num = 0;
16893        for (int i=0; i<mStartedUsers.size();  i++) {
16894            UserStartedState uss = mStartedUsers.valueAt(i);
16895            // This list does not include stopping users.
16896            if (uss.mState != UserStartedState.STATE_STOPPING
16897                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16898                num++;
16899            }
16900        }
16901        mStartedUserArray = new int[num];
16902        num = 0;
16903        for (int i=0; i<mStartedUsers.size();  i++) {
16904            UserStartedState uss = mStartedUsers.valueAt(i);
16905            if (uss.mState != UserStartedState.STATE_STOPPING
16906                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16907                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16908                num++;
16909            }
16910        }
16911    }
16912
16913    @Override
16914    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16915        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16916                != PackageManager.PERMISSION_GRANTED) {
16917            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16918                    + Binder.getCallingPid()
16919                    + ", uid=" + Binder.getCallingUid()
16920                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16921            Slog.w(TAG, msg);
16922            throw new SecurityException(msg);
16923        }
16924
16925        mUserSwitchObservers.register(observer);
16926    }
16927
16928    @Override
16929    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16930        mUserSwitchObservers.unregister(observer);
16931    }
16932
16933    private boolean userExists(int userId) {
16934        if (userId == 0) {
16935            return true;
16936        }
16937        UserManagerService ums = getUserManagerLocked();
16938        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16939    }
16940
16941    int[] getUsersLocked() {
16942        UserManagerService ums = getUserManagerLocked();
16943        return ums != null ? ums.getUserIds() : new int[] { 0 };
16944    }
16945
16946    UserManagerService getUserManagerLocked() {
16947        if (mUserManager == null) {
16948            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16949            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16950        }
16951        return mUserManager;
16952    }
16953
16954    private int applyUserId(int uid, int userId) {
16955        return UserHandle.getUid(userId, uid);
16956    }
16957
16958    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16959        if (info == null) return null;
16960        ApplicationInfo newInfo = new ApplicationInfo(info);
16961        newInfo.uid = applyUserId(info.uid, userId);
16962        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16963                + info.packageName;
16964        return newInfo;
16965    }
16966
16967    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16968        if (aInfo == null
16969                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16970            return aInfo;
16971        }
16972
16973        ActivityInfo info = new ActivityInfo(aInfo);
16974        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16975        return info;
16976    }
16977}
16978