ActivityManagerService.java revision aea74a5977ca9f1054926eb24f247562c3a4a6ba
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    boolean mStartRunning = false;
803    ComponentName mTopComponent;
804    String mTopAction;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    String mDebugApp = null;
949    boolean mWaitForDebugger = false;
950    boolean mDebugTransient = false;
951    String mOrigDebugApp = null;
952    boolean mOrigWaitForDebugger = false;
953    boolean mAlwaysFinishActivities = false;
954    IActivityController mController = null;
955    String mProfileApp = null;
956    ProcessRecord mProfileProc = null;
957    String mProfileFile;
958    ParcelFileDescriptor mProfileFd;
959    int mProfileType = 0;
960    boolean mAutoStopProfiler = false;
961    String mOpenGlTraceApp = null;
962
963    static class ProcessChangeItem {
964        static final int CHANGE_ACTIVITIES = 1<<0;
965        static final int CHANGE_IMPORTANCE= 1<<1;
966        int changes;
967        int uid;
968        int pid;
969        int importance;
970        boolean foregroundActivities;
971    }
972
973    final RemoteCallbackList<IProcessObserver> mProcessObservers
974            = new RemoteCallbackList<IProcessObserver>();
975    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
976
977    final ArrayList<ProcessChangeItem> mPendingProcessChanges
978            = new ArrayList<ProcessChangeItem>();
979    final ArrayList<ProcessChangeItem> mAvailProcessChanges
980            = new ArrayList<ProcessChangeItem>();
981
982    /**
983     * Runtime CPU use collection thread.  This object's lock is used to
984     * protect all related state.
985     */
986    final Thread mProcessCpuThread;
987
988    /**
989     * Used to collect process stats when showing not responding dialog.
990     * Protected by mProcessCpuThread.
991     */
992    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
993            MONITOR_THREAD_CPU_USAGE);
994    final AtomicLong mLastCpuTime = new AtomicLong(0);
995    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
996
997    long mLastWriteTime = 0;
998
999    /**
1000     * Used to retain an update lock when the foreground activity is in
1001     * immersive mode.
1002     */
1003    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1004
1005    /**
1006     * Set to true after the system has finished booting.
1007     */
1008    boolean mBooted = false;
1009
1010    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1011    int mProcessLimitOverride = -1;
1012
1013    WindowManagerService mWindowManager;
1014
1015    final ActivityThread mSystemThread;
1016
1017    int mCurrentUserId = 0;
1018    int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
1019    private UserManagerService mUserManager;
1020
1021    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1022        final ProcessRecord mApp;
1023        final int mPid;
1024        final IApplicationThread mAppThread;
1025
1026        AppDeathRecipient(ProcessRecord app, int pid,
1027                IApplicationThread thread) {
1028            if (localLOGV) Slog.v(
1029                TAG, "New death recipient " + this
1030                + " for thread " + thread.asBinder());
1031            mApp = app;
1032            mPid = pid;
1033            mAppThread = thread;
1034        }
1035
1036        @Override
1037        public void binderDied() {
1038            if (localLOGV) Slog.v(
1039                TAG, "Death received in " + this
1040                + " for thread " + mAppThread.asBinder());
1041            synchronized(ActivityManagerService.this) {
1042                appDiedLocked(mApp, mPid, mAppThread);
1043            }
1044        }
1045    }
1046
1047    static final int SHOW_ERROR_MSG = 1;
1048    static final int SHOW_NOT_RESPONDING_MSG = 2;
1049    static final int SHOW_FACTORY_ERROR_MSG = 3;
1050    static final int UPDATE_CONFIGURATION_MSG = 4;
1051    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1052    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1053    static final int SERVICE_TIMEOUT_MSG = 12;
1054    static final int UPDATE_TIME_ZONE = 13;
1055    static final int SHOW_UID_ERROR_MSG = 14;
1056    static final int IM_FEELING_LUCKY_MSG = 15;
1057    static final int PROC_START_TIMEOUT_MSG = 20;
1058    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1059    static final int KILL_APPLICATION_MSG = 22;
1060    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1061    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1062    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1063    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1064    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1065    static final int CLEAR_DNS_CACHE_MSG = 28;
1066    static final int UPDATE_HTTP_PROXY_MSG = 29;
1067    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1068    static final int DISPATCH_PROCESSES_CHANGED = 31;
1069    static final int DISPATCH_PROCESS_DIED = 32;
1070    static final int REPORT_MEM_USAGE_MSG = 33;
1071    static final int REPORT_USER_SWITCH_MSG = 34;
1072    static final int CONTINUE_USER_SWITCH_MSG = 35;
1073    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1074    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1075    static final int PERSIST_URI_GRANTS_MSG = 38;
1076    static final int REQUEST_ALL_PSS_MSG = 39;
1077    static final int START_RELATED_USERS_MSG = 40;
1078    static final int UPDATE_TIME = 41;
1079
1080    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1081    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1082    static final int FIRST_COMPAT_MODE_MSG = 300;
1083    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1084
1085    AlertDialog mUidAlert;
1086    CompatModeDialog mCompatModeDialog;
1087    long mLastMemUsageReportTime = 0;
1088
1089    /**
1090     * Flag whether the current user is a "monkey", i.e. whether
1091     * the UI is driven by a UI automation tool.
1092     */
1093    private boolean mUserIsMonkey;
1094
1095    final ServiceThread mHandlerThread;
1096    final MainHandler mHandler;
1097
1098    final class MainHandler extends Handler {
1099        public MainHandler(Looper looper) {
1100            super(looper, null, true);
1101        }
1102
1103        @Override
1104        public void handleMessage(Message msg) {
1105            switch (msg.what) {
1106            case SHOW_ERROR_MSG: {
1107                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1108                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1109                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1110                synchronized (ActivityManagerService.this) {
1111                    ProcessRecord proc = (ProcessRecord)data.get("app");
1112                    AppErrorResult res = (AppErrorResult) data.get("result");
1113                    if (proc != null && proc.crashDialog != null) {
1114                        Slog.e(TAG, "App already has crash dialog: " + proc);
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                        return;
1119                    }
1120                    if (!showBackground && UserHandle.getAppId(proc.uid)
1121                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1122                            && proc.pid != MY_PID) {
1123                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1124                        if (res != null) {
1125                            res.set(0);
1126                        }
1127                        return;
1128                    }
1129                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1130                        Dialog d = new AppErrorDialog(mContext,
1131                                ActivityManagerService.this, res, proc);
1132                        d.show();
1133                        proc.crashDialog = d;
1134                    } else {
1135                        // The device is asleep, so just pretend that the user
1136                        // saw a crash dialog and hit "force quit".
1137                        if (res != null) {
1138                            res.set(0);
1139                        }
1140                    }
1141                }
1142
1143                ensureBootCompleted();
1144            } break;
1145            case SHOW_NOT_RESPONDING_MSG: {
1146                synchronized (ActivityManagerService.this) {
1147                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1148                    ProcessRecord proc = (ProcessRecord)data.get("app");
1149                    if (proc != null && proc.anrDialog != null) {
1150                        Slog.e(TAG, "App already has anr dialog: " + proc);
1151                        return;
1152                    }
1153
1154                    Intent intent = new Intent("android.intent.action.ANR");
1155                    if (!mProcessesReady) {
1156                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1157                                | Intent.FLAG_RECEIVER_FOREGROUND);
1158                    }
1159                    broadcastIntentLocked(null, null, intent,
1160                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1161                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1162
1163                    if (mShowDialogs) {
1164                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1165                                mContext, proc, (ActivityRecord)data.get("activity"),
1166                                msg.arg1 != 0);
1167                        d.show();
1168                        proc.anrDialog = d;
1169                    } else {
1170                        // Just kill the app if there is no dialog to be shown.
1171                        killAppAtUsersRequest(proc, null);
1172                    }
1173                }
1174
1175                ensureBootCompleted();
1176            } break;
1177            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                synchronized (ActivityManagerService.this) {
1180                    ProcessRecord proc = (ProcessRecord) data.get("app");
1181                    if (proc == null) {
1182                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1183                        break;
1184                    }
1185                    if (proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1187                        return;
1188                    }
1189                    AppErrorResult res = (AppErrorResult) data.get("result");
1190                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1191                        Dialog d = new StrictModeViolationDialog(mContext,
1192                                ActivityManagerService.this, res, proc);
1193                        d.show();
1194                        proc.crashDialog = d;
1195                    } else {
1196                        // The device is asleep, so just pretend that the user
1197                        // saw a crash dialog and hit "force quit".
1198                        res.set(0);
1199                    }
1200                }
1201                ensureBootCompleted();
1202            } break;
1203            case SHOW_FACTORY_ERROR_MSG: {
1204                Dialog d = new FactoryErrorDialog(
1205                    mContext, msg.getData().getCharSequence("msg"));
1206                d.show();
1207                ensureBootCompleted();
1208            } break;
1209            case UPDATE_CONFIGURATION_MSG: {
1210                final ContentResolver resolver = mContext.getContentResolver();
1211                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1212            } break;
1213            case GC_BACKGROUND_PROCESSES_MSG: {
1214                synchronized (ActivityManagerService.this) {
1215                    performAppGcsIfAppropriateLocked();
1216                }
1217            } break;
1218            case WAIT_FOR_DEBUGGER_MSG: {
1219                synchronized (ActivityManagerService.this) {
1220                    ProcessRecord app = (ProcessRecord)msg.obj;
1221                    if (msg.arg1 != 0) {
1222                        if (!app.waitedForDebugger) {
1223                            Dialog d = new AppWaitingForDebuggerDialog(
1224                                    ActivityManagerService.this,
1225                                    mContext, app);
1226                            app.waitDialog = d;
1227                            app.waitedForDebugger = true;
1228                            d.show();
1229                        }
1230                    } else {
1231                        if (app.waitDialog != null) {
1232                            app.waitDialog.dismiss();
1233                            app.waitDialog = null;
1234                        }
1235                    }
1236                }
1237            } break;
1238            case SERVICE_TIMEOUT_MSG: {
1239                if (mDidDexOpt) {
1240                    mDidDexOpt = false;
1241                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1242                    nmsg.obj = msg.obj;
1243                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1244                    return;
1245                }
1246                mServices.serviceTimeout((ProcessRecord)msg.obj);
1247            } break;
1248            case UPDATE_TIME_ZONE: {
1249                synchronized (ActivityManagerService.this) {
1250                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1251                        ProcessRecord r = mLruProcesses.get(i);
1252                        if (r.thread != null) {
1253                            try {
1254                                r.thread.updateTimeZone();
1255                            } catch (RemoteException ex) {
1256                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1257                            }
1258                        }
1259                    }
1260                }
1261            } break;
1262            case CLEAR_DNS_CACHE_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1265                        ProcessRecord r = mLruProcesses.get(i);
1266                        if (r.thread != null) {
1267                            try {
1268                                r.thread.clearDnsCache();
1269                            } catch (RemoteException ex) {
1270                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1271                            }
1272                        }
1273                    }
1274                }
1275            } break;
1276            case UPDATE_HTTP_PROXY_MSG: {
1277                ProxyProperties proxy = (ProxyProperties)msg.obj;
1278                String host = "";
1279                String port = "";
1280                String exclList = "";
1281                String pacFileUrl = null;
1282                if (proxy != null) {
1283                    host = proxy.getHost();
1284                    port = Integer.toString(proxy.getPort());
1285                    exclList = proxy.getExclusionList();
1286                    pacFileUrl = proxy.getPacFileUrl();
1287                }
1288                synchronized (ActivityManagerService.this) {
1289                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1290                        ProcessRecord r = mLruProcesses.get(i);
1291                        if (r.thread != null) {
1292                            try {
1293                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1294                            } catch (RemoteException ex) {
1295                                Slog.w(TAG, "Failed to update http proxy for: " +
1296                                        r.info.processName);
1297                            }
1298                        }
1299                    }
1300                }
1301            } break;
1302            case SHOW_UID_ERROR_MSG: {
1303                String title = "System UIDs Inconsistent";
1304                String text = "UIDs on the system are inconsistent, you need to wipe your"
1305                        + " data partition or your device will be unstable.";
1306                Log.e(TAG, title + ": " + text);
1307                if (mShowDialogs) {
1308                    // XXX This is a temporary dialog, no need to localize.
1309                    AlertDialog d = new BaseErrorDialog(mContext);
1310                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1311                    d.setCancelable(false);
1312                    d.setTitle(title);
1313                    d.setMessage(text);
1314                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1315                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1316                    mUidAlert = d;
1317                    d.show();
1318                }
1319            } break;
1320            case IM_FEELING_LUCKY_MSG: {
1321                if (mUidAlert != null) {
1322                    mUidAlert.dismiss();
1323                    mUidAlert = null;
1324                }
1325            } break;
1326            case PROC_START_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1332                    return;
1333                }
1334                ProcessRecord app = (ProcessRecord)msg.obj;
1335                synchronized (ActivityManagerService.this) {
1336                    processStartTimedOutLocked(app);
1337                }
1338            } break;
1339            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1340                synchronized (ActivityManagerService.this) {
1341                    doPendingActivityLaunchesLocked(true);
1342                }
1343            } break;
1344            case KILL_APPLICATION_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    int appid = msg.arg1;
1347                    boolean restart = (msg.arg2 == 1);
1348                    Bundle bundle = (Bundle)msg.obj;
1349                    String pkg = bundle.getString("pkg");
1350                    String reason = bundle.getString("reason");
1351                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1352                            false, UserHandle.USER_ALL, reason);
1353                }
1354            } break;
1355            case FINALIZE_PENDING_INTENT_MSG: {
1356                ((PendingIntentRecord)msg.obj).completeFinalize();
1357            } break;
1358            case POST_HEAVY_NOTIFICATION_MSG: {
1359                INotificationManager inm = NotificationManager.getService();
1360                if (inm == null) {
1361                    return;
1362                }
1363
1364                ActivityRecord root = (ActivityRecord)msg.obj;
1365                ProcessRecord process = root.app;
1366                if (process == null) {
1367                    return;
1368                }
1369
1370                try {
1371                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1372                    String text = mContext.getString(R.string.heavy_weight_notification,
1373                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1374                    Notification notification = new Notification();
1375                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1376                    notification.when = 0;
1377                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1378                    notification.tickerText = text;
1379                    notification.defaults = 0; // please be quiet
1380                    notification.sound = null;
1381                    notification.vibrate = null;
1382                    notification.setLatestEventInfo(context, text,
1383                            mContext.getText(R.string.heavy_weight_notification_detail),
1384                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1385                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1386                                    new UserHandle(root.userId)));
1387
1388                    try {
1389                        int[] outId = new int[1];
1390                        inm.enqueueNotificationWithTag("android", "android", null,
1391                                R.string.heavy_weight_notification,
1392                                notification, outId, root.userId);
1393                    } catch (RuntimeException e) {
1394                        Slog.w(ActivityManagerService.TAG,
1395                                "Error showing notification for heavy-weight app", e);
1396                    } catch (RemoteException e) {
1397                    }
1398                } catch (NameNotFoundException e) {
1399                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1400                }
1401            } break;
1402            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1403                INotificationManager inm = NotificationManager.getService();
1404                if (inm == null) {
1405                    return;
1406                }
1407                try {
1408                    inm.cancelNotificationWithTag("android", null,
1409                            R.string.heavy_weight_notification,  msg.arg1);
1410                } catch (RuntimeException e) {
1411                    Slog.w(ActivityManagerService.TAG,
1412                            "Error canceling notification for service", e);
1413                } catch (RemoteException e) {
1414                }
1415            } break;
1416            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    checkExcessivePowerUsageLocked(true);
1419                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1420                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1421                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1422                }
1423            } break;
1424            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    ActivityRecord ar = (ActivityRecord)msg.obj;
1427                    if (mCompatModeDialog != null) {
1428                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1429                                ar.info.applicationInfo.packageName)) {
1430                            return;
1431                        }
1432                        mCompatModeDialog.dismiss();
1433                        mCompatModeDialog = null;
1434                    }
1435                    if (ar != null && false) {
1436                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1437                                ar.packageName)) {
1438                            int mode = mCompatModePackages.computeCompatModeLocked(
1439                                    ar.info.applicationInfo);
1440                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1441                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1442                                mCompatModeDialog = new CompatModeDialog(
1443                                        ActivityManagerService.this, mContext,
1444                                        ar.info.applicationInfo);
1445                                mCompatModeDialog.show();
1446                            }
1447                        }
1448                    }
1449                }
1450                break;
1451            }
1452            case DISPATCH_PROCESSES_CHANGED: {
1453                dispatchProcessesChanged();
1454                break;
1455            }
1456            case DISPATCH_PROCESS_DIED: {
1457                final int pid = msg.arg1;
1458                final int uid = msg.arg2;
1459                dispatchProcessDied(pid, uid);
1460                break;
1461            }
1462            case REPORT_MEM_USAGE_MSG: {
1463                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1464                Thread thread = new Thread() {
1465                    @Override public void run() {
1466                        final SparseArray<ProcessMemInfo> infoMap
1467                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1468                        for (int i=0, N=memInfos.size(); i<N; i++) {
1469                            ProcessMemInfo mi = memInfos.get(i);
1470                            infoMap.put(mi.pid, mi);
1471                        }
1472                        updateCpuStatsNow();
1473                        synchronized (mProcessCpuThread) {
1474                            final int N = mProcessCpuTracker.countStats();
1475                            for (int i=0; i<N; i++) {
1476                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1477                                if (st.vsize > 0) {
1478                                    long pss = Debug.getPss(st.pid, null);
1479                                    if (pss > 0) {
1480                                        if (infoMap.indexOfKey(st.pid) < 0) {
1481                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1482                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1483                                            mi.pss = pss;
1484                                            memInfos.add(mi);
1485                                        }
1486                                    }
1487                                }
1488                            }
1489                        }
1490
1491                        long totalPss = 0;
1492                        for (int i=0, N=memInfos.size(); i<N; i++) {
1493                            ProcessMemInfo mi = memInfos.get(i);
1494                            if (mi.pss == 0) {
1495                                mi.pss = Debug.getPss(mi.pid, null);
1496                            }
1497                            totalPss += mi.pss;
1498                        }
1499                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1500                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1501                                if (lhs.oomAdj != rhs.oomAdj) {
1502                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1503                                }
1504                                if (lhs.pss != rhs.pss) {
1505                                    return lhs.pss < rhs.pss ? 1 : -1;
1506                                }
1507                                return 0;
1508                            }
1509                        });
1510
1511                        StringBuilder tag = new StringBuilder(128);
1512                        StringBuilder stack = new StringBuilder(128);
1513                        tag.append("Low on memory -- ");
1514                        appendMemBucket(tag, totalPss, "total", false);
1515                        appendMemBucket(stack, totalPss, "total", true);
1516
1517                        StringBuilder logBuilder = new StringBuilder(1024);
1518                        logBuilder.append("Low on memory:\n");
1519
1520                        boolean firstLine = true;
1521                        int lastOomAdj = Integer.MIN_VALUE;
1522                        for (int i=0, N=memInfos.size(); i<N; i++) {
1523                            ProcessMemInfo mi = memInfos.get(i);
1524
1525                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1526                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1527                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1528                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1529                                if (lastOomAdj != mi.oomAdj) {
1530                                    lastOomAdj = mi.oomAdj;
1531                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1532                                        tag.append(" / ");
1533                                    }
1534                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1535                                        if (firstLine) {
1536                                            stack.append(":");
1537                                            firstLine = false;
1538                                        }
1539                                        stack.append("\n\t at ");
1540                                    } else {
1541                                        stack.append("$");
1542                                    }
1543                                } else {
1544                                    tag.append(" ");
1545                                    stack.append("$");
1546                                }
1547                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1548                                    appendMemBucket(tag, mi.pss, mi.name, false);
1549                                }
1550                                appendMemBucket(stack, mi.pss, mi.name, true);
1551                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1552                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1553                                    stack.append("(");
1554                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1555                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1556                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1557                                            stack.append(":");
1558                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1559                                        }
1560                                    }
1561                                    stack.append(")");
1562                                }
1563                            }
1564
1565                            logBuilder.append("  ");
1566                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1567                            logBuilder.append(' ');
1568                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1569                            logBuilder.append(' ');
1570                            ProcessList.appendRamKb(logBuilder, mi.pss);
1571                            logBuilder.append(" kB: ");
1572                            logBuilder.append(mi.name);
1573                            logBuilder.append(" (");
1574                            logBuilder.append(mi.pid);
1575                            logBuilder.append(") ");
1576                            logBuilder.append(mi.adjType);
1577                            logBuilder.append('\n');
1578                            if (mi.adjReason != null) {
1579                                logBuilder.append("                      ");
1580                                logBuilder.append(mi.adjReason);
1581                                logBuilder.append('\n');
1582                            }
1583                        }
1584
1585                        logBuilder.append("           ");
1586                        ProcessList.appendRamKb(logBuilder, totalPss);
1587                        logBuilder.append(" kB: TOTAL\n");
1588
1589                        long[] infos = new long[Debug.MEMINFO_COUNT];
1590                        Debug.getMemInfo(infos);
1591                        logBuilder.append("  MemInfo: ");
1592                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1595                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1596                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1597                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1598                            logBuilder.append("  ZRAM: ");
1599                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1600                            logBuilder.append(" kB RAM, ");
1601                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1602                            logBuilder.append(" kB swap total, ");
1603                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1604                            logBuilder.append(" kB swap free\n");
1605                        }
1606                        Slog.i(TAG, logBuilder.toString());
1607
1608                        StringBuilder dropBuilder = new StringBuilder(1024);
1609                        /*
1610                        StringWriter oomSw = new StringWriter();
1611                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1612                        StringWriter catSw = new StringWriter();
1613                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1614                        String[] emptyArgs = new String[] { };
1615                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1616                        oomPw.flush();
1617                        String oomString = oomSw.toString();
1618                        */
1619                        dropBuilder.append(stack);
1620                        dropBuilder.append('\n');
1621                        dropBuilder.append('\n');
1622                        dropBuilder.append(logBuilder);
1623                        dropBuilder.append('\n');
1624                        /*
1625                        dropBuilder.append(oomString);
1626                        dropBuilder.append('\n');
1627                        */
1628                        StringWriter catSw = new StringWriter();
1629                        synchronized (ActivityManagerService.this) {
1630                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1631                            String[] emptyArgs = new String[] { };
1632                            catPw.println();
1633                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1634                            catPw.println();
1635                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1636                                    false, false, null);
1637                            catPw.println();
1638                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1639                            catPw.flush();
1640                        }
1641                        dropBuilder.append(catSw.toString());
1642                        addErrorToDropBox("lowmem", null, "system_server", null,
1643                                null, tag.toString(), dropBuilder.toString(), null, null);
1644                        //Slog.i(TAG, "Sent to dropbox:");
1645                        //Slog.i(TAG, dropBuilder.toString());
1646                        synchronized (ActivityManagerService.this) {
1647                            long now = SystemClock.uptimeMillis();
1648                            if (mLastMemUsageReportTime < now) {
1649                                mLastMemUsageReportTime = now;
1650                            }
1651                        }
1652                    }
1653                };
1654                thread.start();
1655                break;
1656            }
1657            case REPORT_USER_SWITCH_MSG: {
1658                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1659                break;
1660            }
1661            case CONTINUE_USER_SWITCH_MSG: {
1662                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1663                break;
1664            }
1665            case USER_SWITCH_TIMEOUT_MSG: {
1666                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1667                break;
1668            }
1669            case IMMERSIVE_MODE_LOCK_MSG: {
1670                final boolean nextState = (msg.arg1 != 0);
1671                if (mUpdateLock.isHeld() != nextState) {
1672                    if (DEBUG_IMMERSIVE) {
1673                        final ActivityRecord r = (ActivityRecord) msg.obj;
1674                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1675                    }
1676                    if (nextState) {
1677                        mUpdateLock.acquire();
1678                    } else {
1679                        mUpdateLock.release();
1680                    }
1681                }
1682                break;
1683            }
1684            case PERSIST_URI_GRANTS_MSG: {
1685                writeGrantedUriPermissions();
1686                break;
1687            }
1688            case REQUEST_ALL_PSS_MSG: {
1689                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1690                break;
1691            }
1692            case START_RELATED_USERS_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    startRelatedUsersLocked();
1695                }
1696                break;
1697            }
1698            case UPDATE_TIME: {
1699                synchronized (ActivityManagerService.this) {
1700                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1701                        ProcessRecord r = mLruProcesses.get(i);
1702                        if (r.thread != null) {
1703                            try {
1704                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1705                            } catch (RemoteException ex) {
1706                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1707                            }
1708                        }
1709                    }
1710                }
1711                break;
1712            }
1713            }
1714        }
1715    };
1716
1717    static final int COLLECT_PSS_BG_MSG = 1;
1718
1719    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1720        @Override
1721        public void handleMessage(Message msg) {
1722            switch (msg.what) {
1723            case COLLECT_PSS_BG_MSG: {
1724                int i=0, num=0;
1725                long start = SystemClock.uptimeMillis();
1726                long[] tmp = new long[1];
1727                do {
1728                    ProcessRecord proc;
1729                    int procState;
1730                    int pid;
1731                    synchronized (ActivityManagerService.this) {
1732                        if (i >= mPendingPssProcesses.size()) {
1733                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1734                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1735                            mPendingPssProcesses.clear();
1736                            return;
1737                        }
1738                        proc = mPendingPssProcesses.get(i);
1739                        procState = proc.pssProcState;
1740                        if (proc.thread != null && procState == proc.setProcState) {
1741                            pid = proc.pid;
1742                        } else {
1743                            proc = null;
1744                            pid = 0;
1745                        }
1746                        i++;
1747                    }
1748                    if (proc != null) {
1749                        long pss = Debug.getPss(pid, tmp);
1750                        synchronized (ActivityManagerService.this) {
1751                            if (proc.thread != null && proc.setProcState == procState
1752                                    && proc.pid == pid) {
1753                                num++;
1754                                proc.lastPssTime = SystemClock.uptimeMillis();
1755                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1756                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1757                                        + ": " + pss + " lastPss=" + proc.lastPss
1758                                        + " state=" + ProcessList.makeProcStateString(procState));
1759                                if (proc.initialIdlePss == 0) {
1760                                    proc.initialIdlePss = pss;
1761                                }
1762                                proc.lastPss = pss;
1763                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1764                                    proc.lastCachedPss = pss;
1765                                }
1766                            }
1767                        }
1768                    }
1769                } while (true);
1770            }
1771            }
1772        }
1773    };
1774
1775    public void setSystemProcess() {
1776        try {
1777            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1778            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1779            ServiceManager.addService("meminfo", new MemBinder(this));
1780            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1781            ServiceManager.addService("dbinfo", new DbBinder(this));
1782            if (MONITOR_CPU_USAGE) {
1783                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1784            }
1785            ServiceManager.addService("permission", new PermissionController(this));
1786
1787            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1788                    "android", STOCK_PM_FLAGS);
1789            mSystemThread.installSystemApplicationInfo(info);
1790
1791            synchronized (this) {
1792                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1793                app.persistent = true;
1794                app.pid = MY_PID;
1795                app.maxAdj = ProcessList.SYSTEM_ADJ;
1796                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1797                mProcessNames.put(app.processName, app.uid, app);
1798                synchronized (mPidsSelfLocked) {
1799                    mPidsSelfLocked.put(app.pid, app);
1800                }
1801                updateLruProcessLocked(app, false, null);
1802                updateOomAdjLocked();
1803            }
1804        } catch (PackageManager.NameNotFoundException e) {
1805            throw new RuntimeException(
1806                    "Unable to find android system package", e);
1807        }
1808    }
1809
1810    public void setWindowManager(WindowManagerService wm) {
1811        mWindowManager = wm;
1812        mStackSupervisor.setWindowManager(wm);
1813    }
1814
1815    public void startObservingNativeCrashes() {
1816        final NativeCrashListener ncl = new NativeCrashListener(this);
1817        ncl.start();
1818    }
1819
1820    public IAppOpsService getAppOpsService() {
1821        return mAppOpsService;
1822    }
1823
1824    static class MemBinder extends Binder {
1825        ActivityManagerService mActivityManagerService;
1826        MemBinder(ActivityManagerService activityManagerService) {
1827            mActivityManagerService = activityManagerService;
1828        }
1829
1830        @Override
1831        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1832            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1833                    != PackageManager.PERMISSION_GRANTED) {
1834                pw.println("Permission Denial: can't dump meminfo from from pid="
1835                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1836                        + " without permission " + android.Manifest.permission.DUMP);
1837                return;
1838            }
1839
1840            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1841        }
1842    }
1843
1844    static class GraphicsBinder extends Binder {
1845        ActivityManagerService mActivityManagerService;
1846        GraphicsBinder(ActivityManagerService activityManagerService) {
1847            mActivityManagerService = activityManagerService;
1848        }
1849
1850        @Override
1851        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1852            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1853                    != PackageManager.PERMISSION_GRANTED) {
1854                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1855                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1856                        + " without permission " + android.Manifest.permission.DUMP);
1857                return;
1858            }
1859
1860            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1861        }
1862    }
1863
1864    static class DbBinder extends Binder {
1865        ActivityManagerService mActivityManagerService;
1866        DbBinder(ActivityManagerService activityManagerService) {
1867            mActivityManagerService = activityManagerService;
1868        }
1869
1870        @Override
1871        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1872            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1873                    != PackageManager.PERMISSION_GRANTED) {
1874                pw.println("Permission Denial: can't dump dbinfo from from pid="
1875                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1876                        + " without permission " + android.Manifest.permission.DUMP);
1877                return;
1878            }
1879
1880            mActivityManagerService.dumpDbInfo(fd, pw, args);
1881        }
1882    }
1883
1884    static class CpuBinder extends Binder {
1885        ActivityManagerService mActivityManagerService;
1886        CpuBinder(ActivityManagerService activityManagerService) {
1887            mActivityManagerService = activityManagerService;
1888        }
1889
1890        @Override
1891        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1892            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1893                    != PackageManager.PERMISSION_GRANTED) {
1894                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1895                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1896                        + " without permission " + android.Manifest.permission.DUMP);
1897                return;
1898            }
1899
1900            synchronized (mActivityManagerService.mProcessCpuThread) {
1901                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1902                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1903                        SystemClock.uptimeMillis()));
1904            }
1905        }
1906    }
1907
1908    public static final class Lifecycle extends SystemService {
1909        private final ActivityManagerService mService;
1910
1911        public Lifecycle(Context context) {
1912            super(context);
1913            mService = new ActivityManagerService(context);
1914        }
1915
1916        @Override
1917        public void onStart() {
1918            mService.start();
1919        }
1920
1921        public ActivityManagerService getService() {
1922            return mService;
1923        }
1924    }
1925
1926    // Note: This method is invoked on the main thread but may need to attach various
1927    // handlers to other threads.  So take care to be explicit about the looper.
1928    public ActivityManagerService(Context systemContext) {
1929        mContext = systemContext;
1930        mFactoryTest = FactoryTest.getMode();
1931        mSystemThread = ActivityThread.currentActivityThread();
1932
1933        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1934
1935        mHandlerThread = new ServiceThread(TAG,
1936                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1937        mHandlerThread.start();
1938        mHandler = new MainHandler(mHandlerThread.getLooper());
1939
1940        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1941                "foreground", BROADCAST_FG_TIMEOUT, false);
1942        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1943                "background", BROADCAST_BG_TIMEOUT, true);
1944        mBroadcastQueues[0] = mFgBroadcastQueue;
1945        mBroadcastQueues[1] = mBgBroadcastQueue;
1946
1947        mServices = new ActiveServices(this);
1948        mProviderMap = new ProviderMap(this);
1949
1950        // TODO: Move creation of battery stats service outside of activity manager service.
1951        File dataDir = Environment.getDataDirectory();
1952        File systemDir = new File(dataDir, "system");
1953        systemDir.mkdirs();
1954        mBatteryStatsService = new BatteryStatsService(new File(
1955                systemDir, "batterystats.bin").toString(), mHandler);
1956        mBatteryStatsService.getActiveStatistics().readLocked();
1957        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1958        mOnBattery = DEBUG_POWER ? true
1959                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1960        mBatteryStatsService.getActiveStatistics().setCallback(this);
1961
1962        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1963
1964        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1965        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1966
1967        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1968
1969        // User 0 is the first and only user that runs at boot.
1970        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1971        mUserLru.add(Integer.valueOf(0));
1972        updateStartedUserArrayLocked();
1973
1974        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1975            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1976
1977        mConfiguration.setToDefaults();
1978        mConfiguration.setLocale(Locale.getDefault());
1979
1980        mConfigurationSeq = mConfiguration.seq = 1;
1981        mProcessCpuTracker.init();
1982
1983        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1984        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1985        mStackSupervisor = new ActivityStackSupervisor(this);
1986
1987        mProcessCpuThread = new Thread("CpuTracker") {
1988            @Override
1989            public void run() {
1990                while (true) {
1991                    try {
1992                        try {
1993                            synchronized(this) {
1994                                final long now = SystemClock.uptimeMillis();
1995                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1996                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1997                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1998                                //        + ", write delay=" + nextWriteDelay);
1999                                if (nextWriteDelay < nextCpuDelay) {
2000                                    nextCpuDelay = nextWriteDelay;
2001                                }
2002                                if (nextCpuDelay > 0) {
2003                                    mProcessCpuMutexFree.set(true);
2004                                    this.wait(nextCpuDelay);
2005                                }
2006                            }
2007                        } catch (InterruptedException e) {
2008                        }
2009                        updateCpuStatsNow();
2010                    } catch (Exception e) {
2011                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2012                    }
2013                }
2014            }
2015        };
2016
2017        Watchdog.getInstance().addMonitor(this);
2018        Watchdog.getInstance().addThread(mHandler);
2019    }
2020
2021    private void start() {
2022        mProcessCpuThread.start();
2023
2024        mBatteryStatsService.publish(mContext);
2025        mUsageStatsService.publish(mContext);
2026        mAppOpsService.publish(mContext);
2027        startRunning(null, null, null, null);
2028    }
2029
2030    @Override
2031    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2032            throws RemoteException {
2033        if (code == SYSPROPS_TRANSACTION) {
2034            // We need to tell all apps about the system property change.
2035            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2036            synchronized(this) {
2037                final int NP = mProcessNames.getMap().size();
2038                for (int ip=0; ip<NP; ip++) {
2039                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2040                    final int NA = apps.size();
2041                    for (int ia=0; ia<NA; ia++) {
2042                        ProcessRecord app = apps.valueAt(ia);
2043                        if (app.thread != null) {
2044                            procs.add(app.thread.asBinder());
2045                        }
2046                    }
2047                }
2048            }
2049
2050            int N = procs.size();
2051            for (int i=0; i<N; i++) {
2052                Parcel data2 = Parcel.obtain();
2053                try {
2054                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2055                } catch (RemoteException e) {
2056                }
2057                data2.recycle();
2058            }
2059        }
2060        try {
2061            return super.onTransact(code, data, reply, flags);
2062        } catch (RuntimeException e) {
2063            // The activity manager only throws security exceptions, so let's
2064            // log all others.
2065            if (!(e instanceof SecurityException)) {
2066                Slog.wtf(TAG, "Activity Manager Crash", e);
2067            }
2068            throw e;
2069        }
2070    }
2071
2072    void updateCpuStats() {
2073        final long now = SystemClock.uptimeMillis();
2074        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2075            return;
2076        }
2077        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2078            synchronized (mProcessCpuThread) {
2079                mProcessCpuThread.notify();
2080            }
2081        }
2082    }
2083
2084    void updateCpuStatsNow() {
2085        synchronized (mProcessCpuThread) {
2086            mProcessCpuMutexFree.set(false);
2087            final long now = SystemClock.uptimeMillis();
2088            boolean haveNewCpuStats = false;
2089
2090            if (MONITOR_CPU_USAGE &&
2091                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2092                mLastCpuTime.set(now);
2093                haveNewCpuStats = true;
2094                mProcessCpuTracker.update();
2095                //Slog.i(TAG, mProcessCpu.printCurrentState());
2096                //Slog.i(TAG, "Total CPU usage: "
2097                //        + mProcessCpu.getTotalCpuPercent() + "%");
2098
2099                // Slog the cpu usage if the property is set.
2100                if ("true".equals(SystemProperties.get("events.cpu"))) {
2101                    int user = mProcessCpuTracker.getLastUserTime();
2102                    int system = mProcessCpuTracker.getLastSystemTime();
2103                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2104                    int irq = mProcessCpuTracker.getLastIrqTime();
2105                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2106                    int idle = mProcessCpuTracker.getLastIdleTime();
2107
2108                    int total = user + system + iowait + irq + softIrq + idle;
2109                    if (total == 0) total = 1;
2110
2111                    EventLog.writeEvent(EventLogTags.CPU,
2112                            ((user+system+iowait+irq+softIrq) * 100) / total,
2113                            (user * 100) / total,
2114                            (system * 100) / total,
2115                            (iowait * 100) / total,
2116                            (irq * 100) / total,
2117                            (softIrq * 100) / total);
2118                }
2119            }
2120
2121            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2122            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2123            synchronized(bstats) {
2124                synchronized(mPidsSelfLocked) {
2125                    if (haveNewCpuStats) {
2126                        if (mOnBattery) {
2127                            int perc = bstats.startAddingCpuLocked();
2128                            int totalUTime = 0;
2129                            int totalSTime = 0;
2130                            final int N = mProcessCpuTracker.countStats();
2131                            for (int i=0; i<N; i++) {
2132                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2133                                if (!st.working) {
2134                                    continue;
2135                                }
2136                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2137                                int otherUTime = (st.rel_utime*perc)/100;
2138                                int otherSTime = (st.rel_stime*perc)/100;
2139                                totalUTime += otherUTime;
2140                                totalSTime += otherSTime;
2141                                if (pr != null) {
2142                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2143                                    if (ps == null || !ps.isActive()) {
2144                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2145                                                pr.info.uid, pr.processName);
2146                                    }
2147                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2148                                            st.rel_stime-otherSTime);
2149                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2150                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2151                                } else {
2152                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2153                                    if (ps == null || !ps.isActive()) {
2154                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2155                                                bstats.mapUid(st.uid), st.name);
2156                                    }
2157                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2158                                            st.rel_stime-otherSTime);
2159                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2160                                }
2161                            }
2162                            bstats.finishAddingCpuLocked(perc, totalUTime,
2163                                    totalSTime, cpuSpeedTimes);
2164                        }
2165                    }
2166                }
2167
2168                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2169                    mLastWriteTime = now;
2170                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2171                }
2172            }
2173        }
2174    }
2175
2176    @Override
2177    public void batteryNeedsCpuUpdate() {
2178        updateCpuStatsNow();
2179    }
2180
2181    @Override
2182    public void batteryPowerChanged(boolean onBattery) {
2183        // When plugging in, update the CPU stats first before changing
2184        // the plug state.
2185        updateCpuStatsNow();
2186        synchronized (this) {
2187            synchronized(mPidsSelfLocked) {
2188                mOnBattery = DEBUG_POWER ? true : onBattery;
2189            }
2190        }
2191    }
2192
2193    /**
2194     * Initialize the application bind args. These are passed to each
2195     * process when the bindApplication() IPC is sent to the process. They're
2196     * lazily setup to make sure the services are running when they're asked for.
2197     */
2198    private HashMap<String, IBinder> getCommonServicesLocked() {
2199        if (mAppBindArgs == null) {
2200            mAppBindArgs = new HashMap<String, IBinder>();
2201
2202            // Setup the application init args
2203            mAppBindArgs.put("package", ServiceManager.getService("package"));
2204            mAppBindArgs.put("window", ServiceManager.getService("window"));
2205            mAppBindArgs.put(Context.ALARM_SERVICE,
2206                    ServiceManager.getService(Context.ALARM_SERVICE));
2207        }
2208        return mAppBindArgs;
2209    }
2210
2211    final void setFocusedActivityLocked(ActivityRecord r) {
2212        if (mFocusedActivity != r) {
2213            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2214            mFocusedActivity = r;
2215            mStackSupervisor.setFocusedStack(r);
2216            if (r != null) {
2217                mWindowManager.setFocusedApp(r.appToken, true);
2218            }
2219            applyUpdateLockStateLocked(r);
2220        }
2221    }
2222
2223    @Override
2224    public void setFocusedStack(int stackId) {
2225        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2226        synchronized (ActivityManagerService.this) {
2227            ActivityStack stack = mStackSupervisor.getStack(stackId);
2228            if (stack != null) {
2229                ActivityRecord r = stack.topRunningActivityLocked(null);
2230                if (r != null) {
2231                    setFocusedActivityLocked(r);
2232                }
2233            }
2234        }
2235    }
2236
2237    @Override
2238    public void notifyActivityDrawn(IBinder token) {
2239        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2240        synchronized (this) {
2241            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2242            if (r != null) {
2243                r.task.stack.notifyActivityDrawnLocked(r);
2244            }
2245        }
2246    }
2247
2248    final void applyUpdateLockStateLocked(ActivityRecord r) {
2249        // Modifications to the UpdateLock state are done on our handler, outside
2250        // the activity manager's locks.  The new state is determined based on the
2251        // state *now* of the relevant activity record.  The object is passed to
2252        // the handler solely for logging detail, not to be consulted/modified.
2253        final boolean nextState = r != null && r.immersive;
2254        mHandler.sendMessage(
2255                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2256    }
2257
2258    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2259        Message msg = Message.obtain();
2260        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2261        msg.obj = r.task.askedCompatMode ? null : r;
2262        mHandler.sendMessage(msg);
2263    }
2264
2265    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2266            String what, Object obj, ProcessRecord srcApp) {
2267        app.lastActivityTime = now;
2268
2269        if (app.activities.size() > 0) {
2270            // Don't want to touch dependent processes that are hosting activities.
2271            return index;
2272        }
2273
2274        int lrui = mLruProcesses.lastIndexOf(app);
2275        if (lrui < 0) {
2276            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2277                    + what + " " + obj + " from " + srcApp);
2278            return index;
2279        }
2280
2281        if (lrui >= index) {
2282            // Don't want to cause this to move dependent processes *back* in the
2283            // list as if they were less frequently used.
2284            return index;
2285        }
2286
2287        if (lrui >= mLruProcessActivityStart) {
2288            // Don't want to touch dependent processes that are hosting activities.
2289            return index;
2290        }
2291
2292        mLruProcesses.remove(lrui);
2293        if (index > 0) {
2294            index--;
2295        }
2296        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2297                + " in LRU list: " + app);
2298        mLruProcesses.add(index, app);
2299        return index;
2300    }
2301
2302    final void removeLruProcessLocked(ProcessRecord app) {
2303        int lrui = mLruProcesses.lastIndexOf(app);
2304        if (lrui >= 0) {
2305            if (lrui <= mLruProcessActivityStart) {
2306                mLruProcessActivityStart--;
2307            }
2308            if (lrui <= mLruProcessServiceStart) {
2309                mLruProcessServiceStart--;
2310            }
2311            mLruProcesses.remove(lrui);
2312        }
2313    }
2314
2315    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2316            ProcessRecord client) {
2317        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2318        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2319        if (!activityChange && hasActivity) {
2320            // The process has activties, so we are only going to allow activity-based
2321            // adjustments move it.  It should be kept in the front of the list with other
2322            // processes that have activities, and we don't want those to change their
2323            // order except due to activity operations.
2324            return;
2325        }
2326
2327        mLruSeq++;
2328        final long now = SystemClock.uptimeMillis();
2329        app.lastActivityTime = now;
2330
2331        // First a quick reject: if the app is already at the position we will
2332        // put it, then there is nothing to do.
2333        if (hasActivity) {
2334            final int N = mLruProcesses.size();
2335            if (N > 0 && mLruProcesses.get(N-1) == app) {
2336                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2337                return;
2338            }
2339        } else {
2340            if (mLruProcessServiceStart > 0
2341                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2342                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2343                return;
2344            }
2345        }
2346
2347        int lrui = mLruProcesses.lastIndexOf(app);
2348
2349        if (app.persistent && lrui >= 0) {
2350            // We don't care about the position of persistent processes, as long as
2351            // they are in the list.
2352            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2353            return;
2354        }
2355
2356        /* In progress: compute new position first, so we can avoid doing work
2357           if the process is not actually going to move.  Not yet working.
2358        int addIndex;
2359        int nextIndex;
2360        boolean inActivity = false, inService = false;
2361        if (hasActivity) {
2362            // Process has activities, put it at the very tipsy-top.
2363            addIndex = mLruProcesses.size();
2364            nextIndex = mLruProcessServiceStart;
2365            inActivity = true;
2366        } else if (hasService) {
2367            // Process has services, put it at the top of the service list.
2368            addIndex = mLruProcessActivityStart;
2369            nextIndex = mLruProcessServiceStart;
2370            inActivity = true;
2371            inService = true;
2372        } else  {
2373            // Process not otherwise of interest, it goes to the top of the non-service area.
2374            addIndex = mLruProcessServiceStart;
2375            if (client != null) {
2376                int clientIndex = mLruProcesses.lastIndexOf(client);
2377                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2378                        + app);
2379                if (clientIndex >= 0 && addIndex > clientIndex) {
2380                    addIndex = clientIndex;
2381                }
2382            }
2383            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2384        }
2385
2386        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2387                + mLruProcessActivityStart + "): " + app);
2388        */
2389
2390        if (lrui >= 0) {
2391            if (lrui < mLruProcessActivityStart) {
2392                mLruProcessActivityStart--;
2393            }
2394            if (lrui < mLruProcessServiceStart) {
2395                mLruProcessServiceStart--;
2396            }
2397            /*
2398            if (addIndex > lrui) {
2399                addIndex--;
2400            }
2401            if (nextIndex > lrui) {
2402                nextIndex--;
2403            }
2404            */
2405            mLruProcesses.remove(lrui);
2406        }
2407
2408        /*
2409        mLruProcesses.add(addIndex, app);
2410        if (inActivity) {
2411            mLruProcessActivityStart++;
2412        }
2413        if (inService) {
2414            mLruProcessActivityStart++;
2415        }
2416        */
2417
2418        int nextIndex;
2419        if (hasActivity) {
2420            final int N = mLruProcesses.size();
2421            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2422                // Process doesn't have activities, but has clients with
2423                // activities...  move it up, but one below the top (the top
2424                // should always have a real activity).
2425                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2426                mLruProcesses.add(N-1, app);
2427                // To keep it from spamming the LRU list (by making a bunch of clients),
2428                // we will push down any other entries owned by the app.
2429                final int uid = app.info.uid;
2430                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2431                    ProcessRecord subProc = mLruProcesses.get(i);
2432                    if (subProc.info.uid == uid) {
2433                        // We want to push this one down the list.  If the process after
2434                        // it is for the same uid, however, don't do so, because we don't
2435                        // want them internally to be re-ordered.
2436                        if (mLruProcesses.get(i-1).info.uid != uid) {
2437                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2438                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2439                            ProcessRecord tmp = mLruProcesses.get(i);
2440                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2441                            mLruProcesses.set(i-1, tmp);
2442                            i--;
2443                        }
2444                    } else {
2445                        // A gap, we can stop here.
2446                        break;
2447                    }
2448                }
2449            } else {
2450                // Process has activities, put it at the very tipsy-top.
2451                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2452                mLruProcesses.add(app);
2453            }
2454            nextIndex = mLruProcessServiceStart;
2455        } else if (hasService) {
2456            // Process has services, put it at the top of the service list.
2457            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2458            mLruProcesses.add(mLruProcessActivityStart, app);
2459            nextIndex = mLruProcessServiceStart;
2460            mLruProcessActivityStart++;
2461        } else  {
2462            // Process not otherwise of interest, it goes to the top of the non-service area.
2463            int index = mLruProcessServiceStart;
2464            if (client != null) {
2465                // If there is a client, don't allow the process to be moved up higher
2466                // in the list than that client.
2467                int clientIndex = mLruProcesses.lastIndexOf(client);
2468                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2469                        + " when updating " + app);
2470                if (clientIndex <= lrui) {
2471                    // Don't allow the client index restriction to push it down farther in the
2472                    // list than it already is.
2473                    clientIndex = lrui;
2474                }
2475                if (clientIndex >= 0 && index > clientIndex) {
2476                    index = clientIndex;
2477                }
2478            }
2479            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2480            mLruProcesses.add(index, app);
2481            nextIndex = index-1;
2482            mLruProcessActivityStart++;
2483            mLruProcessServiceStart++;
2484        }
2485
2486        // If the app is currently using a content provider or service,
2487        // bump those processes as well.
2488        for (int j=app.connections.size()-1; j>=0; j--) {
2489            ConnectionRecord cr = app.connections.valueAt(j);
2490            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2491                    && cr.binding.service.app != null
2492                    && cr.binding.service.app.lruSeq != mLruSeq
2493                    && !cr.binding.service.app.persistent) {
2494                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2495                        "service connection", cr, app);
2496            }
2497        }
2498        for (int j=app.conProviders.size()-1; j>=0; j--) {
2499            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2500            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2501                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2502                        "provider reference", cpr, app);
2503            }
2504        }
2505    }
2506
2507    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2508        if (uid == Process.SYSTEM_UID) {
2509            // The system gets to run in any process.  If there are multiple
2510            // processes with the same uid, just pick the first (this
2511            // should never happen).
2512            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2513            if (procs == null) return null;
2514            final int N = procs.size();
2515            for (int i = 0; i < N; i++) {
2516                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2517            }
2518        }
2519        ProcessRecord proc = mProcessNames.get(processName, uid);
2520        if (false && proc != null && !keepIfLarge
2521                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2522                && proc.lastCachedPss >= 4000) {
2523            // Turn this condition on to cause killing to happen regularly, for testing.
2524            if (proc.baseProcessTracker != null) {
2525                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2526            }
2527            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2528                    + "k from cached");
2529        } else if (proc != null && !keepIfLarge
2530                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2531                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2532            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2533            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2534                if (proc.baseProcessTracker != null) {
2535                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2536                }
2537                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2538                        + "k from cached");
2539            }
2540        }
2541        return proc;
2542    }
2543
2544    void ensurePackageDexOpt(String packageName) {
2545        IPackageManager pm = AppGlobals.getPackageManager();
2546        try {
2547            if (pm.performDexOpt(packageName)) {
2548                mDidDexOpt = true;
2549            }
2550        } catch (RemoteException e) {
2551        }
2552    }
2553
2554    boolean isNextTransitionForward() {
2555        int transit = mWindowManager.getPendingAppTransition();
2556        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2557                || transit == AppTransition.TRANSIT_TASK_OPEN
2558                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2559    }
2560
2561    final ProcessRecord startProcessLocked(String processName,
2562            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2563            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2564            boolean isolated, boolean keepIfLarge) {
2565        ProcessRecord app;
2566        if (!isolated) {
2567            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2568        } else {
2569            // If this is an isolated process, it can't re-use an existing process.
2570            app = null;
2571        }
2572        // We don't have to do anything more if:
2573        // (1) There is an existing application record; and
2574        // (2) The caller doesn't think it is dead, OR there is no thread
2575        //     object attached to it so we know it couldn't have crashed; and
2576        // (3) There is a pid assigned to it, so it is either starting or
2577        //     already running.
2578        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2579                + " app=" + app + " knownToBeDead=" + knownToBeDead
2580                + " thread=" + (app != null ? app.thread : null)
2581                + " pid=" + (app != null ? app.pid : -1));
2582        if (app != null && app.pid > 0) {
2583            if (!knownToBeDead || app.thread == null) {
2584                // We already have the app running, or are waiting for it to
2585                // come up (we have a pid but not yet its thread), so keep it.
2586                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2587                // If this is a new package in the process, add the package to the list
2588                app.addPackage(info.packageName, mProcessStats);
2589                return app;
2590            }
2591
2592            // An application record is attached to a previous process,
2593            // clean it up now.
2594            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2595            handleAppDiedLocked(app, true, true);
2596        }
2597
2598        String hostingNameStr = hostingName != null
2599                ? hostingName.flattenToShortString() : null;
2600
2601        if (!isolated) {
2602            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2603                // If we are in the background, then check to see if this process
2604                // is bad.  If so, we will just silently fail.
2605                if (mBadProcesses.get(info.processName, info.uid) != null) {
2606                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2607                            + "/" + info.processName);
2608                    return null;
2609                }
2610            } else {
2611                // When the user is explicitly starting a process, then clear its
2612                // crash count so that we won't make it bad until they see at
2613                // least one crash dialog again, and make the process good again
2614                // if it had been bad.
2615                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2616                        + "/" + info.processName);
2617                mProcessCrashTimes.remove(info.processName, info.uid);
2618                if (mBadProcesses.get(info.processName, info.uid) != null) {
2619                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2620                            UserHandle.getUserId(info.uid), info.uid,
2621                            info.processName);
2622                    mBadProcesses.remove(info.processName, info.uid);
2623                    if (app != null) {
2624                        app.bad = false;
2625                    }
2626                }
2627            }
2628        }
2629
2630        if (app == null) {
2631            app = newProcessRecordLocked(info, processName, isolated);
2632            if (app == null) {
2633                Slog.w(TAG, "Failed making new process record for "
2634                        + processName + "/" + info.uid + " isolated=" + isolated);
2635                return null;
2636            }
2637            mProcessNames.put(processName, app.uid, app);
2638            if (isolated) {
2639                mIsolatedProcesses.put(app.uid, app);
2640            }
2641        } else {
2642            // If this is a new package in the process, add the package to the list
2643            app.addPackage(info.packageName, mProcessStats);
2644        }
2645
2646        // If the system is not ready yet, then hold off on starting this
2647        // process until it is.
2648        if (!mProcessesReady
2649                && !isAllowedWhileBooting(info)
2650                && !allowWhileBooting) {
2651            if (!mProcessesOnHold.contains(app)) {
2652                mProcessesOnHold.add(app);
2653            }
2654            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2655            return app;
2656        }
2657
2658        startProcessLocked(app, hostingType, hostingNameStr);
2659        return (app.pid != 0) ? app : null;
2660    }
2661
2662    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2663        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2664    }
2665
2666    private final void startProcessLocked(ProcessRecord app,
2667            String hostingType, String hostingNameStr) {
2668        if (app.pid > 0 && app.pid != MY_PID) {
2669            synchronized (mPidsSelfLocked) {
2670                mPidsSelfLocked.remove(app.pid);
2671                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2672            }
2673            app.setPid(0);
2674        }
2675
2676        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2677                "startProcessLocked removing on hold: " + app);
2678        mProcessesOnHold.remove(app);
2679
2680        updateCpuStats();
2681
2682        try {
2683            int uid = app.uid;
2684
2685            int[] gids = null;
2686            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2687            if (!app.isolated) {
2688                int[] permGids = null;
2689                try {
2690                    final PackageManager pm = mContext.getPackageManager();
2691                    permGids = pm.getPackageGids(app.info.packageName);
2692
2693                    if (Environment.isExternalStorageEmulated()) {
2694                        if (pm.checkPermission(
2695                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2696                                app.info.packageName) == PERMISSION_GRANTED) {
2697                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2698                        } else {
2699                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2700                        }
2701                    }
2702                } catch (PackageManager.NameNotFoundException e) {
2703                    Slog.w(TAG, "Unable to retrieve gids", e);
2704                }
2705
2706                /*
2707                 * Add shared application GID so applications can share some
2708                 * resources like shared libraries
2709                 */
2710                if (permGids == null) {
2711                    gids = new int[1];
2712                } else {
2713                    gids = new int[permGids.length + 1];
2714                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2715                }
2716                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2717            }
2718            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2719                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2720                        && mTopComponent != null
2721                        && app.processName.equals(mTopComponent.getPackageName())) {
2722                    uid = 0;
2723                }
2724                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2725                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2726                    uid = 0;
2727                }
2728            }
2729            int debugFlags = 0;
2730            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2731                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2732                // Also turn on CheckJNI for debuggable apps. It's quite
2733                // awkward to turn on otherwise.
2734                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2735            }
2736            // Run the app in safe mode if its manifest requests so or the
2737            // system is booted in safe mode.
2738            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2739                Zygote.systemInSafeMode == true) {
2740                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2741            }
2742            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2743                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2744            }
2745            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2746                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2747            }
2748            if ("1".equals(SystemProperties.get("debug.assert"))) {
2749                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2750            }
2751
2752            // Start the process.  It will either succeed and return a result containing
2753            // the PID of the new process, or else throw a RuntimeException.
2754            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2755                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2756                    app.info.targetSdkVersion, app.info.seinfo, null);
2757
2758            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2759            synchronized (bs) {
2760                if (bs.isOnBattery()) {
2761                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2762                }
2763            }
2764
2765            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2766                    UserHandle.getUserId(uid), startResult.pid, uid,
2767                    app.processName, hostingType,
2768                    hostingNameStr != null ? hostingNameStr : "");
2769
2770            if (app.persistent) {
2771                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2772            }
2773
2774            StringBuilder buf = mStringBuilder;
2775            buf.setLength(0);
2776            buf.append("Start proc ");
2777            buf.append(app.processName);
2778            buf.append(" for ");
2779            buf.append(hostingType);
2780            if (hostingNameStr != null) {
2781                buf.append(" ");
2782                buf.append(hostingNameStr);
2783            }
2784            buf.append(": pid=");
2785            buf.append(startResult.pid);
2786            buf.append(" uid=");
2787            buf.append(uid);
2788            buf.append(" gids={");
2789            if (gids != null) {
2790                for (int gi=0; gi<gids.length; gi++) {
2791                    if (gi != 0) buf.append(", ");
2792                    buf.append(gids[gi]);
2793
2794                }
2795            }
2796            buf.append("}");
2797            Slog.i(TAG, buf.toString());
2798            app.setPid(startResult.pid);
2799            app.usingWrapper = startResult.usingWrapper;
2800            app.removed = false;
2801            synchronized (mPidsSelfLocked) {
2802                this.mPidsSelfLocked.put(startResult.pid, app);
2803                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2804                msg.obj = app;
2805                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2806                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2807            }
2808            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2809                    app.processName, app.info.uid);
2810            if (app.isolated) {
2811                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2812            }
2813        } catch (RuntimeException e) {
2814            // XXX do better error recovery.
2815            app.setPid(0);
2816            Slog.e(TAG, "Failure starting process " + app.processName, e);
2817        }
2818    }
2819
2820    void updateUsageStats(ActivityRecord component, boolean resumed) {
2821        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2822        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2823        if (resumed) {
2824            mUsageStatsService.noteResumeComponent(component.realActivity);
2825            synchronized (stats) {
2826                stats.noteActivityResumedLocked(component.app.uid);
2827            }
2828        } else {
2829            mUsageStatsService.notePauseComponent(component.realActivity);
2830            synchronized (stats) {
2831                stats.noteActivityPausedLocked(component.app.uid);
2832            }
2833        }
2834    }
2835
2836    Intent getHomeIntent() {
2837        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2838        intent.setComponent(mTopComponent);
2839        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2840            intent.addCategory(Intent.CATEGORY_HOME);
2841        }
2842        return intent;
2843    }
2844
2845    boolean startHomeActivityLocked(int userId) {
2846        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2847                && mTopAction == null) {
2848            // We are running in factory test mode, but unable to find
2849            // the factory test app, so just sit around displaying the
2850            // error message and don't try to start anything.
2851            return false;
2852        }
2853        Intent intent = getHomeIntent();
2854        ActivityInfo aInfo =
2855            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2856        if (aInfo != null) {
2857            intent.setComponent(new ComponentName(
2858                    aInfo.applicationInfo.packageName, aInfo.name));
2859            // Don't do this if the home app is currently being
2860            // instrumented.
2861            aInfo = new ActivityInfo(aInfo);
2862            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2863            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2864                    aInfo.applicationInfo.uid, true);
2865            if (app == null || app.instrumentationClass == null) {
2866                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2867                mStackSupervisor.startHomeActivity(intent, aInfo);
2868            }
2869        }
2870
2871        return true;
2872    }
2873
2874    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2875        ActivityInfo ai = null;
2876        ComponentName comp = intent.getComponent();
2877        try {
2878            if (comp != null) {
2879                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2880            } else {
2881                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2882                        intent,
2883                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2884                            flags, userId);
2885
2886                if (info != null) {
2887                    ai = info.activityInfo;
2888                }
2889            }
2890        } catch (RemoteException e) {
2891            // ignore
2892        }
2893
2894        return ai;
2895    }
2896
2897    /**
2898     * Starts the "new version setup screen" if appropriate.
2899     */
2900    void startSetupActivityLocked() {
2901        // Only do this once per boot.
2902        if (mCheckedForSetup) {
2903            return;
2904        }
2905
2906        // We will show this screen if the current one is a different
2907        // version than the last one shown, and we are not running in
2908        // low-level factory test mode.
2909        final ContentResolver resolver = mContext.getContentResolver();
2910        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2911                Settings.Global.getInt(resolver,
2912                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2913            mCheckedForSetup = true;
2914
2915            // See if we should be showing the platform update setup UI.
2916            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2917            List<ResolveInfo> ris = mContext.getPackageManager()
2918                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2919
2920            // We don't allow third party apps to replace this.
2921            ResolveInfo ri = null;
2922            for (int i=0; ris != null && i<ris.size(); i++) {
2923                if ((ris.get(i).activityInfo.applicationInfo.flags
2924                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2925                    ri = ris.get(i);
2926                    break;
2927                }
2928            }
2929
2930            if (ri != null) {
2931                String vers = ri.activityInfo.metaData != null
2932                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2933                        : null;
2934                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2935                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2936                            Intent.METADATA_SETUP_VERSION);
2937                }
2938                String lastVers = Settings.Secure.getString(
2939                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2940                if (vers != null && !vers.equals(lastVers)) {
2941                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2942                    intent.setComponent(new ComponentName(
2943                            ri.activityInfo.packageName, ri.activityInfo.name));
2944                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2945                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2946                }
2947            }
2948        }
2949    }
2950
2951    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2952        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2953    }
2954
2955    void enforceNotIsolatedCaller(String caller) {
2956        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2957            throw new SecurityException("Isolated process not allowed to call " + caller);
2958        }
2959    }
2960
2961    @Override
2962    public int getFrontActivityScreenCompatMode() {
2963        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2964        synchronized (this) {
2965            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2966        }
2967    }
2968
2969    @Override
2970    public void setFrontActivityScreenCompatMode(int mode) {
2971        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2972                "setFrontActivityScreenCompatMode");
2973        synchronized (this) {
2974            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2975        }
2976    }
2977
2978    @Override
2979    public int getPackageScreenCompatMode(String packageName) {
2980        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2981        synchronized (this) {
2982            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2983        }
2984    }
2985
2986    @Override
2987    public void setPackageScreenCompatMode(String packageName, int mode) {
2988        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2989                "setPackageScreenCompatMode");
2990        synchronized (this) {
2991            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2992        }
2993    }
2994
2995    @Override
2996    public boolean getPackageAskScreenCompat(String packageName) {
2997        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2998        synchronized (this) {
2999            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3000        }
3001    }
3002
3003    @Override
3004    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3005        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3006                "setPackageAskScreenCompat");
3007        synchronized (this) {
3008            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3009        }
3010    }
3011
3012    private void dispatchProcessesChanged() {
3013        int N;
3014        synchronized (this) {
3015            N = mPendingProcessChanges.size();
3016            if (mActiveProcessChanges.length < N) {
3017                mActiveProcessChanges = new ProcessChangeItem[N];
3018            }
3019            mPendingProcessChanges.toArray(mActiveProcessChanges);
3020            mAvailProcessChanges.addAll(mPendingProcessChanges);
3021            mPendingProcessChanges.clear();
3022            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3023        }
3024
3025        int i = mProcessObservers.beginBroadcast();
3026        while (i > 0) {
3027            i--;
3028            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3029            if (observer != null) {
3030                try {
3031                    for (int j=0; j<N; j++) {
3032                        ProcessChangeItem item = mActiveProcessChanges[j];
3033                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3034                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3035                                    + item.pid + " uid=" + item.uid + ": "
3036                                    + item.foregroundActivities);
3037                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3038                                    item.foregroundActivities);
3039                        }
3040                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3041                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3042                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3043                            observer.onImportanceChanged(item.pid, item.uid,
3044                                    item.importance);
3045                        }
3046                    }
3047                } catch (RemoteException e) {
3048                }
3049            }
3050        }
3051        mProcessObservers.finishBroadcast();
3052    }
3053
3054    private void dispatchProcessDied(int pid, int uid) {
3055        int i = mProcessObservers.beginBroadcast();
3056        while (i > 0) {
3057            i--;
3058            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3059            if (observer != null) {
3060                try {
3061                    observer.onProcessDied(pid, uid);
3062                } catch (RemoteException e) {
3063                }
3064            }
3065        }
3066        mProcessObservers.finishBroadcast();
3067    }
3068
3069    final void doPendingActivityLaunchesLocked(boolean doResume) {
3070        final int N = mPendingActivityLaunches.size();
3071        if (N <= 0) {
3072            return;
3073        }
3074        for (int i=0; i<N; i++) {
3075            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3076            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3077                    doResume && i == (N-1), null);
3078        }
3079        mPendingActivityLaunches.clear();
3080    }
3081
3082    @Override
3083    public final int startActivity(IApplicationThread caller, String callingPackage,
3084            Intent intent, String resolvedType, IBinder resultTo,
3085            String resultWho, int requestCode, int startFlags,
3086            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3087        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3088                resultWho, requestCode,
3089                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3090    }
3091
3092    @Override
3093    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3094            Intent intent, String resolvedType, IBinder resultTo,
3095            String resultWho, int requestCode, int startFlags,
3096            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3097        enforceNotIsolatedCaller("startActivity");
3098        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3099                false, true, "startActivity", null);
3100        // TODO: Switch to user app stacks here.
3101        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3102                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3103                null, null, options, userId, null);
3104    }
3105
3106    @Override
3107    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3108            Intent intent, String resolvedType, IBinder resultTo,
3109            String resultWho, int requestCode, int startFlags, String profileFile,
3110            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3111        enforceNotIsolatedCaller("startActivityAndWait");
3112        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3113                false, true, "startActivityAndWait", null);
3114        WaitResult res = new WaitResult();
3115        // TODO: Switch to user app stacks here.
3116        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3117                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3118                res, null, options, UserHandle.getCallingUserId(), null);
3119        return res;
3120    }
3121
3122    @Override
3123    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3124            Intent intent, String resolvedType, IBinder resultTo,
3125            String resultWho, int requestCode, int startFlags, Configuration config,
3126            Bundle options, int userId) {
3127        enforceNotIsolatedCaller("startActivityWithConfig");
3128        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3129                false, true, "startActivityWithConfig", null);
3130        // TODO: Switch to user app stacks here.
3131        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3132                resolvedType, resultTo, resultWho, requestCode, startFlags,
3133                null, null, null, config, options, userId, null);
3134        return ret;
3135    }
3136
3137    @Override
3138    public int startActivityIntentSender(IApplicationThread caller,
3139            IntentSender intent, Intent fillInIntent, String resolvedType,
3140            IBinder resultTo, String resultWho, int requestCode,
3141            int flagsMask, int flagsValues, Bundle options) {
3142        enforceNotIsolatedCaller("startActivityIntentSender");
3143        // Refuse possible leaked file descriptors
3144        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3145            throw new IllegalArgumentException("File descriptors passed in Intent");
3146        }
3147
3148        IIntentSender sender = intent.getTarget();
3149        if (!(sender instanceof PendingIntentRecord)) {
3150            throw new IllegalArgumentException("Bad PendingIntent object");
3151        }
3152
3153        PendingIntentRecord pir = (PendingIntentRecord)sender;
3154
3155        synchronized (this) {
3156            // If this is coming from the currently resumed activity, it is
3157            // effectively saying that app switches are allowed at this point.
3158            final ActivityStack stack = getFocusedStack();
3159            if (stack.mResumedActivity != null &&
3160                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3161                mAppSwitchesAllowedTime = 0;
3162            }
3163        }
3164        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3165                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3166        return ret;
3167    }
3168
3169    @Override
3170    public boolean startNextMatchingActivity(IBinder callingActivity,
3171            Intent intent, Bundle options) {
3172        // Refuse possible leaked file descriptors
3173        if (intent != null && intent.hasFileDescriptors() == true) {
3174            throw new IllegalArgumentException("File descriptors passed in Intent");
3175        }
3176
3177        synchronized (this) {
3178            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3179            if (r == null) {
3180                ActivityOptions.abort(options);
3181                return false;
3182            }
3183            if (r.app == null || r.app.thread == null) {
3184                // The caller is not running...  d'oh!
3185                ActivityOptions.abort(options);
3186                return false;
3187            }
3188            intent = new Intent(intent);
3189            // The caller is not allowed to change the data.
3190            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3191            // And we are resetting to find the next component...
3192            intent.setComponent(null);
3193
3194            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3195
3196            ActivityInfo aInfo = null;
3197            try {
3198                List<ResolveInfo> resolves =
3199                    AppGlobals.getPackageManager().queryIntentActivities(
3200                            intent, r.resolvedType,
3201                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3202                            UserHandle.getCallingUserId());
3203
3204                // Look for the original activity in the list...
3205                final int N = resolves != null ? resolves.size() : 0;
3206                for (int i=0; i<N; i++) {
3207                    ResolveInfo rInfo = resolves.get(i);
3208                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3209                            && rInfo.activityInfo.name.equals(r.info.name)) {
3210                        // We found the current one...  the next matching is
3211                        // after it.
3212                        i++;
3213                        if (i<N) {
3214                            aInfo = resolves.get(i).activityInfo;
3215                        }
3216                        if (debug) {
3217                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3218                                    + "/" + r.info.name);
3219                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3220                                    + "/" + aInfo.name);
3221                        }
3222                        break;
3223                    }
3224                }
3225            } catch (RemoteException e) {
3226            }
3227
3228            if (aInfo == null) {
3229                // Nobody who is next!
3230                ActivityOptions.abort(options);
3231                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3232                return false;
3233            }
3234
3235            intent.setComponent(new ComponentName(
3236                    aInfo.applicationInfo.packageName, aInfo.name));
3237            intent.setFlags(intent.getFlags()&~(
3238                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3239                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3240                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3241                    Intent.FLAG_ACTIVITY_NEW_TASK));
3242
3243            // Okay now we need to start the new activity, replacing the
3244            // currently running activity.  This is a little tricky because
3245            // we want to start the new one as if the current one is finished,
3246            // but not finish the current one first so that there is no flicker.
3247            // And thus...
3248            final boolean wasFinishing = r.finishing;
3249            r.finishing = true;
3250
3251            // Propagate reply information over to the new activity.
3252            final ActivityRecord resultTo = r.resultTo;
3253            final String resultWho = r.resultWho;
3254            final int requestCode = r.requestCode;
3255            r.resultTo = null;
3256            if (resultTo != null) {
3257                resultTo.removeResultsLocked(r, resultWho, requestCode);
3258            }
3259
3260            final long origId = Binder.clearCallingIdentity();
3261            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3262                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3263                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3264                    options, false, null, null);
3265            Binder.restoreCallingIdentity(origId);
3266
3267            r.finishing = wasFinishing;
3268            if (res != ActivityManager.START_SUCCESS) {
3269                return false;
3270            }
3271            return true;
3272        }
3273    }
3274
3275    final int startActivityInPackage(int uid, String callingPackage,
3276            Intent intent, String resolvedType, IBinder resultTo,
3277            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3278                    IActivityContainer container) {
3279
3280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3281                false, true, "startActivityInPackage", null);
3282
3283        // TODO: Switch to user app stacks here.
3284        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3285                resultTo, resultWho, requestCode, startFlags,
3286                null, null, null, null, options, userId, container);
3287        return ret;
3288    }
3289
3290    @Override
3291    public final int startActivities(IApplicationThread caller, String callingPackage,
3292            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3293            int userId) {
3294        enforceNotIsolatedCaller("startActivities");
3295        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3296                false, true, "startActivity", null);
3297        // TODO: Switch to user app stacks here.
3298        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3299                resolvedTypes, resultTo, options, userId);
3300        return ret;
3301    }
3302
3303    final int startActivitiesInPackage(int uid, String callingPackage,
3304            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3305            Bundle options, int userId) {
3306
3307        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3308                false, true, "startActivityInPackage", null);
3309        // TODO: Switch to user app stacks here.
3310        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3311                resultTo, options, userId);
3312        return ret;
3313    }
3314
3315    final void addRecentTaskLocked(TaskRecord task) {
3316        int N = mRecentTasks.size();
3317        // Quick case: check if the top-most recent task is the same.
3318        if (N > 0 && mRecentTasks.get(0) == task) {
3319            return;
3320        }
3321        // Remove any existing entries that are the same kind of task.
3322        for (int i=0; i<N; i++) {
3323            TaskRecord tr = mRecentTasks.get(i);
3324            if (task.userId == tr.userId
3325                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3326                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3327                tr.disposeThumbnail();
3328                mRecentTasks.remove(i);
3329                i--;
3330                N--;
3331                if (task.intent == null) {
3332                    // If the new recent task we are adding is not fully
3333                    // specified, then replace it with the existing recent task.
3334                    task = tr;
3335                }
3336            }
3337        }
3338        if (N >= MAX_RECENT_TASKS) {
3339            mRecentTasks.remove(N-1).disposeThumbnail();
3340        }
3341        mRecentTasks.add(0, task);
3342    }
3343
3344    @Override
3345    public void reportActivityFullyDrawn(IBinder token) {
3346        synchronized (this) {
3347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3348            if (r == null) {
3349                return;
3350            }
3351            r.reportFullyDrawnLocked();
3352        }
3353    }
3354
3355    @Override
3356    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3357        synchronized (this) {
3358            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3359            if (r == null) {
3360                return;
3361            }
3362            final long origId = Binder.clearCallingIdentity();
3363            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3364            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3365                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3366            if (config != null) {
3367                r.frozenBeforeDestroy = true;
3368                if (!updateConfigurationLocked(config, r, false, false)) {
3369                    mStackSupervisor.resumeTopActivitiesLocked();
3370                }
3371            }
3372            Binder.restoreCallingIdentity(origId);
3373        }
3374    }
3375
3376    @Override
3377    public int getRequestedOrientation(IBinder token) {
3378        synchronized (this) {
3379            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3380            if (r == null) {
3381                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3382            }
3383            return mWindowManager.getAppOrientation(r.appToken);
3384        }
3385    }
3386
3387    /**
3388     * This is the internal entry point for handling Activity.finish().
3389     *
3390     * @param token The Binder token referencing the Activity we want to finish.
3391     * @param resultCode Result code, if any, from this Activity.
3392     * @param resultData Result data (Intent), if any, from this Activity.
3393     *
3394     * @return Returns true if the activity successfully finished, or false if it is still running.
3395     */
3396    @Override
3397    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3398        // Refuse possible leaked file descriptors
3399        if (resultData != null && resultData.hasFileDescriptors() == true) {
3400            throw new IllegalArgumentException("File descriptors passed in Intent");
3401        }
3402
3403        synchronized(this) {
3404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3405            if (r == null) {
3406                return true;
3407            }
3408            if (mController != null) {
3409                // Find the first activity that is not finishing.
3410                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3411                if (next != null) {
3412                    // ask watcher if this is allowed
3413                    boolean resumeOK = true;
3414                    try {
3415                        resumeOK = mController.activityResuming(next.packageName);
3416                    } catch (RemoteException e) {
3417                        mController = null;
3418                        Watchdog.getInstance().setActivityController(null);
3419                    }
3420
3421                    if (!resumeOK) {
3422                        return false;
3423                    }
3424                }
3425            }
3426            final long origId = Binder.clearCallingIdentity();
3427            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3428                    resultData, "app-request", true);
3429            Binder.restoreCallingIdentity(origId);
3430            return res;
3431        }
3432    }
3433
3434    @Override
3435    public final void finishHeavyWeightApp() {
3436        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3437                != PackageManager.PERMISSION_GRANTED) {
3438            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3439                    + Binder.getCallingPid()
3440                    + ", uid=" + Binder.getCallingUid()
3441                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3442            Slog.w(TAG, msg);
3443            throw new SecurityException(msg);
3444        }
3445
3446        synchronized(this) {
3447            if (mHeavyWeightProcess == null) {
3448                return;
3449            }
3450
3451            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3452                    mHeavyWeightProcess.activities);
3453            for (int i=0; i<activities.size(); i++) {
3454                ActivityRecord r = activities.get(i);
3455                if (!r.finishing) {
3456                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3457                            null, "finish-heavy", true);
3458                }
3459            }
3460
3461            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3462                    mHeavyWeightProcess.userId, 0));
3463            mHeavyWeightProcess = null;
3464        }
3465    }
3466
3467    @Override
3468    public void crashApplication(int uid, int initialPid, String packageName,
3469            String message) {
3470        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3471                != PackageManager.PERMISSION_GRANTED) {
3472            String msg = "Permission Denial: crashApplication() from pid="
3473                    + Binder.getCallingPid()
3474                    + ", uid=" + Binder.getCallingUid()
3475                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3476            Slog.w(TAG, msg);
3477            throw new SecurityException(msg);
3478        }
3479
3480        synchronized(this) {
3481            ProcessRecord proc = null;
3482
3483            // Figure out which process to kill.  We don't trust that initialPid
3484            // still has any relation to current pids, so must scan through the
3485            // list.
3486            synchronized (mPidsSelfLocked) {
3487                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3488                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3489                    if (p.uid != uid) {
3490                        continue;
3491                    }
3492                    if (p.pid == initialPid) {
3493                        proc = p;
3494                        break;
3495                    }
3496                    if (p.pkgList.containsKey(packageName)) {
3497                        proc = p;
3498                    }
3499                }
3500            }
3501
3502            if (proc == null) {
3503                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3504                        + " initialPid=" + initialPid
3505                        + " packageName=" + packageName);
3506                return;
3507            }
3508
3509            if (proc.thread != null) {
3510                if (proc.pid == Process.myPid()) {
3511                    Log.w(TAG, "crashApplication: trying to crash self!");
3512                    return;
3513                }
3514                long ident = Binder.clearCallingIdentity();
3515                try {
3516                    proc.thread.scheduleCrash(message);
3517                } catch (RemoteException e) {
3518                }
3519                Binder.restoreCallingIdentity(ident);
3520            }
3521        }
3522    }
3523
3524    @Override
3525    public final void finishSubActivity(IBinder token, String resultWho,
3526            int requestCode) {
3527        synchronized(this) {
3528            final long origId = Binder.clearCallingIdentity();
3529            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3530            if (r != null) {
3531                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3532            }
3533            Binder.restoreCallingIdentity(origId);
3534        }
3535    }
3536
3537    @Override
3538    public boolean finishActivityAffinity(IBinder token) {
3539        synchronized(this) {
3540            final long origId = Binder.clearCallingIdentity();
3541            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3542            boolean res = false;
3543            if (r != null) {
3544                res = r.task.stack.finishActivityAffinityLocked(r);
3545            }
3546            Binder.restoreCallingIdentity(origId);
3547            return res;
3548        }
3549    }
3550
3551    @Override
3552    public boolean willActivityBeVisible(IBinder token) {
3553        synchronized(this) {
3554            ActivityStack stack = ActivityRecord.getStackLocked(token);
3555            if (stack != null) {
3556                return stack.willActivityBeVisibleLocked(token);
3557            }
3558            return false;
3559        }
3560    }
3561
3562    @Override
3563    public void overridePendingTransition(IBinder token, String packageName,
3564            int enterAnim, int exitAnim) {
3565        synchronized(this) {
3566            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3567            if (self == null) {
3568                return;
3569            }
3570
3571            final long origId = Binder.clearCallingIdentity();
3572
3573            if (self.state == ActivityState.RESUMED
3574                    || self.state == ActivityState.PAUSING) {
3575                mWindowManager.overridePendingAppTransition(packageName,
3576                        enterAnim, exitAnim, null);
3577            }
3578
3579            Binder.restoreCallingIdentity(origId);
3580        }
3581    }
3582
3583    /**
3584     * Main function for removing an existing process from the activity manager
3585     * as a result of that process going away.  Clears out all connections
3586     * to the process.
3587     */
3588    private final void handleAppDiedLocked(ProcessRecord app,
3589            boolean restarting, boolean allowRestart) {
3590        int pid = app.pid;
3591        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3592        if (!restarting) {
3593            removeLruProcessLocked(app);
3594            if (pid > 0) {
3595                ProcessList.remove(pid);
3596            }
3597        }
3598
3599        if (mProfileProc == app) {
3600            clearProfilerLocked();
3601        }
3602
3603        // Remove this application's activities from active lists.
3604        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3605
3606        app.activities.clear();
3607
3608        if (app.instrumentationClass != null) {
3609            Slog.w(TAG, "Crash of app " + app.processName
3610                  + " running instrumentation " + app.instrumentationClass);
3611            Bundle info = new Bundle();
3612            info.putString("shortMsg", "Process crashed.");
3613            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3614        }
3615
3616        if (!restarting) {
3617            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3618                // If there was nothing to resume, and we are not already
3619                // restarting this process, but there is a visible activity that
3620                // is hosted by the process...  then make sure all visible
3621                // activities are running, taking care of restarting this
3622                // process.
3623                if (hasVisibleActivities) {
3624                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3625                }
3626            }
3627        }
3628    }
3629
3630    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3631        IBinder threadBinder = thread.asBinder();
3632        // Find the application record.
3633        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3634            ProcessRecord rec = mLruProcesses.get(i);
3635            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3636                return i;
3637            }
3638        }
3639        return -1;
3640    }
3641
3642    final ProcessRecord getRecordForAppLocked(
3643            IApplicationThread thread) {
3644        if (thread == null) {
3645            return null;
3646        }
3647
3648        int appIndex = getLRURecordIndexForAppLocked(thread);
3649        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3650    }
3651
3652    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3653        // If there are no longer any background processes running,
3654        // and the app that died was not running instrumentation,
3655        // then tell everyone we are now low on memory.
3656        boolean haveBg = false;
3657        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3658            ProcessRecord rec = mLruProcesses.get(i);
3659            if (rec.thread != null
3660                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3661                haveBg = true;
3662                break;
3663            }
3664        }
3665
3666        if (!haveBg) {
3667            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3668            if (doReport) {
3669                long now = SystemClock.uptimeMillis();
3670                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3671                    doReport = false;
3672                } else {
3673                    mLastMemUsageReportTime = now;
3674                }
3675            }
3676            final ArrayList<ProcessMemInfo> memInfos
3677                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3678            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3679            long now = SystemClock.uptimeMillis();
3680            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3681                ProcessRecord rec = mLruProcesses.get(i);
3682                if (rec == dyingProc || rec.thread == null) {
3683                    continue;
3684                }
3685                if (doReport) {
3686                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3687                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3688                }
3689                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3690                    // The low memory report is overriding any current
3691                    // state for a GC request.  Make sure to do
3692                    // heavy/important/visible/foreground processes first.
3693                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3694                        rec.lastRequestedGc = 0;
3695                    } else {
3696                        rec.lastRequestedGc = rec.lastLowMemory;
3697                    }
3698                    rec.reportLowMemory = true;
3699                    rec.lastLowMemory = now;
3700                    mProcessesToGc.remove(rec);
3701                    addProcessToGcListLocked(rec);
3702                }
3703            }
3704            if (doReport) {
3705                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3706                mHandler.sendMessage(msg);
3707            }
3708            scheduleAppGcsLocked();
3709        }
3710    }
3711
3712    final void appDiedLocked(ProcessRecord app, int pid,
3713            IApplicationThread thread) {
3714
3715        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3716        synchronized (stats) {
3717            stats.noteProcessDiedLocked(app.info.uid, pid);
3718        }
3719
3720        // Clean up already done if the process has been re-started.
3721        if (app.pid == pid && app.thread != null &&
3722                app.thread.asBinder() == thread.asBinder()) {
3723            boolean doLowMem = app.instrumentationClass == null;
3724            boolean doOomAdj = doLowMem;
3725            if (!app.killedByAm) {
3726                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3727                        + ") has died.");
3728                mAllowLowerMemLevel = true;
3729            } else {
3730                // Note that we always want to do oom adj to update our state with the
3731                // new number of procs.
3732                mAllowLowerMemLevel = false;
3733                doLowMem = false;
3734            }
3735            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3736            if (DEBUG_CLEANUP) Slog.v(
3737                TAG, "Dying app: " + app + ", pid: " + pid
3738                + ", thread: " + thread.asBinder());
3739            handleAppDiedLocked(app, false, true);
3740
3741            if (doOomAdj) {
3742                updateOomAdjLocked();
3743            }
3744            if (doLowMem) {
3745                doLowMemReportIfNeededLocked(app);
3746            }
3747        } else if (app.pid != pid) {
3748            // A new process has already been started.
3749            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3750                    + ") has died and restarted (pid " + app.pid + ").");
3751            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3752        } else if (DEBUG_PROCESSES) {
3753            Slog.d(TAG, "Received spurious death notification for thread "
3754                    + thread.asBinder());
3755        }
3756    }
3757
3758    /**
3759     * If a stack trace dump file is configured, dump process stack traces.
3760     * @param clearTraces causes the dump file to be erased prior to the new
3761     *    traces being written, if true; when false, the new traces will be
3762     *    appended to any existing file content.
3763     * @param firstPids of dalvik VM processes to dump stack traces for first
3764     * @param lastPids of dalvik VM processes to dump stack traces for last
3765     * @param nativeProcs optional list of native process names to dump stack crawls
3766     * @return file containing stack traces, or null if no dump file is configured
3767     */
3768    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3769            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3770        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3771        if (tracesPath == null || tracesPath.length() == 0) {
3772            return null;
3773        }
3774
3775        File tracesFile = new File(tracesPath);
3776        try {
3777            File tracesDir = tracesFile.getParentFile();
3778            if (!tracesDir.exists()) {
3779                tracesFile.mkdirs();
3780                if (!SELinux.restorecon(tracesDir)) {
3781                    return null;
3782                }
3783            }
3784            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3785
3786            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3787            tracesFile.createNewFile();
3788            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3789        } catch (IOException e) {
3790            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3791            return null;
3792        }
3793
3794        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3795        return tracesFile;
3796    }
3797
3798    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3799            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3800        // Use a FileObserver to detect when traces finish writing.
3801        // The order of traces is considered important to maintain for legibility.
3802        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3803            @Override
3804            public synchronized void onEvent(int event, String path) { notify(); }
3805        };
3806
3807        try {
3808            observer.startWatching();
3809
3810            // First collect all of the stacks of the most important pids.
3811            if (firstPids != null) {
3812                try {
3813                    int num = firstPids.size();
3814                    for (int i = 0; i < num; i++) {
3815                        synchronized (observer) {
3816                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3817                            observer.wait(200);  // Wait for write-close, give up after 200msec
3818                        }
3819                    }
3820                } catch (InterruptedException e) {
3821                    Log.wtf(TAG, e);
3822                }
3823            }
3824
3825            // Next collect the stacks of the native pids
3826            if (nativeProcs != null) {
3827                int[] pids = Process.getPidsForCommands(nativeProcs);
3828                if (pids != null) {
3829                    for (int pid : pids) {
3830                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3831                    }
3832                }
3833            }
3834
3835            // Lastly, measure CPU usage.
3836            if (processCpuTracker != null) {
3837                processCpuTracker.init();
3838                System.gc();
3839                processCpuTracker.update();
3840                try {
3841                    synchronized (processCpuTracker) {
3842                        processCpuTracker.wait(500); // measure over 1/2 second.
3843                    }
3844                } catch (InterruptedException e) {
3845                }
3846                processCpuTracker.update();
3847
3848                // We'll take the stack crawls of just the top apps using CPU.
3849                final int N = processCpuTracker.countWorkingStats();
3850                int numProcs = 0;
3851                for (int i=0; i<N && numProcs<5; i++) {
3852                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3853                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3854                        numProcs++;
3855                        try {
3856                            synchronized (observer) {
3857                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3858                                observer.wait(200);  // Wait for write-close, give up after 200msec
3859                            }
3860                        } catch (InterruptedException e) {
3861                            Log.wtf(TAG, e);
3862                        }
3863
3864                    }
3865                }
3866            }
3867        } finally {
3868            observer.stopWatching();
3869        }
3870    }
3871
3872    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3873        if (true || IS_USER_BUILD) {
3874            return;
3875        }
3876        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3877        if (tracesPath == null || tracesPath.length() == 0) {
3878            return;
3879        }
3880
3881        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3882        StrictMode.allowThreadDiskWrites();
3883        try {
3884            final File tracesFile = new File(tracesPath);
3885            final File tracesDir = tracesFile.getParentFile();
3886            final File tracesTmp = new File(tracesDir, "__tmp__");
3887            try {
3888                if (!tracesDir.exists()) {
3889                    tracesFile.mkdirs();
3890                    if (!SELinux.restorecon(tracesDir.getPath())) {
3891                        return;
3892                    }
3893                }
3894                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3895
3896                if (tracesFile.exists()) {
3897                    tracesTmp.delete();
3898                    tracesFile.renameTo(tracesTmp);
3899                }
3900                StringBuilder sb = new StringBuilder();
3901                Time tobj = new Time();
3902                tobj.set(System.currentTimeMillis());
3903                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3904                sb.append(": ");
3905                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3906                sb.append(" since ");
3907                sb.append(msg);
3908                FileOutputStream fos = new FileOutputStream(tracesFile);
3909                fos.write(sb.toString().getBytes());
3910                if (app == null) {
3911                    fos.write("\n*** No application process!".getBytes());
3912                }
3913                fos.close();
3914                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3915            } catch (IOException e) {
3916                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3917                return;
3918            }
3919
3920            if (app != null) {
3921                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3922                firstPids.add(app.pid);
3923                dumpStackTraces(tracesPath, firstPids, null, null, null);
3924            }
3925
3926            File lastTracesFile = null;
3927            File curTracesFile = null;
3928            for (int i=9; i>=0; i--) {
3929                String name = String.format(Locale.US, "slow%02d.txt", i);
3930                curTracesFile = new File(tracesDir, name);
3931                if (curTracesFile.exists()) {
3932                    if (lastTracesFile != null) {
3933                        curTracesFile.renameTo(lastTracesFile);
3934                    } else {
3935                        curTracesFile.delete();
3936                    }
3937                }
3938                lastTracesFile = curTracesFile;
3939            }
3940            tracesFile.renameTo(curTracesFile);
3941            if (tracesTmp.exists()) {
3942                tracesTmp.renameTo(tracesFile);
3943            }
3944        } finally {
3945            StrictMode.setThreadPolicy(oldPolicy);
3946        }
3947    }
3948
3949    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3950            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3951        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3952        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3953
3954        if (mController != null) {
3955            try {
3956                // 0 == continue, -1 = kill process immediately
3957                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3958                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3959            } catch (RemoteException e) {
3960                mController = null;
3961                Watchdog.getInstance().setActivityController(null);
3962            }
3963        }
3964
3965        long anrTime = SystemClock.uptimeMillis();
3966        if (MONITOR_CPU_USAGE) {
3967            updateCpuStatsNow();
3968        }
3969
3970        synchronized (this) {
3971            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3972            if (mShuttingDown) {
3973                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3974                return;
3975            } else if (app.notResponding) {
3976                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3977                return;
3978            } else if (app.crashing) {
3979                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3980                return;
3981            }
3982
3983            // In case we come through here for the same app before completing
3984            // this one, mark as anring now so we will bail out.
3985            app.notResponding = true;
3986
3987            // Log the ANR to the event log.
3988            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3989                    app.processName, app.info.flags, annotation);
3990
3991            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3992            firstPids.add(app.pid);
3993
3994            int parentPid = app.pid;
3995            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3996            if (parentPid != app.pid) firstPids.add(parentPid);
3997
3998            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3999
4000            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4001                ProcessRecord r = mLruProcesses.get(i);
4002                if (r != null && r.thread != null) {
4003                    int pid = r.pid;
4004                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4005                        if (r.persistent) {
4006                            firstPids.add(pid);
4007                        } else {
4008                            lastPids.put(pid, Boolean.TRUE);
4009                        }
4010                    }
4011                }
4012            }
4013        }
4014
4015        // Log the ANR to the main log.
4016        StringBuilder info = new StringBuilder();
4017        info.setLength(0);
4018        info.append("ANR in ").append(app.processName);
4019        if (activity != null && activity.shortComponentName != null) {
4020            info.append(" (").append(activity.shortComponentName).append(")");
4021        }
4022        info.append("\n");
4023        info.append("PID: ").append(app.pid).append("\n");
4024        if (annotation != null) {
4025            info.append("Reason: ").append(annotation).append("\n");
4026        }
4027        if (parent != null && parent != activity) {
4028            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4029        }
4030
4031        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4032
4033        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4034                NATIVE_STACKS_OF_INTEREST);
4035
4036        String cpuInfo = null;
4037        if (MONITOR_CPU_USAGE) {
4038            updateCpuStatsNow();
4039            synchronized (mProcessCpuThread) {
4040                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4041            }
4042            info.append(processCpuTracker.printCurrentLoad());
4043            info.append(cpuInfo);
4044        }
4045
4046        info.append(processCpuTracker.printCurrentState(anrTime));
4047
4048        Slog.e(TAG, info.toString());
4049        if (tracesFile == null) {
4050            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4051            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4052        }
4053
4054        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4055                cpuInfo, tracesFile, null);
4056
4057        if (mController != null) {
4058            try {
4059                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4060                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4061                if (res != 0) {
4062                    if (res < 0 && app.pid != MY_PID) {
4063                        Process.killProcess(app.pid);
4064                    } else {
4065                        synchronized (this) {
4066                            mServices.scheduleServiceTimeoutLocked(app);
4067                        }
4068                    }
4069                    return;
4070                }
4071            } catch (RemoteException e) {
4072                mController = null;
4073                Watchdog.getInstance().setActivityController(null);
4074            }
4075        }
4076
4077        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4078        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4079                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4080
4081        synchronized (this) {
4082            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4083                killUnneededProcessLocked(app, "background ANR");
4084                return;
4085            }
4086
4087            // Set the app's notResponding state, and look up the errorReportReceiver
4088            makeAppNotRespondingLocked(app,
4089                    activity != null ? activity.shortComponentName : null,
4090                    annotation != null ? "ANR " + annotation : "ANR",
4091                    info.toString());
4092
4093            // Bring up the infamous App Not Responding dialog
4094            Message msg = Message.obtain();
4095            HashMap<String, Object> map = new HashMap<String, Object>();
4096            msg.what = SHOW_NOT_RESPONDING_MSG;
4097            msg.obj = map;
4098            msg.arg1 = aboveSystem ? 1 : 0;
4099            map.put("app", app);
4100            if (activity != null) {
4101                map.put("activity", activity);
4102            }
4103
4104            mHandler.sendMessage(msg);
4105        }
4106    }
4107
4108    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4109        if (!mLaunchWarningShown) {
4110            mLaunchWarningShown = true;
4111            mHandler.post(new Runnable() {
4112                @Override
4113                public void run() {
4114                    synchronized (ActivityManagerService.this) {
4115                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4116                        d.show();
4117                        mHandler.postDelayed(new Runnable() {
4118                            @Override
4119                            public void run() {
4120                                synchronized (ActivityManagerService.this) {
4121                                    d.dismiss();
4122                                    mLaunchWarningShown = false;
4123                                }
4124                            }
4125                        }, 4000);
4126                    }
4127                }
4128            });
4129        }
4130    }
4131
4132    @Override
4133    public boolean clearApplicationUserData(final String packageName,
4134            final IPackageDataObserver observer, int userId) {
4135        enforceNotIsolatedCaller("clearApplicationUserData");
4136        int uid = Binder.getCallingUid();
4137        int pid = Binder.getCallingPid();
4138        userId = handleIncomingUser(pid, uid,
4139                userId, false, true, "clearApplicationUserData", null);
4140        long callingId = Binder.clearCallingIdentity();
4141        try {
4142            IPackageManager pm = AppGlobals.getPackageManager();
4143            int pkgUid = -1;
4144            synchronized(this) {
4145                try {
4146                    pkgUid = pm.getPackageUid(packageName, userId);
4147                } catch (RemoteException e) {
4148                }
4149                if (pkgUid == -1) {
4150                    Slog.w(TAG, "Invalid packageName: " + packageName);
4151                    if (observer != null) {
4152                        try {
4153                            observer.onRemoveCompleted(packageName, false);
4154                        } catch (RemoteException e) {
4155                            Slog.i(TAG, "Observer no longer exists.");
4156                        }
4157                    }
4158                    return false;
4159                }
4160                if (uid == pkgUid || checkComponentPermission(
4161                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4162                        pid, uid, -1, true)
4163                        == PackageManager.PERMISSION_GRANTED) {
4164                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4165                } else {
4166                    throw new SecurityException("PID " + pid + " does not have permission "
4167                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4168                                    + " of package " + packageName);
4169                }
4170            }
4171
4172            try {
4173                // Clear application user data
4174                pm.clearApplicationUserData(packageName, observer, userId);
4175
4176                // Remove all permissions granted from/to this package
4177                removeUriPermissionsForPackageLocked(packageName, userId, true);
4178
4179                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4180                        Uri.fromParts("package", packageName, null));
4181                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4182                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4183                        null, null, 0, null, null, null, false, false, userId);
4184            } catch (RemoteException e) {
4185            }
4186        } finally {
4187            Binder.restoreCallingIdentity(callingId);
4188        }
4189        return true;
4190    }
4191
4192    @Override
4193    public void killBackgroundProcesses(final String packageName, int userId) {
4194        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4195                != PackageManager.PERMISSION_GRANTED &&
4196                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4197                        != PackageManager.PERMISSION_GRANTED) {
4198            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4199                    + Binder.getCallingPid()
4200                    + ", uid=" + Binder.getCallingUid()
4201                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4202            Slog.w(TAG, msg);
4203            throw new SecurityException(msg);
4204        }
4205
4206        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4207                userId, true, true, "killBackgroundProcesses", null);
4208        long callingId = Binder.clearCallingIdentity();
4209        try {
4210            IPackageManager pm = AppGlobals.getPackageManager();
4211            synchronized(this) {
4212                int appId = -1;
4213                try {
4214                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4215                } catch (RemoteException e) {
4216                }
4217                if (appId == -1) {
4218                    Slog.w(TAG, "Invalid packageName: " + packageName);
4219                    return;
4220                }
4221                killPackageProcessesLocked(packageName, appId, userId,
4222                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4223            }
4224        } finally {
4225            Binder.restoreCallingIdentity(callingId);
4226        }
4227    }
4228
4229    @Override
4230    public void killAllBackgroundProcesses() {
4231        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4232                != PackageManager.PERMISSION_GRANTED) {
4233            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4234                    + Binder.getCallingPid()
4235                    + ", uid=" + Binder.getCallingUid()
4236                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4237            Slog.w(TAG, msg);
4238            throw new SecurityException(msg);
4239        }
4240
4241        long callingId = Binder.clearCallingIdentity();
4242        try {
4243            synchronized(this) {
4244                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4245                final int NP = mProcessNames.getMap().size();
4246                for (int ip=0; ip<NP; ip++) {
4247                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4248                    final int NA = apps.size();
4249                    for (int ia=0; ia<NA; ia++) {
4250                        ProcessRecord app = apps.valueAt(ia);
4251                        if (app.persistent) {
4252                            // we don't kill persistent processes
4253                            continue;
4254                        }
4255                        if (app.removed) {
4256                            procs.add(app);
4257                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4258                            app.removed = true;
4259                            procs.add(app);
4260                        }
4261                    }
4262                }
4263
4264                int N = procs.size();
4265                for (int i=0; i<N; i++) {
4266                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4267                }
4268                mAllowLowerMemLevel = true;
4269                updateOomAdjLocked();
4270                doLowMemReportIfNeededLocked(null);
4271            }
4272        } finally {
4273            Binder.restoreCallingIdentity(callingId);
4274        }
4275    }
4276
4277    @Override
4278    public void forceStopPackage(final String packageName, int userId) {
4279        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4280                != PackageManager.PERMISSION_GRANTED) {
4281            String msg = "Permission Denial: forceStopPackage() from pid="
4282                    + Binder.getCallingPid()
4283                    + ", uid=" + Binder.getCallingUid()
4284                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4285            Slog.w(TAG, msg);
4286            throw new SecurityException(msg);
4287        }
4288        final int callingPid = Binder.getCallingPid();
4289        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4290                userId, true, true, "forceStopPackage", null);
4291        long callingId = Binder.clearCallingIdentity();
4292        try {
4293            IPackageManager pm = AppGlobals.getPackageManager();
4294            synchronized(this) {
4295                int[] users = userId == UserHandle.USER_ALL
4296                        ? getUsersLocked() : new int[] { userId };
4297                for (int user : users) {
4298                    int pkgUid = -1;
4299                    try {
4300                        pkgUid = pm.getPackageUid(packageName, user);
4301                    } catch (RemoteException e) {
4302                    }
4303                    if (pkgUid == -1) {
4304                        Slog.w(TAG, "Invalid packageName: " + packageName);
4305                        continue;
4306                    }
4307                    try {
4308                        pm.setPackageStoppedState(packageName, true, user);
4309                    } catch (RemoteException e) {
4310                    } catch (IllegalArgumentException e) {
4311                        Slog.w(TAG, "Failed trying to unstop package "
4312                                + packageName + ": " + e);
4313                    }
4314                    if (isUserRunningLocked(user, false)) {
4315                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4316                    }
4317                }
4318            }
4319        } finally {
4320            Binder.restoreCallingIdentity(callingId);
4321        }
4322    }
4323
4324    /*
4325     * The pkg name and app id have to be specified.
4326     */
4327    @Override
4328    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4329        if (pkg == null) {
4330            return;
4331        }
4332        // Make sure the uid is valid.
4333        if (appid < 0) {
4334            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4335            return;
4336        }
4337        int callerUid = Binder.getCallingUid();
4338        // Only the system server can kill an application
4339        if (callerUid == Process.SYSTEM_UID) {
4340            // Post an aysnc message to kill the application
4341            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4342            msg.arg1 = appid;
4343            msg.arg2 = 0;
4344            Bundle bundle = new Bundle();
4345            bundle.putString("pkg", pkg);
4346            bundle.putString("reason", reason);
4347            msg.obj = bundle;
4348            mHandler.sendMessage(msg);
4349        } else {
4350            throw new SecurityException(callerUid + " cannot kill pkg: " +
4351                    pkg);
4352        }
4353    }
4354
4355    @Override
4356    public void closeSystemDialogs(String reason) {
4357        enforceNotIsolatedCaller("closeSystemDialogs");
4358
4359        final int pid = Binder.getCallingPid();
4360        final int uid = Binder.getCallingUid();
4361        final long origId = Binder.clearCallingIdentity();
4362        try {
4363            synchronized (this) {
4364                // Only allow this from foreground processes, so that background
4365                // applications can't abuse it to prevent system UI from being shown.
4366                if (uid >= Process.FIRST_APPLICATION_UID) {
4367                    ProcessRecord proc;
4368                    synchronized (mPidsSelfLocked) {
4369                        proc = mPidsSelfLocked.get(pid);
4370                    }
4371                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4372                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4373                                + " from background process " + proc);
4374                        return;
4375                    }
4376                }
4377                closeSystemDialogsLocked(reason);
4378            }
4379        } finally {
4380            Binder.restoreCallingIdentity(origId);
4381        }
4382    }
4383
4384    void closeSystemDialogsLocked(String reason) {
4385        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4386        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4387                | Intent.FLAG_RECEIVER_FOREGROUND);
4388        if (reason != null) {
4389            intent.putExtra("reason", reason);
4390        }
4391        mWindowManager.closeSystemDialogs(reason);
4392
4393        mStackSupervisor.closeSystemDialogsLocked();
4394
4395        broadcastIntentLocked(null, null, intent, null,
4396                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4397                Process.SYSTEM_UID, UserHandle.USER_ALL);
4398    }
4399
4400    @Override
4401    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4402        enforceNotIsolatedCaller("getProcessMemoryInfo");
4403        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4404        for (int i=pids.length-1; i>=0; i--) {
4405            ProcessRecord proc;
4406            int oomAdj;
4407            synchronized (this) {
4408                synchronized (mPidsSelfLocked) {
4409                    proc = mPidsSelfLocked.get(pids[i]);
4410                    oomAdj = proc != null ? proc.setAdj : 0;
4411                }
4412            }
4413            infos[i] = new Debug.MemoryInfo();
4414            Debug.getMemoryInfo(pids[i], infos[i]);
4415            if (proc != null) {
4416                synchronized (this) {
4417                    if (proc.thread != null && proc.setAdj == oomAdj) {
4418                        // Record this for posterity if the process has been stable.
4419                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4420                                infos[i].getTotalUss(), false, proc.pkgList);
4421                    }
4422                }
4423            }
4424        }
4425        return infos;
4426    }
4427
4428    @Override
4429    public long[] getProcessPss(int[] pids) {
4430        enforceNotIsolatedCaller("getProcessPss");
4431        long[] pss = new long[pids.length];
4432        for (int i=pids.length-1; i>=0; i--) {
4433            ProcessRecord proc;
4434            int oomAdj;
4435            synchronized (this) {
4436                synchronized (mPidsSelfLocked) {
4437                    proc = mPidsSelfLocked.get(pids[i]);
4438                    oomAdj = proc != null ? proc.setAdj : 0;
4439                }
4440            }
4441            long[] tmpUss = new long[1];
4442            pss[i] = Debug.getPss(pids[i], tmpUss);
4443            if (proc != null) {
4444                synchronized (this) {
4445                    if (proc.thread != null && proc.setAdj == oomAdj) {
4446                        // Record this for posterity if the process has been stable.
4447                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4448                    }
4449                }
4450            }
4451        }
4452        return pss;
4453    }
4454
4455    @Override
4456    public void killApplicationProcess(String processName, int uid) {
4457        if (processName == null) {
4458            return;
4459        }
4460
4461        int callerUid = Binder.getCallingUid();
4462        // Only the system server can kill an application
4463        if (callerUid == Process.SYSTEM_UID) {
4464            synchronized (this) {
4465                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4466                if (app != null && app.thread != null) {
4467                    try {
4468                        app.thread.scheduleSuicide();
4469                    } catch (RemoteException e) {
4470                        // If the other end already died, then our work here is done.
4471                    }
4472                } else {
4473                    Slog.w(TAG, "Process/uid not found attempting kill of "
4474                            + processName + " / " + uid);
4475                }
4476            }
4477        } else {
4478            throw new SecurityException(callerUid + " cannot kill app process: " +
4479                    processName);
4480        }
4481    }
4482
4483    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4484        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4485                false, true, false, false, UserHandle.getUserId(uid), reason);
4486        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4487                Uri.fromParts("package", packageName, null));
4488        if (!mProcessesReady) {
4489            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4490                    | Intent.FLAG_RECEIVER_FOREGROUND);
4491        }
4492        intent.putExtra(Intent.EXTRA_UID, uid);
4493        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4494        broadcastIntentLocked(null, null, intent,
4495                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4496                false, false,
4497                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4498    }
4499
4500    private void forceStopUserLocked(int userId, String reason) {
4501        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4502        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4503        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4504                | Intent.FLAG_RECEIVER_FOREGROUND);
4505        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4506        broadcastIntentLocked(null, null, intent,
4507                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4508                false, false,
4509                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4510    }
4511
4512    private final boolean killPackageProcessesLocked(String packageName, int appId,
4513            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4514            boolean doit, boolean evenPersistent, String reason) {
4515        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4516
4517        // Remove all processes this package may have touched: all with the
4518        // same UID (except for the system or root user), and all whose name
4519        // matches the package name.
4520        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4521        final int NP = mProcessNames.getMap().size();
4522        for (int ip=0; ip<NP; ip++) {
4523            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4524            final int NA = apps.size();
4525            for (int ia=0; ia<NA; ia++) {
4526                ProcessRecord app = apps.valueAt(ia);
4527                if (app.persistent && !evenPersistent) {
4528                    // we don't kill persistent processes
4529                    continue;
4530                }
4531                if (app.removed) {
4532                    if (doit) {
4533                        procs.add(app);
4534                    }
4535                    continue;
4536                }
4537
4538                // Skip process if it doesn't meet our oom adj requirement.
4539                if (app.setAdj < minOomAdj) {
4540                    continue;
4541                }
4542
4543                // If no package is specified, we call all processes under the
4544                // give user id.
4545                if (packageName == null) {
4546                    if (app.userId != userId) {
4547                        continue;
4548                    }
4549                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4550                        continue;
4551                    }
4552                // Package has been specified, we want to hit all processes
4553                // that match it.  We need to qualify this by the processes
4554                // that are running under the specified app and user ID.
4555                } else {
4556                    if (UserHandle.getAppId(app.uid) != appId) {
4557                        continue;
4558                    }
4559                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4560                        continue;
4561                    }
4562                    if (!app.pkgList.containsKey(packageName)) {
4563                        continue;
4564                    }
4565                }
4566
4567                // Process has passed all conditions, kill it!
4568                if (!doit) {
4569                    return true;
4570                }
4571                app.removed = true;
4572                procs.add(app);
4573            }
4574        }
4575
4576        int N = procs.size();
4577        for (int i=0; i<N; i++) {
4578            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4579        }
4580        updateOomAdjLocked();
4581        return N > 0;
4582    }
4583
4584    private final boolean forceStopPackageLocked(String name, int appId,
4585            boolean callerWillRestart, boolean purgeCache, boolean doit,
4586            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4587        int i;
4588        int N;
4589
4590        if (userId == UserHandle.USER_ALL && name == null) {
4591            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4592        }
4593
4594        if (appId < 0 && name != null) {
4595            try {
4596                appId = UserHandle.getAppId(
4597                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4598            } catch (RemoteException e) {
4599            }
4600        }
4601
4602        if (doit) {
4603            if (name != null) {
4604                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4605                        + " user=" + userId + ": " + reason);
4606            } else {
4607                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4608            }
4609
4610            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4611            for (int ip=pmap.size()-1; ip>=0; ip--) {
4612                SparseArray<Long> ba = pmap.valueAt(ip);
4613                for (i=ba.size()-1; i>=0; i--) {
4614                    boolean remove = false;
4615                    final int entUid = ba.keyAt(i);
4616                    if (name != null) {
4617                        if (userId == UserHandle.USER_ALL) {
4618                            if (UserHandle.getAppId(entUid) == appId) {
4619                                remove = true;
4620                            }
4621                        } else {
4622                            if (entUid == UserHandle.getUid(userId, appId)) {
4623                                remove = true;
4624                            }
4625                        }
4626                    } else if (UserHandle.getUserId(entUid) == userId) {
4627                        remove = true;
4628                    }
4629                    if (remove) {
4630                        ba.removeAt(i);
4631                    }
4632                }
4633                if (ba.size() == 0) {
4634                    pmap.removeAt(ip);
4635                }
4636            }
4637        }
4638
4639        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4640                -100, callerWillRestart, true, doit, evenPersistent,
4641                name == null ? ("stop user " + userId) : ("stop " + name));
4642
4643        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4644            if (!doit) {
4645                return true;
4646            }
4647            didSomething = true;
4648        }
4649
4650        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4651            if (!doit) {
4652                return true;
4653            }
4654            didSomething = true;
4655        }
4656
4657        if (name == null) {
4658            // Remove all sticky broadcasts from this user.
4659            mStickyBroadcasts.remove(userId);
4660        }
4661
4662        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4663        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4664                userId, providers)) {
4665            if (!doit) {
4666                return true;
4667            }
4668            didSomething = true;
4669        }
4670        N = providers.size();
4671        for (i=0; i<N; i++) {
4672            removeDyingProviderLocked(null, providers.get(i), true);
4673        }
4674
4675        // Remove transient permissions granted from/to this package/user
4676        removeUriPermissionsForPackageLocked(name, userId, false);
4677
4678        if (name == null || uninstalling) {
4679            // Remove pending intents.  For now we only do this when force
4680            // stopping users, because we have some problems when doing this
4681            // for packages -- app widgets are not currently cleaned up for
4682            // such packages, so they can be left with bad pending intents.
4683            if (mIntentSenderRecords.size() > 0) {
4684                Iterator<WeakReference<PendingIntentRecord>> it
4685                        = mIntentSenderRecords.values().iterator();
4686                while (it.hasNext()) {
4687                    WeakReference<PendingIntentRecord> wpir = it.next();
4688                    if (wpir == null) {
4689                        it.remove();
4690                        continue;
4691                    }
4692                    PendingIntentRecord pir = wpir.get();
4693                    if (pir == null) {
4694                        it.remove();
4695                        continue;
4696                    }
4697                    if (name == null) {
4698                        // Stopping user, remove all objects for the user.
4699                        if (pir.key.userId != userId) {
4700                            // Not the same user, skip it.
4701                            continue;
4702                        }
4703                    } else {
4704                        if (UserHandle.getAppId(pir.uid) != appId) {
4705                            // Different app id, skip it.
4706                            continue;
4707                        }
4708                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4709                            // Different user, skip it.
4710                            continue;
4711                        }
4712                        if (!pir.key.packageName.equals(name)) {
4713                            // Different package, skip it.
4714                            continue;
4715                        }
4716                    }
4717                    if (!doit) {
4718                        return true;
4719                    }
4720                    didSomething = true;
4721                    it.remove();
4722                    pir.canceled = true;
4723                    if (pir.key.activity != null) {
4724                        pir.key.activity.pendingResults.remove(pir.ref);
4725                    }
4726                }
4727            }
4728        }
4729
4730        if (doit) {
4731            if (purgeCache && name != null) {
4732                AttributeCache ac = AttributeCache.instance();
4733                if (ac != null) {
4734                    ac.removePackage(name);
4735                }
4736            }
4737            if (mBooted) {
4738                mStackSupervisor.resumeTopActivitiesLocked();
4739                mStackSupervisor.scheduleIdleLocked();
4740            }
4741        }
4742
4743        return didSomething;
4744    }
4745
4746    private final boolean removeProcessLocked(ProcessRecord app,
4747            boolean callerWillRestart, boolean allowRestart, String reason) {
4748        final String name = app.processName;
4749        final int uid = app.uid;
4750        if (DEBUG_PROCESSES) Slog.d(
4751            TAG, "Force removing proc " + app.toShortString() + " (" + name
4752            + "/" + uid + ")");
4753
4754        mProcessNames.remove(name, uid);
4755        mIsolatedProcesses.remove(app.uid);
4756        if (mHeavyWeightProcess == app) {
4757            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4758                    mHeavyWeightProcess.userId, 0));
4759            mHeavyWeightProcess = null;
4760        }
4761        boolean needRestart = false;
4762        if (app.pid > 0 && app.pid != MY_PID) {
4763            int pid = app.pid;
4764            synchronized (mPidsSelfLocked) {
4765                mPidsSelfLocked.remove(pid);
4766                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4767            }
4768            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4769                    app.processName, app.info.uid);
4770            if (app.isolated) {
4771                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4772            }
4773            killUnneededProcessLocked(app, reason);
4774            handleAppDiedLocked(app, true, allowRestart);
4775            removeLruProcessLocked(app);
4776
4777            if (app.persistent && !app.isolated) {
4778                if (!callerWillRestart) {
4779                    addAppLocked(app.info, false);
4780                } else {
4781                    needRestart = true;
4782                }
4783            }
4784        } else {
4785            mRemovedProcesses.add(app);
4786        }
4787
4788        return needRestart;
4789    }
4790
4791    private final void processStartTimedOutLocked(ProcessRecord app) {
4792        final int pid = app.pid;
4793        boolean gone = false;
4794        synchronized (mPidsSelfLocked) {
4795            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4796            if (knownApp != null && knownApp.thread == null) {
4797                mPidsSelfLocked.remove(pid);
4798                gone = true;
4799            }
4800        }
4801
4802        if (gone) {
4803            Slog.w(TAG, "Process " + app + " failed to attach");
4804            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4805                    pid, app.uid, app.processName);
4806            mProcessNames.remove(app.processName, app.uid);
4807            mIsolatedProcesses.remove(app.uid);
4808            if (mHeavyWeightProcess == app) {
4809                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4810                        mHeavyWeightProcess.userId, 0));
4811                mHeavyWeightProcess = null;
4812            }
4813            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4814                    app.processName, app.info.uid);
4815            if (app.isolated) {
4816                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4817            }
4818            // Take care of any launching providers waiting for this process.
4819            checkAppInLaunchingProvidersLocked(app, true);
4820            // Take care of any services that are waiting for the process.
4821            mServices.processStartTimedOutLocked(app);
4822            killUnneededProcessLocked(app, "start timeout");
4823            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4824                Slog.w(TAG, "Unattached app died before backup, skipping");
4825                try {
4826                    IBackupManager bm = IBackupManager.Stub.asInterface(
4827                            ServiceManager.getService(Context.BACKUP_SERVICE));
4828                    bm.agentDisconnected(app.info.packageName);
4829                } catch (RemoteException e) {
4830                    // Can't happen; the backup manager is local
4831                }
4832            }
4833            if (isPendingBroadcastProcessLocked(pid)) {
4834                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4835                skipPendingBroadcastLocked(pid);
4836            }
4837        } else {
4838            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4839        }
4840    }
4841
4842    private final boolean attachApplicationLocked(IApplicationThread thread,
4843            int pid) {
4844
4845        // Find the application record that is being attached...  either via
4846        // the pid if we are running in multiple processes, or just pull the
4847        // next app record if we are emulating process with anonymous threads.
4848        ProcessRecord app;
4849        if (pid != MY_PID && pid >= 0) {
4850            synchronized (mPidsSelfLocked) {
4851                app = mPidsSelfLocked.get(pid);
4852            }
4853        } else {
4854            app = null;
4855        }
4856
4857        if (app == null) {
4858            Slog.w(TAG, "No pending application record for pid " + pid
4859                    + " (IApplicationThread " + thread + "); dropping process");
4860            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4861            if (pid > 0 && pid != MY_PID) {
4862                Process.killProcessQuiet(pid);
4863            } else {
4864                try {
4865                    thread.scheduleExit();
4866                } catch (Exception e) {
4867                    // Ignore exceptions.
4868                }
4869            }
4870            return false;
4871        }
4872
4873        // If this application record is still attached to a previous
4874        // process, clean it up now.
4875        if (app.thread != null) {
4876            handleAppDiedLocked(app, true, true);
4877        }
4878
4879        // Tell the process all about itself.
4880
4881        if (localLOGV) Slog.v(
4882                TAG, "Binding process pid " + pid + " to record " + app);
4883
4884        final String processName = app.processName;
4885        try {
4886            AppDeathRecipient adr = new AppDeathRecipient(
4887                    app, pid, thread);
4888            thread.asBinder().linkToDeath(adr, 0);
4889            app.deathRecipient = adr;
4890        } catch (RemoteException e) {
4891            app.resetPackageList(mProcessStats);
4892            startProcessLocked(app, "link fail", processName);
4893            return false;
4894        }
4895
4896        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4897
4898        app.makeActive(thread, mProcessStats);
4899        app.curAdj = app.setAdj = -100;
4900        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4901        app.forcingToForeground = null;
4902        updateProcessForegroundLocked(app, false, false);
4903        app.hasShownUi = false;
4904        app.debugging = false;
4905        app.cached = false;
4906
4907        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4908
4909        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4910        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4911
4912        if (!normalMode) {
4913            Slog.i(TAG, "Launching preboot mode app: " + app);
4914        }
4915
4916        if (localLOGV) Slog.v(
4917            TAG, "New app record " + app
4918            + " thread=" + thread.asBinder() + " pid=" + pid);
4919        try {
4920            int testMode = IApplicationThread.DEBUG_OFF;
4921            if (mDebugApp != null && mDebugApp.equals(processName)) {
4922                testMode = mWaitForDebugger
4923                    ? IApplicationThread.DEBUG_WAIT
4924                    : IApplicationThread.DEBUG_ON;
4925                app.debugging = true;
4926                if (mDebugTransient) {
4927                    mDebugApp = mOrigDebugApp;
4928                    mWaitForDebugger = mOrigWaitForDebugger;
4929                }
4930            }
4931            String profileFile = app.instrumentationProfileFile;
4932            ParcelFileDescriptor profileFd = null;
4933            boolean profileAutoStop = false;
4934            if (mProfileApp != null && mProfileApp.equals(processName)) {
4935                mProfileProc = app;
4936                profileFile = mProfileFile;
4937                profileFd = mProfileFd;
4938                profileAutoStop = mAutoStopProfiler;
4939            }
4940            boolean enableOpenGlTrace = false;
4941            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4942                enableOpenGlTrace = true;
4943                mOpenGlTraceApp = null;
4944            }
4945
4946            // If the app is being launched for restore or full backup, set it up specially
4947            boolean isRestrictedBackupMode = false;
4948            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4949                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4950                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4951                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4952            }
4953
4954            ensurePackageDexOpt(app.instrumentationInfo != null
4955                    ? app.instrumentationInfo.packageName
4956                    : app.info.packageName);
4957            if (app.instrumentationClass != null) {
4958                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4959            }
4960            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4961                    + processName + " with config " + mConfiguration);
4962            ApplicationInfo appInfo = app.instrumentationInfo != null
4963                    ? app.instrumentationInfo : app.info;
4964            app.compat = compatibilityInfoForPackageLocked(appInfo);
4965            if (profileFd != null) {
4966                profileFd = profileFd.dup();
4967            }
4968            thread.bindApplication(processName, appInfo, providers,
4969                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4970                    app.instrumentationArguments, app.instrumentationWatcher,
4971                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4972                    isRestrictedBackupMode || !normalMode, app.persistent,
4973                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4974                    mCoreSettingsObserver.getCoreSettingsLocked());
4975            updateLruProcessLocked(app, false, null);
4976            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4977        } catch (Exception e) {
4978            // todo: Yikes!  What should we do?  For now we will try to
4979            // start another process, but that could easily get us in
4980            // an infinite loop of restarting processes...
4981            Slog.w(TAG, "Exception thrown during bind!", e);
4982
4983            app.resetPackageList(mProcessStats);
4984            app.unlinkDeathRecipient();
4985            startProcessLocked(app, "bind fail", processName);
4986            return false;
4987        }
4988
4989        // Remove this record from the list of starting applications.
4990        mPersistentStartingProcesses.remove(app);
4991        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4992                "Attach application locked removing on hold: " + app);
4993        mProcessesOnHold.remove(app);
4994
4995        boolean badApp = false;
4996        boolean didSomething = false;
4997
4998        // See if the top visible activity is waiting to run in this process...
4999        if (normalMode) {
5000            try {
5001                if (mStackSupervisor.attachApplicationLocked(app)) {
5002                    didSomething = true;
5003                }
5004            } catch (Exception e) {
5005                badApp = true;
5006            }
5007        }
5008
5009        // Find any services that should be running in this process...
5010        if (!badApp) {
5011            try {
5012                didSomething |= mServices.attachApplicationLocked(app, processName);
5013            } catch (Exception e) {
5014                badApp = true;
5015            }
5016        }
5017
5018        // Check if a next-broadcast receiver is in this process...
5019        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5020            try {
5021                didSomething |= sendPendingBroadcastsLocked(app);
5022            } catch (Exception e) {
5023                // If the app died trying to launch the receiver we declare it 'bad'
5024                badApp = true;
5025            }
5026        }
5027
5028        // Check whether the next backup agent is in this process...
5029        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5030            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5031            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5032            try {
5033                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5034                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5035                        mBackupTarget.backupMode);
5036            } catch (Exception e) {
5037                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5038                e.printStackTrace();
5039            }
5040        }
5041
5042        if (badApp) {
5043            // todo: Also need to kill application to deal with all
5044            // kinds of exceptions.
5045            handleAppDiedLocked(app, false, true);
5046            return false;
5047        }
5048
5049        if (!didSomething) {
5050            updateOomAdjLocked();
5051        }
5052
5053        return true;
5054    }
5055
5056    @Override
5057    public final void attachApplication(IApplicationThread thread) {
5058        synchronized (this) {
5059            int callingPid = Binder.getCallingPid();
5060            final long origId = Binder.clearCallingIdentity();
5061            attachApplicationLocked(thread, callingPid);
5062            Binder.restoreCallingIdentity(origId);
5063        }
5064    }
5065
5066    @Override
5067    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5068        final long origId = Binder.clearCallingIdentity();
5069        synchronized (this) {
5070            ActivityStack stack = ActivityRecord.getStackLocked(token);
5071            if (stack != null) {
5072                ActivityRecord r =
5073                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5074                if (stopProfiling) {
5075                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5076                        try {
5077                            mProfileFd.close();
5078                        } catch (IOException e) {
5079                        }
5080                        clearProfilerLocked();
5081                    }
5082                }
5083            }
5084        }
5085        Binder.restoreCallingIdentity(origId);
5086    }
5087
5088    void enableScreenAfterBoot() {
5089        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5090                SystemClock.uptimeMillis());
5091        mWindowManager.enableScreenAfterBoot();
5092
5093        synchronized (this) {
5094            updateEventDispatchingLocked();
5095        }
5096    }
5097
5098    @Override
5099    public void showBootMessage(final CharSequence msg, final boolean always) {
5100        enforceNotIsolatedCaller("showBootMessage");
5101        mWindowManager.showBootMessage(msg, always);
5102    }
5103
5104    @Override
5105    public void dismissKeyguardOnNextActivity() {
5106        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5107        final long token = Binder.clearCallingIdentity();
5108        try {
5109            synchronized (this) {
5110                if (DEBUG_LOCKSCREEN) logLockScreen("");
5111                if (mLockScreenShown) {
5112                    mLockScreenShown = false;
5113                    comeOutOfSleepIfNeededLocked();
5114                }
5115                mStackSupervisor.setDismissKeyguard(true);
5116            }
5117        } finally {
5118            Binder.restoreCallingIdentity(token);
5119        }
5120    }
5121
5122    final void finishBooting() {
5123        IntentFilter pkgFilter = new IntentFilter();
5124        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5125        pkgFilter.addDataScheme("package");
5126        mContext.registerReceiver(new BroadcastReceiver() {
5127            @Override
5128            public void onReceive(Context context, Intent intent) {
5129                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5130                if (pkgs != null) {
5131                    for (String pkg : pkgs) {
5132                        synchronized (ActivityManagerService.this) {
5133                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5134                                    "finished booting")) {
5135                                setResultCode(Activity.RESULT_OK);
5136                                return;
5137                            }
5138                        }
5139                    }
5140                }
5141            }
5142        }, pkgFilter);
5143
5144        synchronized (this) {
5145            // Ensure that any processes we had put on hold are now started
5146            // up.
5147            final int NP = mProcessesOnHold.size();
5148            if (NP > 0) {
5149                ArrayList<ProcessRecord> procs =
5150                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5151                for (int ip=0; ip<NP; ip++) {
5152                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5153                            + procs.get(ip));
5154                    startProcessLocked(procs.get(ip), "on-hold", null);
5155                }
5156            }
5157
5158            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5159                // Start looking for apps that are abusing wake locks.
5160                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5161                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5162                // Tell anyone interested that we are done booting!
5163                SystemProperties.set("sys.boot_completed", "1");
5164                SystemProperties.set("dev.bootcomplete", "1");
5165                for (int i=0; i<mStartedUsers.size(); i++) {
5166                    UserStartedState uss = mStartedUsers.valueAt(i);
5167                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5168                        uss.mState = UserStartedState.STATE_RUNNING;
5169                        final int userId = mStartedUsers.keyAt(i);
5170                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5171                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5172                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5173                        broadcastIntentLocked(null, null, intent, null,
5174                                new IIntentReceiver.Stub() {
5175                                    @Override
5176                                    public void performReceive(Intent intent, int resultCode,
5177                                            String data, Bundle extras, boolean ordered,
5178                                            boolean sticky, int sendingUser) {
5179                                        synchronized (ActivityManagerService.this) {
5180                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5181                                                    true, false);
5182                                        }
5183                                    }
5184                                },
5185                                0, null, null,
5186                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5187                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5188                                userId);
5189                    }
5190                }
5191                scheduleStartRelatedUsersLocked();
5192            }
5193        }
5194    }
5195
5196    final void ensureBootCompleted() {
5197        boolean booting;
5198        boolean enableScreen;
5199        synchronized (this) {
5200            booting = mBooting;
5201            mBooting = false;
5202            enableScreen = !mBooted;
5203            mBooted = true;
5204        }
5205
5206        if (booting) {
5207            finishBooting();
5208        }
5209
5210        if (enableScreen) {
5211            enableScreenAfterBoot();
5212        }
5213    }
5214
5215    @Override
5216    public final void activityResumed(IBinder token) {
5217        final long origId = Binder.clearCallingIdentity();
5218        synchronized(this) {
5219            ActivityStack stack = ActivityRecord.getStackLocked(token);
5220            if (stack != null) {
5221                ActivityRecord.activityResumedLocked(token);
5222            }
5223        }
5224        Binder.restoreCallingIdentity(origId);
5225    }
5226
5227    @Override
5228    public final void activityPaused(IBinder token) {
5229        final long origId = Binder.clearCallingIdentity();
5230        synchronized(this) {
5231            ActivityStack stack = ActivityRecord.getStackLocked(token);
5232            if (stack != null) {
5233                stack.activityPausedLocked(token, false);
5234            }
5235        }
5236        Binder.restoreCallingIdentity(origId);
5237    }
5238
5239    @Override
5240    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5241            CharSequence description) {
5242        if (localLOGV) Slog.v(
5243            TAG, "Activity stopped: token=" + token);
5244
5245        // Refuse possible leaked file descriptors
5246        if (icicle != null && icicle.hasFileDescriptors()) {
5247            throw new IllegalArgumentException("File descriptors passed in Bundle");
5248        }
5249
5250        ActivityRecord r = null;
5251
5252        final long origId = Binder.clearCallingIdentity();
5253
5254        synchronized (this) {
5255            r = ActivityRecord.isInStackLocked(token);
5256            if (r != null) {
5257                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5258            }
5259        }
5260
5261        if (r != null) {
5262            sendPendingThumbnail(r, null, null, null, false);
5263        }
5264
5265        trimApplications();
5266
5267        Binder.restoreCallingIdentity(origId);
5268    }
5269
5270    @Override
5271    public final void activityDestroyed(IBinder token) {
5272        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5273        synchronized (this) {
5274            ActivityStack stack = ActivityRecord.getStackLocked(token);
5275            if (stack != null) {
5276                stack.activityDestroyedLocked(token);
5277            }
5278        }
5279    }
5280
5281    @Override
5282    public String getCallingPackage(IBinder token) {
5283        synchronized (this) {
5284            ActivityRecord r = getCallingRecordLocked(token);
5285            return r != null ? r.info.packageName : null;
5286        }
5287    }
5288
5289    @Override
5290    public ComponentName getCallingActivity(IBinder token) {
5291        synchronized (this) {
5292            ActivityRecord r = getCallingRecordLocked(token);
5293            return r != null ? r.intent.getComponent() : null;
5294        }
5295    }
5296
5297    private ActivityRecord getCallingRecordLocked(IBinder token) {
5298        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5299        if (r == null) {
5300            return null;
5301        }
5302        return r.resultTo;
5303    }
5304
5305    @Override
5306    public ComponentName getActivityClassForToken(IBinder token) {
5307        synchronized(this) {
5308            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5309            if (r == null) {
5310                return null;
5311            }
5312            return r.intent.getComponent();
5313        }
5314    }
5315
5316    @Override
5317    public String getPackageForToken(IBinder token) {
5318        synchronized(this) {
5319            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5320            if (r == null) {
5321                return null;
5322            }
5323            return r.packageName;
5324        }
5325    }
5326
5327    @Override
5328    public IIntentSender getIntentSender(int type,
5329            String packageName, IBinder token, String resultWho,
5330            int requestCode, Intent[] intents, String[] resolvedTypes,
5331            int flags, Bundle options, int userId) {
5332        enforceNotIsolatedCaller("getIntentSender");
5333        // Refuse possible leaked file descriptors
5334        if (intents != null) {
5335            if (intents.length < 1) {
5336                throw new IllegalArgumentException("Intents array length must be >= 1");
5337            }
5338            for (int i=0; i<intents.length; i++) {
5339                Intent intent = intents[i];
5340                if (intent != null) {
5341                    if (intent.hasFileDescriptors()) {
5342                        throw new IllegalArgumentException("File descriptors passed in Intent");
5343                    }
5344                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5345                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5346                        throw new IllegalArgumentException(
5347                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5348                    }
5349                    intents[i] = new Intent(intent);
5350                }
5351            }
5352            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5353                throw new IllegalArgumentException(
5354                        "Intent array length does not match resolvedTypes length");
5355            }
5356        }
5357        if (options != null) {
5358            if (options.hasFileDescriptors()) {
5359                throw new IllegalArgumentException("File descriptors passed in options");
5360            }
5361        }
5362
5363        synchronized(this) {
5364            int callingUid = Binder.getCallingUid();
5365            int origUserId = userId;
5366            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5367                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5368                    "getIntentSender", null);
5369            if (origUserId == UserHandle.USER_CURRENT) {
5370                // We don't want to evaluate this until the pending intent is
5371                // actually executed.  However, we do want to always do the
5372                // security checking for it above.
5373                userId = UserHandle.USER_CURRENT;
5374            }
5375            try {
5376                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5377                    int uid = AppGlobals.getPackageManager()
5378                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5379                    if (!UserHandle.isSameApp(callingUid, uid)) {
5380                        String msg = "Permission Denial: getIntentSender() from pid="
5381                            + Binder.getCallingPid()
5382                            + ", uid=" + Binder.getCallingUid()
5383                            + ", (need uid=" + uid + ")"
5384                            + " is not allowed to send as package " + packageName;
5385                        Slog.w(TAG, msg);
5386                        throw new SecurityException(msg);
5387                    }
5388                }
5389
5390                return getIntentSenderLocked(type, packageName, callingUid, userId,
5391                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5392
5393            } catch (RemoteException e) {
5394                throw new SecurityException(e);
5395            }
5396        }
5397    }
5398
5399    IIntentSender getIntentSenderLocked(int type, String packageName,
5400            int callingUid, int userId, IBinder token, String resultWho,
5401            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5402            Bundle options) {
5403        if (DEBUG_MU)
5404            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5405        ActivityRecord activity = null;
5406        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5407            activity = ActivityRecord.isInStackLocked(token);
5408            if (activity == null) {
5409                return null;
5410            }
5411            if (activity.finishing) {
5412                return null;
5413            }
5414        }
5415
5416        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5417        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5418        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5419        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5420                |PendingIntent.FLAG_UPDATE_CURRENT);
5421
5422        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5423                type, packageName, activity, resultWho,
5424                requestCode, intents, resolvedTypes, flags, options, userId);
5425        WeakReference<PendingIntentRecord> ref;
5426        ref = mIntentSenderRecords.get(key);
5427        PendingIntentRecord rec = ref != null ? ref.get() : null;
5428        if (rec != null) {
5429            if (!cancelCurrent) {
5430                if (updateCurrent) {
5431                    if (rec.key.requestIntent != null) {
5432                        rec.key.requestIntent.replaceExtras(intents != null ?
5433                                intents[intents.length - 1] : null);
5434                    }
5435                    if (intents != null) {
5436                        intents[intents.length-1] = rec.key.requestIntent;
5437                        rec.key.allIntents = intents;
5438                        rec.key.allResolvedTypes = resolvedTypes;
5439                    } else {
5440                        rec.key.allIntents = null;
5441                        rec.key.allResolvedTypes = null;
5442                    }
5443                }
5444                return rec;
5445            }
5446            rec.canceled = true;
5447            mIntentSenderRecords.remove(key);
5448        }
5449        if (noCreate) {
5450            return rec;
5451        }
5452        rec = new PendingIntentRecord(this, key, callingUid);
5453        mIntentSenderRecords.put(key, rec.ref);
5454        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5455            if (activity.pendingResults == null) {
5456                activity.pendingResults
5457                        = new HashSet<WeakReference<PendingIntentRecord>>();
5458            }
5459            activity.pendingResults.add(rec.ref);
5460        }
5461        return rec;
5462    }
5463
5464    @Override
5465    public void cancelIntentSender(IIntentSender sender) {
5466        if (!(sender instanceof PendingIntentRecord)) {
5467            return;
5468        }
5469        synchronized(this) {
5470            PendingIntentRecord rec = (PendingIntentRecord)sender;
5471            try {
5472                int uid = AppGlobals.getPackageManager()
5473                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5474                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5475                    String msg = "Permission Denial: cancelIntentSender() from pid="
5476                        + Binder.getCallingPid()
5477                        + ", uid=" + Binder.getCallingUid()
5478                        + " is not allowed to cancel packges "
5479                        + rec.key.packageName;
5480                    Slog.w(TAG, msg);
5481                    throw new SecurityException(msg);
5482                }
5483            } catch (RemoteException e) {
5484                throw new SecurityException(e);
5485            }
5486            cancelIntentSenderLocked(rec, true);
5487        }
5488    }
5489
5490    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5491        rec.canceled = true;
5492        mIntentSenderRecords.remove(rec.key);
5493        if (cleanActivity && rec.key.activity != null) {
5494            rec.key.activity.pendingResults.remove(rec.ref);
5495        }
5496    }
5497
5498    @Override
5499    public String getPackageForIntentSender(IIntentSender pendingResult) {
5500        if (!(pendingResult instanceof PendingIntentRecord)) {
5501            return null;
5502        }
5503        try {
5504            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5505            return res.key.packageName;
5506        } catch (ClassCastException e) {
5507        }
5508        return null;
5509    }
5510
5511    @Override
5512    public int getUidForIntentSender(IIntentSender sender) {
5513        if (sender instanceof PendingIntentRecord) {
5514            try {
5515                PendingIntentRecord res = (PendingIntentRecord)sender;
5516                return res.uid;
5517            } catch (ClassCastException e) {
5518            }
5519        }
5520        return -1;
5521    }
5522
5523    @Override
5524    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5525        if (!(pendingResult instanceof PendingIntentRecord)) {
5526            return false;
5527        }
5528        try {
5529            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5530            if (res.key.allIntents == null) {
5531                return false;
5532            }
5533            for (int i=0; i<res.key.allIntents.length; i++) {
5534                Intent intent = res.key.allIntents[i];
5535                if (intent.getPackage() != null && intent.getComponent() != null) {
5536                    return false;
5537                }
5538            }
5539            return true;
5540        } catch (ClassCastException e) {
5541        }
5542        return false;
5543    }
5544
5545    @Override
5546    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5547        if (!(pendingResult instanceof PendingIntentRecord)) {
5548            return false;
5549        }
5550        try {
5551            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5552            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5553                return true;
5554            }
5555            return false;
5556        } catch (ClassCastException e) {
5557        }
5558        return false;
5559    }
5560
5561    @Override
5562    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5563        if (!(pendingResult instanceof PendingIntentRecord)) {
5564            return null;
5565        }
5566        try {
5567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5568            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5569        } catch (ClassCastException e) {
5570        }
5571        return null;
5572    }
5573
5574    @Override
5575    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5576        if (!(pendingResult instanceof PendingIntentRecord)) {
5577            return null;
5578        }
5579        try {
5580            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5581            Intent intent = res.key.requestIntent;
5582            if (intent != null) {
5583                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5584                        || res.lastTagPrefix.equals(prefix))) {
5585                    return res.lastTag;
5586                }
5587                res.lastTagPrefix = prefix;
5588                StringBuilder sb = new StringBuilder(128);
5589                if (prefix != null) {
5590                    sb.append(prefix);
5591                }
5592                if (intent.getAction() != null) {
5593                    sb.append(intent.getAction());
5594                } else if (intent.getComponent() != null) {
5595                    intent.getComponent().appendShortString(sb);
5596                } else {
5597                    sb.append("?");
5598                }
5599                return res.lastTag = sb.toString();
5600            }
5601        } catch (ClassCastException e) {
5602        }
5603        return null;
5604    }
5605
5606    @Override
5607    public void setProcessLimit(int max) {
5608        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5609                "setProcessLimit()");
5610        synchronized (this) {
5611            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5612            mProcessLimitOverride = max;
5613        }
5614        trimApplications();
5615    }
5616
5617    @Override
5618    public int getProcessLimit() {
5619        synchronized (this) {
5620            return mProcessLimitOverride;
5621        }
5622    }
5623
5624    void foregroundTokenDied(ForegroundToken token) {
5625        synchronized (ActivityManagerService.this) {
5626            synchronized (mPidsSelfLocked) {
5627                ForegroundToken cur
5628                    = mForegroundProcesses.get(token.pid);
5629                if (cur != token) {
5630                    return;
5631                }
5632                mForegroundProcesses.remove(token.pid);
5633                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5634                if (pr == null) {
5635                    return;
5636                }
5637                pr.forcingToForeground = null;
5638                updateProcessForegroundLocked(pr, false, false);
5639            }
5640            updateOomAdjLocked();
5641        }
5642    }
5643
5644    @Override
5645    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5646        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5647                "setProcessForeground()");
5648        synchronized(this) {
5649            boolean changed = false;
5650
5651            synchronized (mPidsSelfLocked) {
5652                ProcessRecord pr = mPidsSelfLocked.get(pid);
5653                if (pr == null && isForeground) {
5654                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5655                    return;
5656                }
5657                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5658                if (oldToken != null) {
5659                    oldToken.token.unlinkToDeath(oldToken, 0);
5660                    mForegroundProcesses.remove(pid);
5661                    if (pr != null) {
5662                        pr.forcingToForeground = null;
5663                    }
5664                    changed = true;
5665                }
5666                if (isForeground && token != null) {
5667                    ForegroundToken newToken = new ForegroundToken() {
5668                        @Override
5669                        public void binderDied() {
5670                            foregroundTokenDied(this);
5671                        }
5672                    };
5673                    newToken.pid = pid;
5674                    newToken.token = token;
5675                    try {
5676                        token.linkToDeath(newToken, 0);
5677                        mForegroundProcesses.put(pid, newToken);
5678                        pr.forcingToForeground = token;
5679                        changed = true;
5680                    } catch (RemoteException e) {
5681                        // If the process died while doing this, we will later
5682                        // do the cleanup with the process death link.
5683                    }
5684                }
5685            }
5686
5687            if (changed) {
5688                updateOomAdjLocked();
5689            }
5690        }
5691    }
5692
5693    // =========================================================
5694    // PERMISSIONS
5695    // =========================================================
5696
5697    static class PermissionController extends IPermissionController.Stub {
5698        ActivityManagerService mActivityManagerService;
5699        PermissionController(ActivityManagerService activityManagerService) {
5700            mActivityManagerService = activityManagerService;
5701        }
5702
5703        @Override
5704        public boolean checkPermission(String permission, int pid, int uid) {
5705            return mActivityManagerService.checkPermission(permission, pid,
5706                    uid) == PackageManager.PERMISSION_GRANTED;
5707        }
5708    }
5709
5710    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5711        @Override
5712        public int checkComponentPermission(String permission, int pid, int uid,
5713                int owningUid, boolean exported) {
5714            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5715                    owningUid, exported);
5716        }
5717
5718        @Override
5719        public Object getAMSLock() {
5720            return ActivityManagerService.this;
5721        }
5722    }
5723
5724    /**
5725     * This can be called with or without the global lock held.
5726     */
5727    int checkComponentPermission(String permission, int pid, int uid,
5728            int owningUid, boolean exported) {
5729        // We might be performing an operation on behalf of an indirect binder
5730        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5731        // client identity accordingly before proceeding.
5732        Identity tlsIdentity = sCallerIdentity.get();
5733        if (tlsIdentity != null) {
5734            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5735                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5736            uid = tlsIdentity.uid;
5737            pid = tlsIdentity.pid;
5738        }
5739
5740        if (pid == MY_PID) {
5741            return PackageManager.PERMISSION_GRANTED;
5742        }
5743
5744        return ActivityManager.checkComponentPermission(permission, uid,
5745                owningUid, exported);
5746    }
5747
5748    /**
5749     * As the only public entry point for permissions checking, this method
5750     * can enforce the semantic that requesting a check on a null global
5751     * permission is automatically denied.  (Internally a null permission
5752     * string is used when calling {@link #checkComponentPermission} in cases
5753     * when only uid-based security is needed.)
5754     *
5755     * This can be called with or without the global lock held.
5756     */
5757    @Override
5758    public int checkPermission(String permission, int pid, int uid) {
5759        if (permission == null) {
5760            return PackageManager.PERMISSION_DENIED;
5761        }
5762        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5763    }
5764
5765    /**
5766     * Binder IPC calls go through the public entry point.
5767     * This can be called with or without the global lock held.
5768     */
5769    int checkCallingPermission(String permission) {
5770        return checkPermission(permission,
5771                Binder.getCallingPid(),
5772                UserHandle.getAppId(Binder.getCallingUid()));
5773    }
5774
5775    /**
5776     * This can be called with or without the global lock held.
5777     */
5778    void enforceCallingPermission(String permission, String func) {
5779        if (checkCallingPermission(permission)
5780                == PackageManager.PERMISSION_GRANTED) {
5781            return;
5782        }
5783
5784        String msg = "Permission Denial: " + func + " from pid="
5785                + Binder.getCallingPid()
5786                + ", uid=" + Binder.getCallingUid()
5787                + " requires " + permission;
5788        Slog.w(TAG, msg);
5789        throw new SecurityException(msg);
5790    }
5791
5792    /**
5793     * Determine if UID is holding permissions required to access {@link Uri} in
5794     * the given {@link ProviderInfo}. Final permission checking is always done
5795     * in {@link ContentProvider}.
5796     */
5797    private final boolean checkHoldingPermissionsLocked(
5798            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5799        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5800                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5801
5802        if (pi.applicationInfo.uid == uid) {
5803            return true;
5804        } else if (!pi.exported) {
5805            return false;
5806        }
5807
5808        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5809        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5810        try {
5811            // check if target holds top-level <provider> permissions
5812            if (!readMet && pi.readPermission != null
5813                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5814                readMet = true;
5815            }
5816            if (!writeMet && pi.writePermission != null
5817                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5818                writeMet = true;
5819            }
5820
5821            // track if unprotected read/write is allowed; any denied
5822            // <path-permission> below removes this ability
5823            boolean allowDefaultRead = pi.readPermission == null;
5824            boolean allowDefaultWrite = pi.writePermission == null;
5825
5826            // check if target holds any <path-permission> that match uri
5827            final PathPermission[] pps = pi.pathPermissions;
5828            if (pps != null) {
5829                final String path = uri.getPath();
5830                int i = pps.length;
5831                while (i > 0 && (!readMet || !writeMet)) {
5832                    i--;
5833                    PathPermission pp = pps[i];
5834                    if (pp.match(path)) {
5835                        if (!readMet) {
5836                            final String pprperm = pp.getReadPermission();
5837                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5838                                    + pprperm + " for " + pp.getPath()
5839                                    + ": match=" + pp.match(path)
5840                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5841                            if (pprperm != null) {
5842                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5843                                    readMet = true;
5844                                } else {
5845                                    allowDefaultRead = false;
5846                                }
5847                            }
5848                        }
5849                        if (!writeMet) {
5850                            final String ppwperm = pp.getWritePermission();
5851                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5852                                    + ppwperm + " for " + pp.getPath()
5853                                    + ": match=" + pp.match(path)
5854                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5855                            if (ppwperm != null) {
5856                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5857                                    writeMet = true;
5858                                } else {
5859                                    allowDefaultWrite = false;
5860                                }
5861                            }
5862                        }
5863                    }
5864                }
5865            }
5866
5867            // grant unprotected <provider> read/write, if not blocked by
5868            // <path-permission> above
5869            if (allowDefaultRead) readMet = true;
5870            if (allowDefaultWrite) writeMet = true;
5871
5872        } catch (RemoteException e) {
5873            return false;
5874        }
5875
5876        return readMet && writeMet;
5877    }
5878
5879    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5880        ProviderInfo pi = null;
5881        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5882        if (cpr != null) {
5883            pi = cpr.info;
5884        } else {
5885            try {
5886                pi = AppGlobals.getPackageManager().resolveContentProvider(
5887                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5888            } catch (RemoteException ex) {
5889            }
5890        }
5891        return pi;
5892    }
5893
5894    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5895        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5896        if (targetUris != null) {
5897            return targetUris.get(uri);
5898        } else {
5899            return null;
5900        }
5901    }
5902
5903    private UriPermission findOrCreateUriPermissionLocked(
5904            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5905        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5906        if (targetUris == null) {
5907            targetUris = Maps.newArrayMap();
5908            mGrantedUriPermissions.put(targetUid, targetUris);
5909        }
5910
5911        UriPermission perm = targetUris.get(uri);
5912        if (perm == null) {
5913            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5914            targetUris.put(uri, perm);
5915        }
5916
5917        return perm;
5918    }
5919
5920    private final boolean checkUriPermissionLocked(
5921            Uri uri, int uid, int modeFlags, int minStrength) {
5922        // Root gets to do everything.
5923        if (uid == 0) {
5924            return true;
5925        }
5926        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5927        if (perms == null) return false;
5928        UriPermission perm = perms.get(uri);
5929        if (perm == null) return false;
5930        return perm.getStrength(modeFlags) >= minStrength;
5931    }
5932
5933    @Override
5934    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5935        enforceNotIsolatedCaller("checkUriPermission");
5936
5937        // Another redirected-binder-call permissions check as in
5938        // {@link checkComponentPermission}.
5939        Identity tlsIdentity = sCallerIdentity.get();
5940        if (tlsIdentity != null) {
5941            uid = tlsIdentity.uid;
5942            pid = tlsIdentity.pid;
5943        }
5944
5945        // Our own process gets to do everything.
5946        if (pid == MY_PID) {
5947            return PackageManager.PERMISSION_GRANTED;
5948        }
5949        synchronized(this) {
5950            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5951                    ? PackageManager.PERMISSION_GRANTED
5952                    : PackageManager.PERMISSION_DENIED;
5953        }
5954    }
5955
5956    /**
5957     * Check if the targetPkg can be granted permission to access uri by
5958     * the callingUid using the given modeFlags.  Throws a security exception
5959     * if callingUid is not allowed to do this.  Returns the uid of the target
5960     * if the URI permission grant should be performed; returns -1 if it is not
5961     * needed (for example targetPkg already has permission to access the URI).
5962     * If you already know the uid of the target, you can supply it in
5963     * lastTargetUid else set that to -1.
5964     */
5965    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5966            Uri uri, int modeFlags, int lastTargetUid) {
5967        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5968        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5969                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5970        if (modeFlags == 0) {
5971            return -1;
5972        }
5973
5974        if (targetPkg != null) {
5975            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5976                    "Checking grant " + targetPkg + " permission to " + uri);
5977        }
5978
5979        final IPackageManager pm = AppGlobals.getPackageManager();
5980
5981        // If this is not a content: uri, we can't do anything with it.
5982        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5983            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5984                    "Can't grant URI permission for non-content URI: " + uri);
5985            return -1;
5986        }
5987
5988        final String authority = uri.getAuthority();
5989        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5990        if (pi == null) {
5991            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5992            return -1;
5993        }
5994
5995        int targetUid = lastTargetUid;
5996        if (targetUid < 0 && targetPkg != null) {
5997            try {
5998                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5999                if (targetUid < 0) {
6000                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6001                            "Can't grant URI permission no uid for: " + targetPkg);
6002                    return -1;
6003                }
6004            } catch (RemoteException ex) {
6005                return -1;
6006            }
6007        }
6008
6009        if (targetUid >= 0) {
6010            // First...  does the target actually need this permission?
6011            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6012                // No need to grant the target this permission.
6013                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6014                        "Target " + targetPkg + " already has full permission to " + uri);
6015                return -1;
6016            }
6017        } else {
6018            // First...  there is no target package, so can anyone access it?
6019            boolean allowed = pi.exported;
6020            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6021                if (pi.readPermission != null) {
6022                    allowed = false;
6023                }
6024            }
6025            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6026                if (pi.writePermission != null) {
6027                    allowed = false;
6028                }
6029            }
6030            if (allowed) {
6031                return -1;
6032            }
6033        }
6034
6035        // Second...  is the provider allowing granting of URI permissions?
6036        if (!pi.grantUriPermissions) {
6037            throw new SecurityException("Provider " + pi.packageName
6038                    + "/" + pi.name
6039                    + " does not allow granting of Uri permissions (uri "
6040                    + uri + ")");
6041        }
6042        if (pi.uriPermissionPatterns != null) {
6043            final int N = pi.uriPermissionPatterns.length;
6044            boolean allowed = false;
6045            for (int i=0; i<N; i++) {
6046                if (pi.uriPermissionPatterns[i] != null
6047                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6048                    allowed = true;
6049                    break;
6050                }
6051            }
6052            if (!allowed) {
6053                throw new SecurityException("Provider " + pi.packageName
6054                        + "/" + pi.name
6055                        + " does not allow granting of permission to path of Uri "
6056                        + uri);
6057            }
6058        }
6059
6060        // Third...  does the caller itself have permission to access
6061        // this uri?
6062        if (callingUid != Process.myUid()) {
6063            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6064                // Require they hold a strong enough Uri permission
6065                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6066                        : UriPermission.STRENGTH_OWNED;
6067                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6068                    throw new SecurityException("Uid " + callingUid
6069                            + " does not have permission to uri " + uri);
6070                }
6071            }
6072        }
6073
6074        return targetUid;
6075    }
6076
6077    @Override
6078    public int checkGrantUriPermission(int callingUid, String targetPkg,
6079            Uri uri, int modeFlags) {
6080        enforceNotIsolatedCaller("checkGrantUriPermission");
6081        synchronized(this) {
6082            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6083        }
6084    }
6085
6086    void grantUriPermissionUncheckedLocked(
6087            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6088        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6089        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6090                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6091        if (modeFlags == 0) {
6092            return;
6093        }
6094
6095        // So here we are: the caller has the assumed permission
6096        // to the uri, and the target doesn't.  Let's now give this to
6097        // the target.
6098
6099        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6100                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6101
6102        final String authority = uri.getAuthority();
6103        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6104        if (pi == null) {
6105            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6106            return;
6107        }
6108
6109        final UriPermission perm = findOrCreateUriPermissionLocked(
6110                pi.packageName, targetPkg, targetUid, uri);
6111        perm.grantModes(modeFlags, persistable, owner);
6112    }
6113
6114    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6115            int modeFlags, UriPermissionOwner owner) {
6116        if (targetPkg == null) {
6117            throw new NullPointerException("targetPkg");
6118        }
6119
6120        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6121        if (targetUid < 0) {
6122            return;
6123        }
6124
6125        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6126    }
6127
6128    static class NeededUriGrants extends ArrayList<Uri> {
6129        final String targetPkg;
6130        final int targetUid;
6131        final int flags;
6132
6133        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6134            this.targetPkg = targetPkg;
6135            this.targetUid = targetUid;
6136            this.flags = flags;
6137        }
6138    }
6139
6140    /**
6141     * Like checkGrantUriPermissionLocked, but takes an Intent.
6142     */
6143    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6144            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6145        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6146                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6147                + " clip=" + (intent != null ? intent.getClipData() : null)
6148                + " from " + intent + "; flags=0x"
6149                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6150
6151        if (targetPkg == null) {
6152            throw new NullPointerException("targetPkg");
6153        }
6154
6155        if (intent == null) {
6156            return null;
6157        }
6158        Uri data = intent.getData();
6159        ClipData clip = intent.getClipData();
6160        if (data == null && clip == null) {
6161            return null;
6162        }
6163
6164        if (data != null) {
6165            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6166                mode, needed != null ? needed.targetUid : -1);
6167            if (targetUid > 0) {
6168                if (needed == null) {
6169                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6170                }
6171                needed.add(data);
6172            }
6173        }
6174        if (clip != null) {
6175            for (int i=0; i<clip.getItemCount(); i++) {
6176                Uri uri = clip.getItemAt(i).getUri();
6177                if (uri != null) {
6178                    int targetUid = -1;
6179                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6180                            mode, needed != null ? needed.targetUid : -1);
6181                    if (targetUid > 0) {
6182                        if (needed == null) {
6183                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6184                        }
6185                        needed.add(uri);
6186                    }
6187                } else {
6188                    Intent clipIntent = clip.getItemAt(i).getIntent();
6189                    if (clipIntent != null) {
6190                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6191                                callingUid, targetPkg, clipIntent, mode, needed);
6192                        if (newNeeded != null) {
6193                            needed = newNeeded;
6194                        }
6195                    }
6196                }
6197            }
6198        }
6199
6200        return needed;
6201    }
6202
6203    /**
6204     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6205     */
6206    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6207            UriPermissionOwner owner) {
6208        if (needed != null) {
6209            for (int i=0; i<needed.size(); i++) {
6210                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6211                        needed.get(i), needed.flags, owner);
6212            }
6213        }
6214    }
6215
6216    void grantUriPermissionFromIntentLocked(int callingUid,
6217            String targetPkg, Intent intent, UriPermissionOwner owner) {
6218        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6219                intent, intent != null ? intent.getFlags() : 0, null);
6220        if (needed == null) {
6221            return;
6222        }
6223
6224        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6225    }
6226
6227    @Override
6228    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6229            Uri uri, int modeFlags) {
6230        enforceNotIsolatedCaller("grantUriPermission");
6231        synchronized(this) {
6232            final ProcessRecord r = getRecordForAppLocked(caller);
6233            if (r == null) {
6234                throw new SecurityException("Unable to find app for caller "
6235                        + caller
6236                        + " when granting permission to uri " + uri);
6237            }
6238            if (targetPkg == null) {
6239                throw new IllegalArgumentException("null target");
6240            }
6241            if (uri == null) {
6242                throw new IllegalArgumentException("null uri");
6243            }
6244
6245            // Persistable only supported through Intents
6246            Preconditions.checkFlagsArgument(modeFlags,
6247                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6248
6249            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6250                    null);
6251        }
6252    }
6253
6254    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6255        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6256                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6257            ArrayMap<Uri, UriPermission> perms
6258                    = mGrantedUriPermissions.get(perm.targetUid);
6259            if (perms != null) {
6260                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6261                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6262                perms.remove(perm.uri);
6263                if (perms.size() == 0) {
6264                    mGrantedUriPermissions.remove(perm.targetUid);
6265                }
6266            }
6267        }
6268    }
6269
6270    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6271        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6272
6273        final IPackageManager pm = AppGlobals.getPackageManager();
6274        final String authority = uri.getAuthority();
6275        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6276        if (pi == null) {
6277            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6278            return;
6279        }
6280
6281        // Does the caller have this permission on the URI?
6282        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6283            // Right now, if you are not the original owner of the permission,
6284            // you are not allowed to revoke it.
6285            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6286                throw new SecurityException("Uid " + callingUid
6287                        + " does not have permission to uri " + uri);
6288            //}
6289        }
6290
6291        boolean persistChanged = false;
6292
6293        // Go through all of the permissions and remove any that match.
6294        final List<String> SEGMENTS = uri.getPathSegments();
6295        if (SEGMENTS != null) {
6296            final int NS = SEGMENTS.size();
6297            int N = mGrantedUriPermissions.size();
6298            for (int i=0; i<N; i++) {
6299                ArrayMap<Uri, UriPermission> perms
6300                        = mGrantedUriPermissions.valueAt(i);
6301                Iterator<UriPermission> it = perms.values().iterator();
6302            toploop:
6303                while (it.hasNext()) {
6304                    UriPermission perm = it.next();
6305                    Uri targetUri = perm.uri;
6306                    if (!authority.equals(targetUri.getAuthority())) {
6307                        continue;
6308                    }
6309                    List<String> targetSegments = targetUri.getPathSegments();
6310                    if (targetSegments == null) {
6311                        continue;
6312                    }
6313                    if (targetSegments.size() < NS) {
6314                        continue;
6315                    }
6316                    for (int j=0; j<NS; j++) {
6317                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6318                            continue toploop;
6319                        }
6320                    }
6321                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6322                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6323                    persistChanged |= perm.clearModes(modeFlags, true);
6324                    if (perm.modeFlags == 0) {
6325                        it.remove();
6326                    }
6327                }
6328                if (perms.size() == 0) {
6329                    mGrantedUriPermissions.remove(
6330                            mGrantedUriPermissions.keyAt(i));
6331                    N--;
6332                    i--;
6333                }
6334            }
6335        }
6336
6337        if (persistChanged) {
6338            schedulePersistUriGrants();
6339        }
6340    }
6341
6342    @Override
6343    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6344            int modeFlags) {
6345        enforceNotIsolatedCaller("revokeUriPermission");
6346        synchronized(this) {
6347            final ProcessRecord r = getRecordForAppLocked(caller);
6348            if (r == null) {
6349                throw new SecurityException("Unable to find app for caller "
6350                        + caller
6351                        + " when revoking permission to uri " + uri);
6352            }
6353            if (uri == null) {
6354                Slog.w(TAG, "revokeUriPermission: null uri");
6355                return;
6356            }
6357
6358            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6359                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6360            if (modeFlags == 0) {
6361                return;
6362            }
6363
6364            final IPackageManager pm = AppGlobals.getPackageManager();
6365            final String authority = uri.getAuthority();
6366            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6367            if (pi == null) {
6368                Slog.w(TAG, "No content provider found for permission revoke: "
6369                        + uri.toSafeString());
6370                return;
6371            }
6372
6373            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6374        }
6375    }
6376
6377    /**
6378     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6379     * given package.
6380     *
6381     * @param packageName Package name to match, or {@code null} to apply to all
6382     *            packages.
6383     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6384     *            to all users.
6385     * @param persistable If persistable grants should be removed.
6386     */
6387    private void removeUriPermissionsForPackageLocked(
6388            String packageName, int userHandle, boolean persistable) {
6389        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6390            throw new IllegalArgumentException("Must narrow by either package or user");
6391        }
6392
6393        boolean persistChanged = false;
6394
6395        final int size = mGrantedUriPermissions.size();
6396        for (int i = 0; i < size; i++) {
6397            // Only inspect grants matching user
6398            if (userHandle == UserHandle.USER_ALL
6399                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6400                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6401                        .values().iterator();
6402                while (it.hasNext()) {
6403                    final UriPermission perm = it.next();
6404
6405                    // Only inspect grants matching package
6406                    if (packageName == null || perm.sourcePkg.equals(packageName)
6407                            || perm.targetPkg.equals(packageName)) {
6408                        persistChanged |= perm.clearModes(~0, persistable);
6409
6410                        // Only remove when no modes remain; any persisted grants
6411                        // will keep this alive.
6412                        if (perm.modeFlags == 0) {
6413                            it.remove();
6414                        }
6415                    }
6416                }
6417            }
6418        }
6419
6420        if (persistChanged) {
6421            schedulePersistUriGrants();
6422        }
6423    }
6424
6425    @Override
6426    public IBinder newUriPermissionOwner(String name) {
6427        enforceNotIsolatedCaller("newUriPermissionOwner");
6428        synchronized(this) {
6429            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6430            return owner.getExternalTokenLocked();
6431        }
6432    }
6433
6434    @Override
6435    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6436            Uri uri, int modeFlags) {
6437        synchronized(this) {
6438            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6439            if (owner == null) {
6440                throw new IllegalArgumentException("Unknown owner: " + token);
6441            }
6442            if (fromUid != Binder.getCallingUid()) {
6443                if (Binder.getCallingUid() != Process.myUid()) {
6444                    // Only system code can grant URI permissions on behalf
6445                    // of other users.
6446                    throw new SecurityException("nice try");
6447                }
6448            }
6449            if (targetPkg == null) {
6450                throw new IllegalArgumentException("null target");
6451            }
6452            if (uri == null) {
6453                throw new IllegalArgumentException("null uri");
6454            }
6455
6456            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6457        }
6458    }
6459
6460    @Override
6461    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6462        synchronized(this) {
6463            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6464            if (owner == null) {
6465                throw new IllegalArgumentException("Unknown owner: " + token);
6466            }
6467
6468            if (uri == null) {
6469                owner.removeUriPermissionsLocked(mode);
6470            } else {
6471                owner.removeUriPermissionLocked(uri, mode);
6472            }
6473        }
6474    }
6475
6476    private void schedulePersistUriGrants() {
6477        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6478            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6479                    10 * DateUtils.SECOND_IN_MILLIS);
6480        }
6481    }
6482
6483    private void writeGrantedUriPermissions() {
6484        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6485
6486        // Snapshot permissions so we can persist without lock
6487        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6488        synchronized (this) {
6489            final int size = mGrantedUriPermissions.size();
6490            for (int i = 0 ; i < size; i++) {
6491                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6492                    if (perm.persistedModeFlags != 0) {
6493                        persist.add(perm.snapshot());
6494                    }
6495                }
6496            }
6497        }
6498
6499        FileOutputStream fos = null;
6500        try {
6501            fos = mGrantFile.startWrite();
6502
6503            XmlSerializer out = new FastXmlSerializer();
6504            out.setOutput(fos, "utf-8");
6505            out.startDocument(null, true);
6506            out.startTag(null, TAG_URI_GRANTS);
6507            for (UriPermission.Snapshot perm : persist) {
6508                out.startTag(null, TAG_URI_GRANT);
6509                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6510                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6511                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6512                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6513                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6514                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6515                out.endTag(null, TAG_URI_GRANT);
6516            }
6517            out.endTag(null, TAG_URI_GRANTS);
6518            out.endDocument();
6519
6520            mGrantFile.finishWrite(fos);
6521        } catch (IOException e) {
6522            if (fos != null) {
6523                mGrantFile.failWrite(fos);
6524            }
6525        }
6526    }
6527
6528    private void readGrantedUriPermissionsLocked() {
6529        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6530
6531        final long now = System.currentTimeMillis();
6532
6533        FileInputStream fis = null;
6534        try {
6535            fis = mGrantFile.openRead();
6536            final XmlPullParser in = Xml.newPullParser();
6537            in.setInput(fis, null);
6538
6539            int type;
6540            while ((type = in.next()) != END_DOCUMENT) {
6541                final String tag = in.getName();
6542                if (type == START_TAG) {
6543                    if (TAG_URI_GRANT.equals(tag)) {
6544                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6545                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6546                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6547                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6548                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6549                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6550
6551                        // Sanity check that provider still belongs to source package
6552                        final ProviderInfo pi = getProviderInfoLocked(
6553                                uri.getAuthority(), userHandle);
6554                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6555                            int targetUid = -1;
6556                            try {
6557                                targetUid = AppGlobals.getPackageManager()
6558                                        .getPackageUid(targetPkg, userHandle);
6559                            } catch (RemoteException e) {
6560                            }
6561                            if (targetUid != -1) {
6562                                final UriPermission perm = findOrCreateUriPermissionLocked(
6563                                        sourcePkg, targetPkg, targetUid, uri);
6564                                perm.initPersistedModes(modeFlags, createdTime);
6565                            }
6566                        } else {
6567                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6568                                    + " but instead found " + pi);
6569                        }
6570                    }
6571                }
6572            }
6573        } catch (FileNotFoundException e) {
6574            // Missing grants is okay
6575        } catch (IOException e) {
6576            Log.wtf(TAG, "Failed reading Uri grants", e);
6577        } catch (XmlPullParserException e) {
6578            Log.wtf(TAG, "Failed reading Uri grants", e);
6579        } finally {
6580            IoUtils.closeQuietly(fis);
6581        }
6582    }
6583
6584    @Override
6585    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6586        enforceNotIsolatedCaller("takePersistableUriPermission");
6587
6588        Preconditions.checkFlagsArgument(modeFlags,
6589                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6590
6591        synchronized (this) {
6592            final int callingUid = Binder.getCallingUid();
6593            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6594            if (perm == null) {
6595                throw new SecurityException("No permission grant found for UID " + callingUid
6596                        + " and Uri " + uri.toSafeString());
6597            }
6598
6599            boolean persistChanged = perm.takePersistableModes(modeFlags);
6600            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6601
6602            if (persistChanged) {
6603                schedulePersistUriGrants();
6604            }
6605        }
6606    }
6607
6608    @Override
6609    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6610        enforceNotIsolatedCaller("releasePersistableUriPermission");
6611
6612        Preconditions.checkFlagsArgument(modeFlags,
6613                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6614
6615        synchronized (this) {
6616            final int callingUid = Binder.getCallingUid();
6617
6618            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6619            if (perm == null) {
6620                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6621                        + uri.toSafeString());
6622                return;
6623            }
6624
6625            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6626            removeUriPermissionIfNeededLocked(perm);
6627            if (persistChanged) {
6628                schedulePersistUriGrants();
6629            }
6630        }
6631    }
6632
6633    /**
6634     * Prune any older {@link UriPermission} for the given UID until outstanding
6635     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6636     *
6637     * @return if any mutations occured that require persisting.
6638     */
6639    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6640        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6641        if (perms == null) return false;
6642        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6643
6644        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6645        for (UriPermission perm : perms.values()) {
6646            if (perm.persistedModeFlags != 0) {
6647                persisted.add(perm);
6648            }
6649        }
6650
6651        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6652        if (trimCount <= 0) return false;
6653
6654        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6655        for (int i = 0; i < trimCount; i++) {
6656            final UriPermission perm = persisted.get(i);
6657
6658            if (DEBUG_URI_PERMISSION) {
6659                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6660            }
6661
6662            perm.releasePersistableModes(~0);
6663            removeUriPermissionIfNeededLocked(perm);
6664        }
6665
6666        return true;
6667    }
6668
6669    @Override
6670    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6671            String packageName, boolean incoming) {
6672        enforceNotIsolatedCaller("getPersistedUriPermissions");
6673        Preconditions.checkNotNull(packageName, "packageName");
6674
6675        final int callingUid = Binder.getCallingUid();
6676        final IPackageManager pm = AppGlobals.getPackageManager();
6677        try {
6678            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6679            if (packageUid != callingUid) {
6680                throw new SecurityException(
6681                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6682            }
6683        } catch (RemoteException e) {
6684            throw new SecurityException("Failed to verify package name ownership");
6685        }
6686
6687        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6688        synchronized (this) {
6689            if (incoming) {
6690                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6691                if (perms == null) {
6692                    Slog.w(TAG, "No permission grants found for " + packageName);
6693                } else {
6694                    final int size = perms.size();
6695                    for (int i = 0; i < size; i++) {
6696                        final UriPermission perm = perms.valueAt(i);
6697                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6698                            result.add(perm.buildPersistedPublicApiObject());
6699                        }
6700                    }
6701                }
6702            } else {
6703                final int size = mGrantedUriPermissions.size();
6704                for (int i = 0; i < size; i++) {
6705                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6706                    final int permsSize = perms.size();
6707                    for (int j = 0; j < permsSize; j++) {
6708                        final UriPermission perm = perms.valueAt(j);
6709                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6710                            result.add(perm.buildPersistedPublicApiObject());
6711                        }
6712                    }
6713                }
6714            }
6715        }
6716        return new ParceledListSlice<android.content.UriPermission>(result);
6717    }
6718
6719    @Override
6720    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6721        synchronized (this) {
6722            ProcessRecord app =
6723                who != null ? getRecordForAppLocked(who) : null;
6724            if (app == null) return;
6725
6726            Message msg = Message.obtain();
6727            msg.what = WAIT_FOR_DEBUGGER_MSG;
6728            msg.obj = app;
6729            msg.arg1 = waiting ? 1 : 0;
6730            mHandler.sendMessage(msg);
6731        }
6732    }
6733
6734    @Override
6735    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6736        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6737        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6738        outInfo.availMem = Process.getFreeMemory();
6739        outInfo.totalMem = Process.getTotalMemory();
6740        outInfo.threshold = homeAppMem;
6741        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6742        outInfo.hiddenAppThreshold = cachedAppMem;
6743        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6744                ProcessList.SERVICE_ADJ);
6745        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6746                ProcessList.VISIBLE_APP_ADJ);
6747        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6748                ProcessList.FOREGROUND_APP_ADJ);
6749    }
6750
6751    // =========================================================
6752    // TASK MANAGEMENT
6753    // =========================================================
6754
6755    @Override
6756    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6757                         IThumbnailReceiver receiver) {
6758        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6759
6760        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6761        ActivityRecord topRecord = null;
6762
6763        synchronized(this) {
6764            if (localLOGV) Slog.v(
6765                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6766                + ", receiver=" + receiver);
6767
6768            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6769                    != PackageManager.PERMISSION_GRANTED) {
6770                if (receiver != null) {
6771                    // If the caller wants to wait for pending thumbnails,
6772                    // it ain't gonna get them.
6773                    try {
6774                        receiver.finished();
6775                    } catch (RemoteException ex) {
6776                    }
6777                }
6778                String msg = "Permission Denial: getTasks() from pid="
6779                        + Binder.getCallingPid()
6780                        + ", uid=" + Binder.getCallingUid()
6781                        + " requires " + android.Manifest.permission.GET_TASKS;
6782                Slog.w(TAG, msg);
6783                throw new SecurityException(msg);
6784            }
6785
6786            // TODO: Improve with MRU list from all ActivityStacks.
6787            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6788
6789            if (!pending.pendingRecords.isEmpty()) {
6790                mPendingThumbnails.add(pending);
6791            }
6792        }
6793
6794        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6795
6796        if (topRecord != null) {
6797            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6798            try {
6799                IApplicationThread topThumbnail = topRecord.app.thread;
6800                topThumbnail.requestThumbnail(topRecord.appToken);
6801            } catch (Exception e) {
6802                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6803                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6804            }
6805        }
6806
6807        if (pending == null && receiver != null) {
6808            // In this case all thumbnails were available and the client
6809            // is being asked to be told when the remaining ones come in...
6810            // which is unusually, since the top-most currently running
6811            // activity should never have a canned thumbnail!  Oh well.
6812            try {
6813                receiver.finished();
6814            } catch (RemoteException ex) {
6815            }
6816        }
6817
6818        return list;
6819    }
6820
6821    TaskRecord getMostRecentTask() {
6822        return mRecentTasks.get(0);
6823    }
6824
6825    @Override
6826    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6827            int flags, int userId) {
6828        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6829                false, true, "getRecentTasks", null);
6830
6831        synchronized (this) {
6832            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6833                    "getRecentTasks()");
6834            final boolean detailed = checkCallingPermission(
6835                    android.Manifest.permission.GET_DETAILED_TASKS)
6836                    == PackageManager.PERMISSION_GRANTED;
6837
6838            IPackageManager pm = AppGlobals.getPackageManager();
6839
6840            final int N = mRecentTasks.size();
6841            ArrayList<ActivityManager.RecentTaskInfo> res
6842                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6843                            maxNum < N ? maxNum : N);
6844            for (int i=0; i<N && maxNum > 0; i++) {
6845                TaskRecord tr = mRecentTasks.get(i);
6846                // Only add calling user's recent tasks
6847                if (tr.userId != userId) continue;
6848                // Return the entry if desired by the caller.  We always return
6849                // the first entry, because callers always expect this to be the
6850                // foreground app.  We may filter others if the caller has
6851                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6852                // we should exclude the entry.
6853
6854                if (i == 0
6855                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6856                        || (tr.intent == null)
6857                        || ((tr.intent.getFlags()
6858                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6859                    ActivityManager.RecentTaskInfo rti
6860                            = new ActivityManager.RecentTaskInfo();
6861                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6862                    rti.persistentId = tr.taskId;
6863                    rti.baseIntent = new Intent(
6864                            tr.intent != null ? tr.intent : tr.affinityIntent);
6865                    if (!detailed) {
6866                        rti.baseIntent.replaceExtras((Bundle)null);
6867                    }
6868                    rti.origActivity = tr.origActivity;
6869                    rti.description = tr.lastDescription;
6870                    rti.stackId = tr.stack.mStackId;
6871
6872                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6873                        // Check whether this activity is currently available.
6874                        try {
6875                            if (rti.origActivity != null) {
6876                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6877                                        == null) {
6878                                    continue;
6879                                }
6880                            } else if (rti.baseIntent != null) {
6881                                if (pm.queryIntentActivities(rti.baseIntent,
6882                                        null, 0, userId) == null) {
6883                                    continue;
6884                                }
6885                            }
6886                        } catch (RemoteException e) {
6887                            // Will never happen.
6888                        }
6889                    }
6890
6891                    res.add(rti);
6892                    maxNum--;
6893                }
6894            }
6895            return res;
6896        }
6897    }
6898
6899    private TaskRecord recentTaskForIdLocked(int id) {
6900        final int N = mRecentTasks.size();
6901            for (int i=0; i<N; i++) {
6902                TaskRecord tr = mRecentTasks.get(i);
6903                if (tr.taskId == id) {
6904                    return tr;
6905                }
6906            }
6907            return null;
6908    }
6909
6910    @Override
6911    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6912        synchronized (this) {
6913            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6914                    "getTaskThumbnails()");
6915            TaskRecord tr = recentTaskForIdLocked(id);
6916            if (tr != null) {
6917                return tr.getTaskThumbnailsLocked();
6918            }
6919        }
6920        return null;
6921    }
6922
6923    @Override
6924    public Bitmap getTaskTopThumbnail(int id) {
6925        synchronized (this) {
6926            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6927                    "getTaskTopThumbnail()");
6928            TaskRecord tr = recentTaskForIdLocked(id);
6929            if (tr != null) {
6930                return tr.getTaskTopThumbnailLocked();
6931            }
6932        }
6933        return null;
6934    }
6935
6936    @Override
6937    public boolean removeSubTask(int taskId, int subTaskIndex) {
6938        synchronized (this) {
6939            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6940                    "removeSubTask()");
6941            long ident = Binder.clearCallingIdentity();
6942            try {
6943                TaskRecord tr = recentTaskForIdLocked(taskId);
6944                if (tr != null) {
6945                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6946                }
6947                return false;
6948            } finally {
6949                Binder.restoreCallingIdentity(ident);
6950            }
6951        }
6952    }
6953
6954    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6955        if (!pr.killedByAm) {
6956            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6957            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6958                    pr.processName, pr.setAdj, reason);
6959            pr.killedByAm = true;
6960            Process.killProcessQuiet(pr.pid);
6961        }
6962    }
6963
6964    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6965        tr.disposeThumbnail();
6966        mRecentTasks.remove(tr);
6967        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6968        Intent baseIntent = new Intent(
6969                tr.intent != null ? tr.intent : tr.affinityIntent);
6970        ComponentName component = baseIntent.getComponent();
6971        if (component == null) {
6972            Slog.w(TAG, "Now component for base intent of task: " + tr);
6973            return;
6974        }
6975
6976        // Find any running services associated with this app.
6977        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6978
6979        if (killProcesses) {
6980            // Find any running processes associated with this app.
6981            final String pkg = component.getPackageName();
6982            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6983            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6984            for (int i=0; i<pmap.size(); i++) {
6985                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6986                for (int j=0; j<uids.size(); j++) {
6987                    ProcessRecord proc = uids.valueAt(j);
6988                    if (proc.userId != tr.userId) {
6989                        continue;
6990                    }
6991                    if (!proc.pkgList.containsKey(pkg)) {
6992                        continue;
6993                    }
6994                    procs.add(proc);
6995                }
6996            }
6997
6998            // Kill the running processes.
6999            for (int i=0; i<procs.size(); i++) {
7000                ProcessRecord pr = procs.get(i);
7001                if (pr == mHomeProcess) {
7002                    // Don't kill the home process along with tasks from the same package.
7003                    continue;
7004                }
7005                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7006                    killUnneededProcessLocked(pr, "remove task");
7007                } else {
7008                    pr.waitingToKill = "remove task";
7009                }
7010            }
7011        }
7012    }
7013
7014    @Override
7015    public boolean removeTask(int taskId, int flags) {
7016        synchronized (this) {
7017            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7018                    "removeTask()");
7019            long ident = Binder.clearCallingIdentity();
7020            try {
7021                TaskRecord tr = recentTaskForIdLocked(taskId);
7022                if (tr != null) {
7023                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7024                    if (r != null) {
7025                        cleanUpRemovedTaskLocked(tr, flags);
7026                        return true;
7027                    }
7028                    if (tr.mActivities.size() == 0) {
7029                        // Caller is just removing a recent task that is
7030                        // not actively running.  That is easy!
7031                        cleanUpRemovedTaskLocked(tr, flags);
7032                        return true;
7033                    }
7034                    Slog.w(TAG, "removeTask: task " + taskId
7035                            + " does not have activities to remove, "
7036                            + " but numActivities=" + tr.numActivities
7037                            + ": " + tr);
7038                }
7039            } finally {
7040                Binder.restoreCallingIdentity(ident);
7041            }
7042        }
7043        return false;
7044    }
7045
7046    /**
7047     * TODO: Add mController hook
7048     */
7049    @Override
7050    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7051        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7052                "moveTaskToFront()");
7053
7054        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7055        synchronized(this) {
7056            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7057                    Binder.getCallingUid(), "Task to front")) {
7058                ActivityOptions.abort(options);
7059                return;
7060            }
7061            final long origId = Binder.clearCallingIdentity();
7062            try {
7063                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7064                if (task == null) {
7065                    return;
7066                }
7067                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7068                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7069                    return;
7070                }
7071                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7072            } finally {
7073                Binder.restoreCallingIdentity(origId);
7074            }
7075            ActivityOptions.abort(options);
7076        }
7077    }
7078
7079    @Override
7080    public void moveTaskToBack(int taskId) {
7081        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7082                "moveTaskToBack()");
7083
7084        synchronized(this) {
7085            TaskRecord tr = recentTaskForIdLocked(taskId);
7086            if (tr != null) {
7087                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7088                ActivityStack stack = tr.stack;
7089                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7090                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7091                            Binder.getCallingUid(), "Task to back")) {
7092                        return;
7093                    }
7094                }
7095                final long origId = Binder.clearCallingIdentity();
7096                try {
7097                    stack.moveTaskToBackLocked(taskId, null);
7098                } finally {
7099                    Binder.restoreCallingIdentity(origId);
7100                }
7101            }
7102        }
7103    }
7104
7105    /**
7106     * Moves an activity, and all of the other activities within the same task, to the bottom
7107     * of the history stack.  The activity's order within the task is unchanged.
7108     *
7109     * @param token A reference to the activity we wish to move
7110     * @param nonRoot If false then this only works if the activity is the root
7111     *                of a task; if true it will work for any activity in a task.
7112     * @return Returns true if the move completed, false if not.
7113     */
7114    @Override
7115    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7116        enforceNotIsolatedCaller("moveActivityTaskToBack");
7117        synchronized(this) {
7118            final long origId = Binder.clearCallingIdentity();
7119            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7120            if (taskId >= 0) {
7121                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7122            }
7123            Binder.restoreCallingIdentity(origId);
7124        }
7125        return false;
7126    }
7127
7128    @Override
7129    public void moveTaskBackwards(int task) {
7130        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7131                "moveTaskBackwards()");
7132
7133        synchronized(this) {
7134            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7135                    Binder.getCallingUid(), "Task backwards")) {
7136                return;
7137            }
7138            final long origId = Binder.clearCallingIdentity();
7139            moveTaskBackwardsLocked(task);
7140            Binder.restoreCallingIdentity(origId);
7141        }
7142    }
7143
7144    private final void moveTaskBackwardsLocked(int task) {
7145        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7146    }
7147
7148    @Override
7149    public IBinder getHomeActivityToken() throws RemoteException {
7150        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7151                "getHomeActivityToken()");
7152        synchronized (this) {
7153            return mStackSupervisor.getHomeActivityToken();
7154        }
7155    }
7156
7157    @Override
7158    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7159            IActivityContainerCallback callback) throws RemoteException {
7160        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7161                "createActivityContainer()");
7162        synchronized (this) {
7163            if (parentActivityToken == null) {
7164                throw new IllegalArgumentException("parent token must not be null");
7165            }
7166            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7167            if (r == null) {
7168                return null;
7169            }
7170            return mStackSupervisor.createActivityContainer(r, callback);
7171        }
7172    }
7173
7174    @Override
7175    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7176        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7177                "deleteActivityContainer()");
7178        synchronized (this) {
7179            mStackSupervisor.deleteActivityContainer(container);
7180        }
7181    }
7182
7183    @Override
7184    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7185            throws RemoteException {
7186        synchronized (this) {
7187            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7188            if (stack != null) {
7189                return stack.mActivityContainer;
7190            }
7191            return null;
7192        }
7193    }
7194
7195    @Override
7196    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7197        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7198                "moveTaskToStack()");
7199        if (stackId == HOME_STACK_ID) {
7200            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7201                    new RuntimeException("here").fillInStackTrace());
7202        }
7203        synchronized (this) {
7204            long ident = Binder.clearCallingIdentity();
7205            try {
7206                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7207                        + stackId + " toTop=" + toTop);
7208                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7209            } finally {
7210                Binder.restoreCallingIdentity(ident);
7211            }
7212        }
7213    }
7214
7215    @Override
7216    public void resizeStack(int stackBoxId, Rect bounds) {
7217        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7218                "resizeStackBox()");
7219        long ident = Binder.clearCallingIdentity();
7220        try {
7221            mWindowManager.resizeStack(stackBoxId, bounds);
7222        } finally {
7223            Binder.restoreCallingIdentity(ident);
7224        }
7225    }
7226
7227    @Override
7228    public List<StackInfo> getAllStackInfos() {
7229        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7230                "getAllStackInfos()");
7231        long ident = Binder.clearCallingIdentity();
7232        try {
7233            synchronized (this) {
7234                return mStackSupervisor.getAllStackInfosLocked();
7235            }
7236        } finally {
7237            Binder.restoreCallingIdentity(ident);
7238        }
7239    }
7240
7241    @Override
7242    public StackInfo getStackInfo(int stackId) {
7243        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7244                "getStackInfo()");
7245        long ident = Binder.clearCallingIdentity();
7246        try {
7247            synchronized (this) {
7248                return mStackSupervisor.getStackInfoLocked(stackId);
7249            }
7250        } finally {
7251            Binder.restoreCallingIdentity(ident);
7252        }
7253    }
7254
7255    @Override
7256    public boolean isInHomeStack(int taskId) {
7257        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7258                "getStackInfo()");
7259        long ident = Binder.clearCallingIdentity();
7260        try {
7261            synchronized (this) {
7262                TaskRecord tr = recentTaskForIdLocked(taskId);
7263                if (tr != null) {
7264                    return tr.stack.isHomeStack();
7265                }
7266            }
7267        } finally {
7268            Binder.restoreCallingIdentity(ident);
7269        }
7270        return false;
7271    }
7272
7273    @Override
7274    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7275        synchronized(this) {
7276            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7277        }
7278    }
7279
7280    private boolean isLockTaskAuthorized(ComponentName name) {
7281//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7282//                "startLockTaskMode()");
7283//        DevicePolicyManager dpm = (DevicePolicyManager)
7284//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7285//        return dpm != null && dpm.isLockTaskPermitted(name);
7286        return true;
7287    }
7288
7289    private void startLockTaskMode(TaskRecord task) {
7290        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7291            return;
7292        }
7293        long ident = Binder.clearCallingIdentity();
7294        try {
7295            synchronized (this) {
7296                // Since we lost lock on task, make sure it is still there.
7297                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7298                if (task != null) {
7299                    mStackSupervisor.setLockTaskModeLocked(task);
7300                }
7301            }
7302        } finally {
7303            Binder.restoreCallingIdentity(ident);
7304        }
7305    }
7306
7307    @Override
7308    public void startLockTaskMode(int taskId) {
7309        long ident = Binder.clearCallingIdentity();
7310        try {
7311            final TaskRecord task;
7312            synchronized (this) {
7313                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7314            }
7315            if (task != null) {
7316                startLockTaskMode(task);
7317            }
7318        } finally {
7319            Binder.restoreCallingIdentity(ident);
7320        }
7321    }
7322
7323    @Override
7324    public void startLockTaskMode(IBinder token) {
7325        long ident = Binder.clearCallingIdentity();
7326        try {
7327            final TaskRecord task;
7328            synchronized (this) {
7329                final ActivityRecord r = ActivityRecord.forToken(token);
7330                if (r == null) {
7331                    return;
7332                }
7333                task = r.task;
7334            }
7335            if (task != null) {
7336                startLockTaskMode(task);
7337            }
7338        } finally {
7339            Binder.restoreCallingIdentity(ident);
7340        }
7341    }
7342
7343    @Override
7344    public void stopLockTaskMode() {
7345//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7346//                "stopLockTaskMode()");
7347        synchronized (this) {
7348            mStackSupervisor.setLockTaskModeLocked(null);
7349        }
7350    }
7351
7352    @Override
7353    public boolean isInLockTaskMode() {
7354        synchronized (this) {
7355            return mStackSupervisor.isInLockTaskMode();
7356        }
7357    }
7358
7359    // =========================================================
7360    // THUMBNAILS
7361    // =========================================================
7362
7363    public void reportThumbnail(IBinder token,
7364            Bitmap thumbnail, CharSequence description) {
7365        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7366        final long origId = Binder.clearCallingIdentity();
7367        sendPendingThumbnail(null, token, thumbnail, description, true);
7368        Binder.restoreCallingIdentity(origId);
7369    }
7370
7371    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7372            Bitmap thumbnail, CharSequence description, boolean always) {
7373        TaskRecord task;
7374        ArrayList<PendingThumbnailsRecord> receivers = null;
7375
7376        //System.out.println("Send pending thumbnail: " + r);
7377
7378        synchronized(this) {
7379            if (r == null) {
7380                r = ActivityRecord.isInStackLocked(token);
7381                if (r == null) {
7382                    return;
7383                }
7384            }
7385            if (thumbnail == null && r.thumbHolder != null) {
7386                thumbnail = r.thumbHolder.lastThumbnail;
7387                description = r.thumbHolder.lastDescription;
7388            }
7389            if (thumbnail == null && !always) {
7390                // If there is no thumbnail, and this entry is not actually
7391                // going away, then abort for now and pick up the next
7392                // thumbnail we get.
7393                return;
7394            }
7395            task = r.task;
7396
7397            int N = mPendingThumbnails.size();
7398            int i=0;
7399            while (i<N) {
7400                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7401                //System.out.println("Looking in " + pr.pendingRecords);
7402                if (pr.pendingRecords.remove(r)) {
7403                    if (receivers == null) {
7404                        receivers = new ArrayList<PendingThumbnailsRecord>();
7405                    }
7406                    receivers.add(pr);
7407                    if (pr.pendingRecords.size() == 0) {
7408                        pr.finished = true;
7409                        mPendingThumbnails.remove(i);
7410                        N--;
7411                        continue;
7412                    }
7413                }
7414                i++;
7415            }
7416        }
7417
7418        if (receivers != null) {
7419            final int N = receivers.size();
7420            for (int i=0; i<N; i++) {
7421                try {
7422                    PendingThumbnailsRecord pr = receivers.get(i);
7423                    pr.receiver.newThumbnail(
7424                        task != null ? task.taskId : -1, thumbnail, description);
7425                    if (pr.finished) {
7426                        pr.receiver.finished();
7427                    }
7428                } catch (Exception e) {
7429                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7430                }
7431            }
7432        }
7433    }
7434
7435    // =========================================================
7436    // CONTENT PROVIDERS
7437    // =========================================================
7438
7439    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7440        List<ProviderInfo> providers = null;
7441        try {
7442            providers = AppGlobals.getPackageManager().
7443                queryContentProviders(app.processName, app.uid,
7444                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7445        } catch (RemoteException ex) {
7446        }
7447        if (DEBUG_MU)
7448            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7449        int userId = app.userId;
7450        if (providers != null) {
7451            int N = providers.size();
7452            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7453            for (int i=0; i<N; i++) {
7454                ProviderInfo cpi =
7455                    (ProviderInfo)providers.get(i);
7456                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7457                        cpi.name, cpi.flags);
7458                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7459                    // This is a singleton provider, but a user besides the
7460                    // default user is asking to initialize a process it runs
7461                    // in...  well, no, it doesn't actually run in this process,
7462                    // it runs in the process of the default user.  Get rid of it.
7463                    providers.remove(i);
7464                    N--;
7465                    i--;
7466                    continue;
7467                }
7468
7469                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7470                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7471                if (cpr == null) {
7472                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7473                    mProviderMap.putProviderByClass(comp, cpr);
7474                }
7475                if (DEBUG_MU)
7476                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7477                app.pubProviders.put(cpi.name, cpr);
7478                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7479                    // Don't add this if it is a platform component that is marked
7480                    // to run in multiple processes, because this is actually
7481                    // part of the framework so doesn't make sense to track as a
7482                    // separate apk in the process.
7483                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7484                }
7485                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7486            }
7487        }
7488        return providers;
7489    }
7490
7491    /**
7492     * Check if {@link ProcessRecord} has a possible chance at accessing the
7493     * given {@link ProviderInfo}. Final permission checking is always done
7494     * in {@link ContentProvider}.
7495     */
7496    private final String checkContentProviderPermissionLocked(
7497            ProviderInfo cpi, ProcessRecord r) {
7498        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7499        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7500        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7501                cpi.applicationInfo.uid, cpi.exported)
7502                == PackageManager.PERMISSION_GRANTED) {
7503            return null;
7504        }
7505        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7506                cpi.applicationInfo.uid, cpi.exported)
7507                == PackageManager.PERMISSION_GRANTED) {
7508            return null;
7509        }
7510
7511        PathPermission[] pps = cpi.pathPermissions;
7512        if (pps != null) {
7513            int i = pps.length;
7514            while (i > 0) {
7515                i--;
7516                PathPermission pp = pps[i];
7517                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7518                        cpi.applicationInfo.uid, cpi.exported)
7519                        == PackageManager.PERMISSION_GRANTED) {
7520                    return null;
7521                }
7522                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7523                        cpi.applicationInfo.uid, cpi.exported)
7524                        == PackageManager.PERMISSION_GRANTED) {
7525                    return null;
7526                }
7527            }
7528        }
7529
7530        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7531        if (perms != null) {
7532            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7533                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7534                    return null;
7535                }
7536            }
7537        }
7538
7539        String msg;
7540        if (!cpi.exported) {
7541            msg = "Permission Denial: opening provider " + cpi.name
7542                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7543                    + ", uid=" + callingUid + ") that is not exported from uid "
7544                    + cpi.applicationInfo.uid;
7545        } else {
7546            msg = "Permission Denial: opening provider " + cpi.name
7547                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7548                    + ", uid=" + callingUid + ") requires "
7549                    + cpi.readPermission + " or " + cpi.writePermission;
7550        }
7551        Slog.w(TAG, msg);
7552        return msg;
7553    }
7554
7555    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7556            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7557        if (r != null) {
7558            for (int i=0; i<r.conProviders.size(); i++) {
7559                ContentProviderConnection conn = r.conProviders.get(i);
7560                if (conn.provider == cpr) {
7561                    if (DEBUG_PROVIDER) Slog.v(TAG,
7562                            "Adding provider requested by "
7563                            + r.processName + " from process "
7564                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7565                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7566                    if (stable) {
7567                        conn.stableCount++;
7568                        conn.numStableIncs++;
7569                    } else {
7570                        conn.unstableCount++;
7571                        conn.numUnstableIncs++;
7572                    }
7573                    return conn;
7574                }
7575            }
7576            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7577            if (stable) {
7578                conn.stableCount = 1;
7579                conn.numStableIncs = 1;
7580            } else {
7581                conn.unstableCount = 1;
7582                conn.numUnstableIncs = 1;
7583            }
7584            cpr.connections.add(conn);
7585            r.conProviders.add(conn);
7586            return conn;
7587        }
7588        cpr.addExternalProcessHandleLocked(externalProcessToken);
7589        return null;
7590    }
7591
7592    boolean decProviderCountLocked(ContentProviderConnection conn,
7593            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7594        if (conn != null) {
7595            cpr = conn.provider;
7596            if (DEBUG_PROVIDER) Slog.v(TAG,
7597                    "Removing provider requested by "
7598                    + conn.client.processName + " from process "
7599                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7600                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7601            if (stable) {
7602                conn.stableCount--;
7603            } else {
7604                conn.unstableCount--;
7605            }
7606            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7607                cpr.connections.remove(conn);
7608                conn.client.conProviders.remove(conn);
7609                return true;
7610            }
7611            return false;
7612        }
7613        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7614        return false;
7615    }
7616
7617    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7618            String name, IBinder token, boolean stable, int userId) {
7619        ContentProviderRecord cpr;
7620        ContentProviderConnection conn = null;
7621        ProviderInfo cpi = null;
7622
7623        synchronized(this) {
7624            ProcessRecord r = null;
7625            if (caller != null) {
7626                r = getRecordForAppLocked(caller);
7627                if (r == null) {
7628                    throw new SecurityException(
7629                            "Unable to find app for caller " + caller
7630                          + " (pid=" + Binder.getCallingPid()
7631                          + ") when getting content provider " + name);
7632                }
7633            }
7634
7635            // First check if this content provider has been published...
7636            cpr = mProviderMap.getProviderByName(name, userId);
7637            boolean providerRunning = cpr != null;
7638            if (providerRunning) {
7639                cpi = cpr.info;
7640                String msg;
7641                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7642                    throw new SecurityException(msg);
7643                }
7644
7645                if (r != null && cpr.canRunHere(r)) {
7646                    // This provider has been published or is in the process
7647                    // of being published...  but it is also allowed to run
7648                    // in the caller's process, so don't make a connection
7649                    // and just let the caller instantiate its own instance.
7650                    ContentProviderHolder holder = cpr.newHolder(null);
7651                    // don't give caller the provider object, it needs
7652                    // to make its own.
7653                    holder.provider = null;
7654                    return holder;
7655                }
7656
7657                final long origId = Binder.clearCallingIdentity();
7658
7659                // In this case the provider instance already exists, so we can
7660                // return it right away.
7661                conn = incProviderCountLocked(r, cpr, token, stable);
7662                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7663                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7664                        // If this is a perceptible app accessing the provider,
7665                        // make sure to count it as being accessed and thus
7666                        // back up on the LRU list.  This is good because
7667                        // content providers are often expensive to start.
7668                        updateLruProcessLocked(cpr.proc, false, null);
7669                    }
7670                }
7671
7672                if (cpr.proc != null) {
7673                    if (false) {
7674                        if (cpr.name.flattenToShortString().equals(
7675                                "com.android.providers.calendar/.CalendarProvider2")) {
7676                            Slog.v(TAG, "****************** KILLING "
7677                                + cpr.name.flattenToShortString());
7678                            Process.killProcess(cpr.proc.pid);
7679                        }
7680                    }
7681                    boolean success = updateOomAdjLocked(cpr.proc);
7682                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7683                    // NOTE: there is still a race here where a signal could be
7684                    // pending on the process even though we managed to update its
7685                    // adj level.  Not sure what to do about this, but at least
7686                    // the race is now smaller.
7687                    if (!success) {
7688                        // Uh oh...  it looks like the provider's process
7689                        // has been killed on us.  We need to wait for a new
7690                        // process to be started, and make sure its death
7691                        // doesn't kill our process.
7692                        Slog.i(TAG,
7693                                "Existing provider " + cpr.name.flattenToShortString()
7694                                + " is crashing; detaching " + r);
7695                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7696                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7697                        if (!lastRef) {
7698                            // This wasn't the last ref our process had on
7699                            // the provider...  we have now been killed, bail.
7700                            return null;
7701                        }
7702                        providerRunning = false;
7703                        conn = null;
7704                    }
7705                }
7706
7707                Binder.restoreCallingIdentity(origId);
7708            }
7709
7710            boolean singleton;
7711            if (!providerRunning) {
7712                try {
7713                    cpi = AppGlobals.getPackageManager().
7714                        resolveContentProvider(name,
7715                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7716                } catch (RemoteException ex) {
7717                }
7718                if (cpi == null) {
7719                    return null;
7720                }
7721                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7722                        cpi.name, cpi.flags);
7723                if (singleton) {
7724                    userId = 0;
7725                }
7726                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7727
7728                String msg;
7729                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7730                    throw new SecurityException(msg);
7731                }
7732
7733                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7734                        && !cpi.processName.equals("system")) {
7735                    // If this content provider does not run in the system
7736                    // process, and the system is not yet ready to run other
7737                    // processes, then fail fast instead of hanging.
7738                    throw new IllegalArgumentException(
7739                            "Attempt to launch content provider before system ready");
7740                }
7741
7742                // Make sure that the user who owns this provider is started.  If not,
7743                // we don't want to allow it to run.
7744                if (mStartedUsers.get(userId) == null) {
7745                    Slog.w(TAG, "Unable to launch app "
7746                            + cpi.applicationInfo.packageName + "/"
7747                            + cpi.applicationInfo.uid + " for provider "
7748                            + name + ": user " + userId + " is stopped");
7749                    return null;
7750                }
7751
7752                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7753                cpr = mProviderMap.getProviderByClass(comp, userId);
7754                final boolean firstClass = cpr == null;
7755                if (firstClass) {
7756                    try {
7757                        ApplicationInfo ai =
7758                            AppGlobals.getPackageManager().
7759                                getApplicationInfo(
7760                                        cpi.applicationInfo.packageName,
7761                                        STOCK_PM_FLAGS, userId);
7762                        if (ai == null) {
7763                            Slog.w(TAG, "No package info for content provider "
7764                                    + cpi.name);
7765                            return null;
7766                        }
7767                        ai = getAppInfoForUser(ai, userId);
7768                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7769                    } catch (RemoteException ex) {
7770                        // pm is in same process, this will never happen.
7771                    }
7772                }
7773
7774                if (r != null && cpr.canRunHere(r)) {
7775                    // If this is a multiprocess provider, then just return its
7776                    // info and allow the caller to instantiate it.  Only do
7777                    // this if the provider is the same user as the caller's
7778                    // process, or can run as root (so can be in any process).
7779                    return cpr.newHolder(null);
7780                }
7781
7782                if (DEBUG_PROVIDER) {
7783                    RuntimeException e = new RuntimeException("here");
7784                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7785                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7786                }
7787
7788                // This is single process, and our app is now connecting to it.
7789                // See if we are already in the process of launching this
7790                // provider.
7791                final int N = mLaunchingProviders.size();
7792                int i;
7793                for (i=0; i<N; i++) {
7794                    if (mLaunchingProviders.get(i) == cpr) {
7795                        break;
7796                    }
7797                }
7798
7799                // If the provider is not already being launched, then get it
7800                // started.
7801                if (i >= N) {
7802                    final long origId = Binder.clearCallingIdentity();
7803
7804                    try {
7805                        // Content provider is now in use, its package can't be stopped.
7806                        try {
7807                            AppGlobals.getPackageManager().setPackageStoppedState(
7808                                    cpr.appInfo.packageName, false, userId);
7809                        } catch (RemoteException e) {
7810                        } catch (IllegalArgumentException e) {
7811                            Slog.w(TAG, "Failed trying to unstop package "
7812                                    + cpr.appInfo.packageName + ": " + e);
7813                        }
7814
7815                        // Use existing process if already started
7816                        ProcessRecord proc = getProcessRecordLocked(
7817                                cpi.processName, cpr.appInfo.uid, false);
7818                        if (proc != null && proc.thread != null) {
7819                            if (DEBUG_PROVIDER) {
7820                                Slog.d(TAG, "Installing in existing process " + proc);
7821                            }
7822                            proc.pubProviders.put(cpi.name, cpr);
7823                            try {
7824                                proc.thread.scheduleInstallProvider(cpi);
7825                            } catch (RemoteException e) {
7826                            }
7827                        } else {
7828                            proc = startProcessLocked(cpi.processName,
7829                                    cpr.appInfo, false, 0, "content provider",
7830                                    new ComponentName(cpi.applicationInfo.packageName,
7831                                            cpi.name), false, false, false);
7832                            if (proc == null) {
7833                                Slog.w(TAG, "Unable to launch app "
7834                                        + cpi.applicationInfo.packageName + "/"
7835                                        + cpi.applicationInfo.uid + " for provider "
7836                                        + name + ": process is bad");
7837                                return null;
7838                            }
7839                        }
7840                        cpr.launchingApp = proc;
7841                        mLaunchingProviders.add(cpr);
7842                    } finally {
7843                        Binder.restoreCallingIdentity(origId);
7844                    }
7845                }
7846
7847                // Make sure the provider is published (the same provider class
7848                // may be published under multiple names).
7849                if (firstClass) {
7850                    mProviderMap.putProviderByClass(comp, cpr);
7851                }
7852
7853                mProviderMap.putProviderByName(name, cpr);
7854                conn = incProviderCountLocked(r, cpr, token, stable);
7855                if (conn != null) {
7856                    conn.waiting = true;
7857                }
7858            }
7859        }
7860
7861        // Wait for the provider to be published...
7862        synchronized (cpr) {
7863            while (cpr.provider == null) {
7864                if (cpr.launchingApp == null) {
7865                    Slog.w(TAG, "Unable to launch app "
7866                            + cpi.applicationInfo.packageName + "/"
7867                            + cpi.applicationInfo.uid + " for provider "
7868                            + name + ": launching app became null");
7869                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7870                            UserHandle.getUserId(cpi.applicationInfo.uid),
7871                            cpi.applicationInfo.packageName,
7872                            cpi.applicationInfo.uid, name);
7873                    return null;
7874                }
7875                try {
7876                    if (DEBUG_MU) {
7877                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7878                                + cpr.launchingApp);
7879                    }
7880                    if (conn != null) {
7881                        conn.waiting = true;
7882                    }
7883                    cpr.wait();
7884                } catch (InterruptedException ex) {
7885                } finally {
7886                    if (conn != null) {
7887                        conn.waiting = false;
7888                    }
7889                }
7890            }
7891        }
7892        return cpr != null ? cpr.newHolder(conn) : null;
7893    }
7894
7895    public final ContentProviderHolder getContentProvider(
7896            IApplicationThread caller, String name, int userId, boolean stable) {
7897        enforceNotIsolatedCaller("getContentProvider");
7898        if (caller == null) {
7899            String msg = "null IApplicationThread when getting content provider "
7900                    + name;
7901            Slog.w(TAG, msg);
7902            throw new SecurityException(msg);
7903        }
7904
7905        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7906                false, true, "getContentProvider", null);
7907        return getContentProviderImpl(caller, name, null, stable, userId);
7908    }
7909
7910    public ContentProviderHolder getContentProviderExternal(
7911            String name, int userId, IBinder token) {
7912        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7913            "Do not have permission in call getContentProviderExternal()");
7914        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7915                false, true, "getContentProvider", null);
7916        return getContentProviderExternalUnchecked(name, token, userId);
7917    }
7918
7919    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7920            IBinder token, int userId) {
7921        return getContentProviderImpl(null, name, token, true, userId);
7922    }
7923
7924    /**
7925     * Drop a content provider from a ProcessRecord's bookkeeping
7926     */
7927    public void removeContentProvider(IBinder connection, boolean stable) {
7928        enforceNotIsolatedCaller("removeContentProvider");
7929        long ident = Binder.clearCallingIdentity();
7930        try {
7931            synchronized (this) {
7932                ContentProviderConnection conn;
7933                try {
7934                    conn = (ContentProviderConnection)connection;
7935                } catch (ClassCastException e) {
7936                    String msg ="removeContentProvider: " + connection
7937                            + " not a ContentProviderConnection";
7938                    Slog.w(TAG, msg);
7939                    throw new IllegalArgumentException(msg);
7940                }
7941                if (conn == null) {
7942                    throw new NullPointerException("connection is null");
7943                }
7944                if (decProviderCountLocked(conn, null, null, stable)) {
7945                    updateOomAdjLocked();
7946                }
7947            }
7948        } finally {
7949            Binder.restoreCallingIdentity(ident);
7950        }
7951    }
7952
7953    public void removeContentProviderExternal(String name, IBinder token) {
7954        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7955            "Do not have permission in call removeContentProviderExternal()");
7956        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7957    }
7958
7959    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7960        synchronized (this) {
7961            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7962            if(cpr == null) {
7963                //remove from mProvidersByClass
7964                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7965                return;
7966            }
7967
7968            //update content provider record entry info
7969            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7970            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7971            if (localCpr.hasExternalProcessHandles()) {
7972                if (localCpr.removeExternalProcessHandleLocked(token)) {
7973                    updateOomAdjLocked();
7974                } else {
7975                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7976                            + " with no external reference for token: "
7977                            + token + ".");
7978                }
7979            } else {
7980                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7981                        + " with no external references.");
7982            }
7983        }
7984    }
7985
7986    public final void publishContentProviders(IApplicationThread caller,
7987            List<ContentProviderHolder> providers) {
7988        if (providers == null) {
7989            return;
7990        }
7991
7992        enforceNotIsolatedCaller("publishContentProviders");
7993        synchronized (this) {
7994            final ProcessRecord r = getRecordForAppLocked(caller);
7995            if (DEBUG_MU)
7996                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7997            if (r == null) {
7998                throw new SecurityException(
7999                        "Unable to find app for caller " + caller
8000                      + " (pid=" + Binder.getCallingPid()
8001                      + ") when publishing content providers");
8002            }
8003
8004            final long origId = Binder.clearCallingIdentity();
8005
8006            final int N = providers.size();
8007            for (int i=0; i<N; i++) {
8008                ContentProviderHolder src = providers.get(i);
8009                if (src == null || src.info == null || src.provider == null) {
8010                    continue;
8011                }
8012                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8013                if (DEBUG_MU)
8014                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8015                if (dst != null) {
8016                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8017                    mProviderMap.putProviderByClass(comp, dst);
8018                    String names[] = dst.info.authority.split(";");
8019                    for (int j = 0; j < names.length; j++) {
8020                        mProviderMap.putProviderByName(names[j], dst);
8021                    }
8022
8023                    int NL = mLaunchingProviders.size();
8024                    int j;
8025                    for (j=0; j<NL; j++) {
8026                        if (mLaunchingProviders.get(j) == dst) {
8027                            mLaunchingProviders.remove(j);
8028                            j--;
8029                            NL--;
8030                        }
8031                    }
8032                    synchronized (dst) {
8033                        dst.provider = src.provider;
8034                        dst.proc = r;
8035                        dst.notifyAll();
8036                    }
8037                    updateOomAdjLocked(r);
8038                }
8039            }
8040
8041            Binder.restoreCallingIdentity(origId);
8042        }
8043    }
8044
8045    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8046        ContentProviderConnection conn;
8047        try {
8048            conn = (ContentProviderConnection)connection;
8049        } catch (ClassCastException e) {
8050            String msg ="refContentProvider: " + connection
8051                    + " not a ContentProviderConnection";
8052            Slog.w(TAG, msg);
8053            throw new IllegalArgumentException(msg);
8054        }
8055        if (conn == null) {
8056            throw new NullPointerException("connection is null");
8057        }
8058
8059        synchronized (this) {
8060            if (stable > 0) {
8061                conn.numStableIncs += stable;
8062            }
8063            stable = conn.stableCount + stable;
8064            if (stable < 0) {
8065                throw new IllegalStateException("stableCount < 0: " + stable);
8066            }
8067
8068            if (unstable > 0) {
8069                conn.numUnstableIncs += unstable;
8070            }
8071            unstable = conn.unstableCount + unstable;
8072            if (unstable < 0) {
8073                throw new IllegalStateException("unstableCount < 0: " + unstable);
8074            }
8075
8076            if ((stable+unstable) <= 0) {
8077                throw new IllegalStateException("ref counts can't go to zero here: stable="
8078                        + stable + " unstable=" + unstable);
8079            }
8080            conn.stableCount = stable;
8081            conn.unstableCount = unstable;
8082            return !conn.dead;
8083        }
8084    }
8085
8086    public void unstableProviderDied(IBinder connection) {
8087        ContentProviderConnection conn;
8088        try {
8089            conn = (ContentProviderConnection)connection;
8090        } catch (ClassCastException e) {
8091            String msg ="refContentProvider: " + connection
8092                    + " not a ContentProviderConnection";
8093            Slog.w(TAG, msg);
8094            throw new IllegalArgumentException(msg);
8095        }
8096        if (conn == null) {
8097            throw new NullPointerException("connection is null");
8098        }
8099
8100        // Safely retrieve the content provider associated with the connection.
8101        IContentProvider provider;
8102        synchronized (this) {
8103            provider = conn.provider.provider;
8104        }
8105
8106        if (provider == null) {
8107            // Um, yeah, we're way ahead of you.
8108            return;
8109        }
8110
8111        // Make sure the caller is being honest with us.
8112        if (provider.asBinder().pingBinder()) {
8113            // Er, no, still looks good to us.
8114            synchronized (this) {
8115                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8116                        + " says " + conn + " died, but we don't agree");
8117                return;
8118            }
8119        }
8120
8121        // Well look at that!  It's dead!
8122        synchronized (this) {
8123            if (conn.provider.provider != provider) {
8124                // But something changed...  good enough.
8125                return;
8126            }
8127
8128            ProcessRecord proc = conn.provider.proc;
8129            if (proc == null || proc.thread == null) {
8130                // Seems like the process is already cleaned up.
8131                return;
8132            }
8133
8134            // As far as we're concerned, this is just like receiving a
8135            // death notification...  just a bit prematurely.
8136            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8137                    + ") early provider death");
8138            final long ident = Binder.clearCallingIdentity();
8139            try {
8140                appDiedLocked(proc, proc.pid, proc.thread);
8141            } finally {
8142                Binder.restoreCallingIdentity(ident);
8143            }
8144        }
8145    }
8146
8147    @Override
8148    public void appNotRespondingViaProvider(IBinder connection) {
8149        enforceCallingPermission(
8150                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8151
8152        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8153        if (conn == null) {
8154            Slog.w(TAG, "ContentProviderConnection is null");
8155            return;
8156        }
8157
8158        final ProcessRecord host = conn.provider.proc;
8159        if (host == null) {
8160            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8161            return;
8162        }
8163
8164        final long token = Binder.clearCallingIdentity();
8165        try {
8166            appNotResponding(host, null, null, false, "ContentProvider not responding");
8167        } finally {
8168            Binder.restoreCallingIdentity(token);
8169        }
8170    }
8171
8172    public final void installSystemProviders() {
8173        List<ProviderInfo> providers;
8174        synchronized (this) {
8175            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8176            providers = generateApplicationProvidersLocked(app);
8177            if (providers != null) {
8178                for (int i=providers.size()-1; i>=0; i--) {
8179                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8180                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8181                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8182                                + ": not system .apk");
8183                        providers.remove(i);
8184                    }
8185                }
8186            }
8187        }
8188        if (providers != null) {
8189            mSystemThread.installSystemProviders(providers);
8190        }
8191
8192        mCoreSettingsObserver = new CoreSettingsObserver(this);
8193
8194        mUsageStatsService.monitorPackages();
8195    }
8196
8197    /**
8198     * Allows app to retrieve the MIME type of a URI without having permission
8199     * to access its content provider.
8200     *
8201     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8202     *
8203     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8204     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8205     */
8206    public String getProviderMimeType(Uri uri, int userId) {
8207        enforceNotIsolatedCaller("getProviderMimeType");
8208        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8209                userId, false, true, "getProviderMimeType", null);
8210        final String name = uri.getAuthority();
8211        final long ident = Binder.clearCallingIdentity();
8212        ContentProviderHolder holder = null;
8213
8214        try {
8215            holder = getContentProviderExternalUnchecked(name, null, userId);
8216            if (holder != null) {
8217                return holder.provider.getType(uri);
8218            }
8219        } catch (RemoteException e) {
8220            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8221            return null;
8222        } finally {
8223            if (holder != null) {
8224                removeContentProviderExternalUnchecked(name, null, userId);
8225            }
8226            Binder.restoreCallingIdentity(ident);
8227        }
8228
8229        return null;
8230    }
8231
8232    // =========================================================
8233    // GLOBAL MANAGEMENT
8234    // =========================================================
8235
8236    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8237            boolean isolated) {
8238        String proc = customProcess != null ? customProcess : info.processName;
8239        BatteryStatsImpl.Uid.Proc ps = null;
8240        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8241        int uid = info.uid;
8242        if (isolated) {
8243            int userId = UserHandle.getUserId(uid);
8244            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8245            while (true) {
8246                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8247                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8248                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8249                }
8250                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8251                mNextIsolatedProcessUid++;
8252                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8253                    // No process for this uid, use it.
8254                    break;
8255                }
8256                stepsLeft--;
8257                if (stepsLeft <= 0) {
8258                    return null;
8259                }
8260            }
8261        }
8262        return new ProcessRecord(stats, info, proc, uid);
8263    }
8264
8265    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8266        ProcessRecord app;
8267        if (!isolated) {
8268            app = getProcessRecordLocked(info.processName, info.uid, true);
8269        } else {
8270            app = null;
8271        }
8272
8273        if (app == null) {
8274            app = newProcessRecordLocked(info, null, isolated);
8275            mProcessNames.put(info.processName, app.uid, app);
8276            if (isolated) {
8277                mIsolatedProcesses.put(app.uid, app);
8278            }
8279            updateLruProcessLocked(app, false, null);
8280            updateOomAdjLocked();
8281        }
8282
8283        // This package really, really can not be stopped.
8284        try {
8285            AppGlobals.getPackageManager().setPackageStoppedState(
8286                    info.packageName, false, UserHandle.getUserId(app.uid));
8287        } catch (RemoteException e) {
8288        } catch (IllegalArgumentException e) {
8289            Slog.w(TAG, "Failed trying to unstop package "
8290                    + info.packageName + ": " + e);
8291        }
8292
8293        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8294                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8295            app.persistent = true;
8296            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8297        }
8298        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8299            mPersistentStartingProcesses.add(app);
8300            startProcessLocked(app, "added application", app.processName);
8301        }
8302
8303        return app;
8304    }
8305
8306    public void unhandledBack() {
8307        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8308                "unhandledBack()");
8309
8310        synchronized(this) {
8311            final long origId = Binder.clearCallingIdentity();
8312            try {
8313                getFocusedStack().unhandledBackLocked();
8314            } finally {
8315                Binder.restoreCallingIdentity(origId);
8316            }
8317        }
8318    }
8319
8320    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8321        enforceNotIsolatedCaller("openContentUri");
8322        final int userId = UserHandle.getCallingUserId();
8323        String name = uri.getAuthority();
8324        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8325        ParcelFileDescriptor pfd = null;
8326        if (cph != null) {
8327            // We record the binder invoker's uid in thread-local storage before
8328            // going to the content provider to open the file.  Later, in the code
8329            // that handles all permissions checks, we look for this uid and use
8330            // that rather than the Activity Manager's own uid.  The effect is that
8331            // we do the check against the caller's permissions even though it looks
8332            // to the content provider like the Activity Manager itself is making
8333            // the request.
8334            sCallerIdentity.set(new Identity(
8335                    Binder.getCallingPid(), Binder.getCallingUid()));
8336            try {
8337                pfd = cph.provider.openFile(null, uri, "r", null);
8338            } catch (FileNotFoundException e) {
8339                // do nothing; pfd will be returned null
8340            } finally {
8341                // Ensure that whatever happens, we clean up the identity state
8342                sCallerIdentity.remove();
8343            }
8344
8345            // We've got the fd now, so we're done with the provider.
8346            removeContentProviderExternalUnchecked(name, null, userId);
8347        } else {
8348            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8349        }
8350        return pfd;
8351    }
8352
8353    // Actually is sleeping or shutting down or whatever else in the future
8354    // is an inactive state.
8355    public boolean isSleepingOrShuttingDown() {
8356        return mSleeping || mShuttingDown;
8357    }
8358
8359    public void goingToSleep() {
8360        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8361                != PackageManager.PERMISSION_GRANTED) {
8362            throw new SecurityException("Requires permission "
8363                    + android.Manifest.permission.DEVICE_POWER);
8364        }
8365
8366        synchronized(this) {
8367            mWentToSleep = true;
8368            updateEventDispatchingLocked();
8369
8370            if (!mSleeping) {
8371                mSleeping = true;
8372                mStackSupervisor.goingToSleepLocked();
8373
8374                // Initialize the wake times of all processes.
8375                checkExcessivePowerUsageLocked(false);
8376                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8377                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8378                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8379            }
8380        }
8381    }
8382
8383    @Override
8384    public boolean shutdown(int timeout) {
8385        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8386                != PackageManager.PERMISSION_GRANTED) {
8387            throw new SecurityException("Requires permission "
8388                    + android.Manifest.permission.SHUTDOWN);
8389        }
8390
8391        boolean timedout = false;
8392
8393        synchronized(this) {
8394            mShuttingDown = true;
8395            updateEventDispatchingLocked();
8396            timedout = mStackSupervisor.shutdownLocked(timeout);
8397        }
8398
8399        mAppOpsService.shutdown();
8400        mUsageStatsService.shutdown();
8401        mBatteryStatsService.shutdown();
8402        synchronized (this) {
8403            mProcessStats.shutdownLocked();
8404        }
8405
8406        return timedout;
8407    }
8408
8409    public final void activitySlept(IBinder token) {
8410        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8411
8412        final long origId = Binder.clearCallingIdentity();
8413
8414        synchronized (this) {
8415            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8416            if (r != null) {
8417                mStackSupervisor.activitySleptLocked(r);
8418            }
8419        }
8420
8421        Binder.restoreCallingIdentity(origId);
8422    }
8423
8424    void logLockScreen(String msg) {
8425        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8426                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8427                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8428                mStackSupervisor.mDismissKeyguardOnNextActivity);
8429    }
8430
8431    private void comeOutOfSleepIfNeededLocked() {
8432        if (!mWentToSleep && !mLockScreenShown) {
8433            if (mSleeping) {
8434                mSleeping = false;
8435                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8436            }
8437        }
8438    }
8439
8440    public void wakingUp() {
8441        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8442                != PackageManager.PERMISSION_GRANTED) {
8443            throw new SecurityException("Requires permission "
8444                    + android.Manifest.permission.DEVICE_POWER);
8445        }
8446
8447        synchronized(this) {
8448            mWentToSleep = false;
8449            updateEventDispatchingLocked();
8450            comeOutOfSleepIfNeededLocked();
8451        }
8452    }
8453
8454    private void updateEventDispatchingLocked() {
8455        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8456    }
8457
8458    public void setLockScreenShown(boolean shown) {
8459        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8460                != PackageManager.PERMISSION_GRANTED) {
8461            throw new SecurityException("Requires permission "
8462                    + android.Manifest.permission.DEVICE_POWER);
8463        }
8464
8465        synchronized(this) {
8466            long ident = Binder.clearCallingIdentity();
8467            try {
8468                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8469                mLockScreenShown = shown;
8470                comeOutOfSleepIfNeededLocked();
8471            } finally {
8472                Binder.restoreCallingIdentity(ident);
8473            }
8474        }
8475    }
8476
8477    public void stopAppSwitches() {
8478        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8479                != PackageManager.PERMISSION_GRANTED) {
8480            throw new SecurityException("Requires permission "
8481                    + android.Manifest.permission.STOP_APP_SWITCHES);
8482        }
8483
8484        synchronized(this) {
8485            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8486                    + APP_SWITCH_DELAY_TIME;
8487            mDidAppSwitch = false;
8488            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8489            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8490            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8491        }
8492    }
8493
8494    public void resumeAppSwitches() {
8495        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8496                != PackageManager.PERMISSION_GRANTED) {
8497            throw new SecurityException("Requires permission "
8498                    + android.Manifest.permission.STOP_APP_SWITCHES);
8499        }
8500
8501        synchronized(this) {
8502            // Note that we don't execute any pending app switches... we will
8503            // let those wait until either the timeout, or the next start
8504            // activity request.
8505            mAppSwitchesAllowedTime = 0;
8506        }
8507    }
8508
8509    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8510            String name) {
8511        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8512            return true;
8513        }
8514
8515        final int perm = checkComponentPermission(
8516                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8517                callingUid, -1, true);
8518        if (perm == PackageManager.PERMISSION_GRANTED) {
8519            return true;
8520        }
8521
8522        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8523        return false;
8524    }
8525
8526    public void setDebugApp(String packageName, boolean waitForDebugger,
8527            boolean persistent) {
8528        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8529                "setDebugApp()");
8530
8531        long ident = Binder.clearCallingIdentity();
8532        try {
8533            // Note that this is not really thread safe if there are multiple
8534            // callers into it at the same time, but that's not a situation we
8535            // care about.
8536            if (persistent) {
8537                final ContentResolver resolver = mContext.getContentResolver();
8538                Settings.Global.putString(
8539                    resolver, Settings.Global.DEBUG_APP,
8540                    packageName);
8541                Settings.Global.putInt(
8542                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8543                    waitForDebugger ? 1 : 0);
8544            }
8545
8546            synchronized (this) {
8547                if (!persistent) {
8548                    mOrigDebugApp = mDebugApp;
8549                    mOrigWaitForDebugger = mWaitForDebugger;
8550                }
8551                mDebugApp = packageName;
8552                mWaitForDebugger = waitForDebugger;
8553                mDebugTransient = !persistent;
8554                if (packageName != null) {
8555                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8556                            false, UserHandle.USER_ALL, "set debug app");
8557                }
8558            }
8559        } finally {
8560            Binder.restoreCallingIdentity(ident);
8561        }
8562    }
8563
8564    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8565        synchronized (this) {
8566            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8567            if (!isDebuggable) {
8568                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8569                    throw new SecurityException("Process not debuggable: " + app.packageName);
8570                }
8571            }
8572
8573            mOpenGlTraceApp = processName;
8574        }
8575    }
8576
8577    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8578            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8579        synchronized (this) {
8580            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8581            if (!isDebuggable) {
8582                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8583                    throw new SecurityException("Process not debuggable: " + app.packageName);
8584                }
8585            }
8586            mProfileApp = processName;
8587            mProfileFile = profileFile;
8588            if (mProfileFd != null) {
8589                try {
8590                    mProfileFd.close();
8591                } catch (IOException e) {
8592                }
8593                mProfileFd = null;
8594            }
8595            mProfileFd = profileFd;
8596            mProfileType = 0;
8597            mAutoStopProfiler = autoStopProfiler;
8598        }
8599    }
8600
8601    @Override
8602    public void setAlwaysFinish(boolean enabled) {
8603        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8604                "setAlwaysFinish()");
8605
8606        Settings.Global.putInt(
8607                mContext.getContentResolver(),
8608                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8609
8610        synchronized (this) {
8611            mAlwaysFinishActivities = enabled;
8612        }
8613    }
8614
8615    @Override
8616    public void setActivityController(IActivityController controller) {
8617        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8618                "setActivityController()");
8619        synchronized (this) {
8620            mController = controller;
8621            Watchdog.getInstance().setActivityController(controller);
8622        }
8623    }
8624
8625    @Override
8626    public void setUserIsMonkey(boolean userIsMonkey) {
8627        synchronized (this) {
8628            synchronized (mPidsSelfLocked) {
8629                final int callingPid = Binder.getCallingPid();
8630                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8631                if (precessRecord == null) {
8632                    throw new SecurityException("Unknown process: " + callingPid);
8633                }
8634                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8635                    throw new SecurityException("Only an instrumentation process "
8636                            + "with a UiAutomation can call setUserIsMonkey");
8637                }
8638            }
8639            mUserIsMonkey = userIsMonkey;
8640        }
8641    }
8642
8643    @Override
8644    public boolean isUserAMonkey() {
8645        synchronized (this) {
8646            // If there is a controller also implies the user is a monkey.
8647            return (mUserIsMonkey || mController != null);
8648        }
8649    }
8650
8651    public void requestBugReport() {
8652        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8653        SystemProperties.set("ctl.start", "bugreport");
8654    }
8655
8656    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8657        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8658    }
8659
8660    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8661        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8662            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8663        }
8664        return KEY_DISPATCHING_TIMEOUT;
8665    }
8666
8667    @Override
8668    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8669        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8670                != PackageManager.PERMISSION_GRANTED) {
8671            throw new SecurityException("Requires permission "
8672                    + android.Manifest.permission.FILTER_EVENTS);
8673        }
8674        ProcessRecord proc;
8675        long timeout;
8676        synchronized (this) {
8677            synchronized (mPidsSelfLocked) {
8678                proc = mPidsSelfLocked.get(pid);
8679            }
8680            timeout = getInputDispatchingTimeoutLocked(proc);
8681        }
8682
8683        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8684            return -1;
8685        }
8686
8687        return timeout;
8688    }
8689
8690    /**
8691     * Handle input dispatching timeouts.
8692     * Returns whether input dispatching should be aborted or not.
8693     */
8694    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8695            final ActivityRecord activity, final ActivityRecord parent,
8696            final boolean aboveSystem, String reason) {
8697        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8698                != PackageManager.PERMISSION_GRANTED) {
8699            throw new SecurityException("Requires permission "
8700                    + android.Manifest.permission.FILTER_EVENTS);
8701        }
8702
8703        final String annotation;
8704        if (reason == null) {
8705            annotation = "Input dispatching timed out";
8706        } else {
8707            annotation = "Input dispatching timed out (" + reason + ")";
8708        }
8709
8710        if (proc != null) {
8711            synchronized (this) {
8712                if (proc.debugging) {
8713                    return false;
8714                }
8715
8716                if (mDidDexOpt) {
8717                    // Give more time since we were dexopting.
8718                    mDidDexOpt = false;
8719                    return false;
8720                }
8721
8722                if (proc.instrumentationClass != null) {
8723                    Bundle info = new Bundle();
8724                    info.putString("shortMsg", "keyDispatchingTimedOut");
8725                    info.putString("longMsg", annotation);
8726                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8727                    return true;
8728                }
8729            }
8730            mHandler.post(new Runnable() {
8731                @Override
8732                public void run() {
8733                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8734                }
8735            });
8736        }
8737
8738        return true;
8739    }
8740
8741    public Bundle getAssistContextExtras(int requestType) {
8742        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8743                "getAssistContextExtras()");
8744        PendingAssistExtras pae;
8745        Bundle extras = new Bundle();
8746        synchronized (this) {
8747            ActivityRecord activity = getFocusedStack().mResumedActivity;
8748            if (activity == null) {
8749                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8750                return null;
8751            }
8752            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8753            if (activity.app == null || activity.app.thread == null) {
8754                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8755                return extras;
8756            }
8757            if (activity.app.pid == Binder.getCallingPid()) {
8758                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8759                return extras;
8760            }
8761            pae = new PendingAssistExtras(activity);
8762            try {
8763                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8764                        requestType);
8765                mPendingAssistExtras.add(pae);
8766                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8767            } catch (RemoteException e) {
8768                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8769                return extras;
8770            }
8771        }
8772        synchronized (pae) {
8773            while (!pae.haveResult) {
8774                try {
8775                    pae.wait();
8776                } catch (InterruptedException e) {
8777                }
8778            }
8779            if (pae.result != null) {
8780                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8781            }
8782        }
8783        synchronized (this) {
8784            mPendingAssistExtras.remove(pae);
8785            mHandler.removeCallbacks(pae);
8786        }
8787        return extras;
8788    }
8789
8790    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8791        PendingAssistExtras pae = (PendingAssistExtras)token;
8792        synchronized (pae) {
8793            pae.result = extras;
8794            pae.haveResult = true;
8795            pae.notifyAll();
8796        }
8797    }
8798
8799    public void registerProcessObserver(IProcessObserver observer) {
8800        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8801                "registerProcessObserver()");
8802        synchronized (this) {
8803            mProcessObservers.register(observer);
8804        }
8805    }
8806
8807    @Override
8808    public void unregisterProcessObserver(IProcessObserver observer) {
8809        synchronized (this) {
8810            mProcessObservers.unregister(observer);
8811        }
8812    }
8813
8814    @Override
8815    public boolean convertFromTranslucent(IBinder token) {
8816        final long origId = Binder.clearCallingIdentity();
8817        try {
8818            synchronized (this) {
8819                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8820                if (r == null) {
8821                    return false;
8822                }
8823                if (r.changeWindowTranslucency(true)) {
8824                    mWindowManager.setAppFullscreen(token, true);
8825                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8826                    return true;
8827                }
8828                return false;
8829            }
8830        } finally {
8831            Binder.restoreCallingIdentity(origId);
8832        }
8833    }
8834
8835    @Override
8836    public boolean convertToTranslucent(IBinder token) {
8837        final long origId = Binder.clearCallingIdentity();
8838        try {
8839            synchronized (this) {
8840                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8841                if (r == null) {
8842                    return false;
8843                }
8844                if (r.changeWindowTranslucency(false)) {
8845                    r.task.stack.convertToTranslucent(r);
8846                    mWindowManager.setAppFullscreen(token, false);
8847                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8848                    return true;
8849                }
8850                return false;
8851            }
8852        } finally {
8853            Binder.restoreCallingIdentity(origId);
8854        }
8855    }
8856
8857    @Override
8858    public void setImmersive(IBinder token, boolean immersive) {
8859        synchronized(this) {
8860            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8861            if (r == null) {
8862                throw new IllegalArgumentException();
8863            }
8864            r.immersive = immersive;
8865
8866            // update associated state if we're frontmost
8867            if (r == mFocusedActivity) {
8868                if (DEBUG_IMMERSIVE) {
8869                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8870                }
8871                applyUpdateLockStateLocked(r);
8872            }
8873        }
8874    }
8875
8876    @Override
8877    public boolean isImmersive(IBinder token) {
8878        synchronized (this) {
8879            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8880            if (r == null) {
8881                throw new IllegalArgumentException();
8882            }
8883            return r.immersive;
8884        }
8885    }
8886
8887    public boolean isTopActivityImmersive() {
8888        enforceNotIsolatedCaller("startActivity");
8889        synchronized (this) {
8890            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8891            return (r != null) ? r.immersive : false;
8892        }
8893    }
8894
8895    public final void enterSafeMode() {
8896        synchronized(this) {
8897            // It only makes sense to do this before the system is ready
8898            // and started launching other packages.
8899            if (!mSystemReady) {
8900                try {
8901                    AppGlobals.getPackageManager().enterSafeMode();
8902                } catch (RemoteException e) {
8903                }
8904            }
8905        }
8906    }
8907
8908    public final void showSafeModeOverlay() {
8909        View v = LayoutInflater.from(mContext).inflate(
8910                com.android.internal.R.layout.safe_mode, null);
8911        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8912        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8913        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8914        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8915        lp.gravity = Gravity.BOTTOM | Gravity.START;
8916        lp.format = v.getBackground().getOpacity();
8917        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8918                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8919        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8920        ((WindowManager)mContext.getSystemService(
8921                Context.WINDOW_SERVICE)).addView(v, lp);
8922    }
8923
8924    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8925        if (!(sender instanceof PendingIntentRecord)) {
8926            return;
8927        }
8928        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8929        synchronized (stats) {
8930            if (mBatteryStatsService.isOnBattery()) {
8931                mBatteryStatsService.enforceCallingPermission();
8932                PendingIntentRecord rec = (PendingIntentRecord)sender;
8933                int MY_UID = Binder.getCallingUid();
8934                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8935                BatteryStatsImpl.Uid.Pkg pkg =
8936                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8937                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8938                pkg.incWakeupsLocked();
8939            }
8940        }
8941    }
8942
8943    public boolean killPids(int[] pids, String pReason, boolean secure) {
8944        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8945            throw new SecurityException("killPids only available to the system");
8946        }
8947        String reason = (pReason == null) ? "Unknown" : pReason;
8948        // XXX Note: don't acquire main activity lock here, because the window
8949        // manager calls in with its locks held.
8950
8951        boolean killed = false;
8952        synchronized (mPidsSelfLocked) {
8953            int[] types = new int[pids.length];
8954            int worstType = 0;
8955            for (int i=0; i<pids.length; i++) {
8956                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8957                if (proc != null) {
8958                    int type = proc.setAdj;
8959                    types[i] = type;
8960                    if (type > worstType) {
8961                        worstType = type;
8962                    }
8963                }
8964            }
8965
8966            // If the worst oom_adj is somewhere in the cached proc LRU range,
8967            // then constrain it so we will kill all cached procs.
8968            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8969                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8970                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8971            }
8972
8973            // If this is not a secure call, don't let it kill processes that
8974            // are important.
8975            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8976                worstType = ProcessList.SERVICE_ADJ;
8977            }
8978
8979            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8980            for (int i=0; i<pids.length; i++) {
8981                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8982                if (proc == null) {
8983                    continue;
8984                }
8985                int adj = proc.setAdj;
8986                if (adj >= worstType && !proc.killedByAm) {
8987                    killUnneededProcessLocked(proc, reason);
8988                    killed = true;
8989                }
8990            }
8991        }
8992        return killed;
8993    }
8994
8995    @Override
8996    public void killUid(int uid, String reason) {
8997        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8998            throw new SecurityException("killUid only available to the system");
8999        }
9000        synchronized (this) {
9001            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9002                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9003                    reason != null ? reason : "kill uid");
9004        }
9005    }
9006
9007    @Override
9008    public boolean killProcessesBelowForeground(String reason) {
9009        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9010            throw new SecurityException("killProcessesBelowForeground() only available to system");
9011        }
9012
9013        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9014    }
9015
9016    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9017        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9018            throw new SecurityException("killProcessesBelowAdj() only available to system");
9019        }
9020
9021        boolean killed = false;
9022        synchronized (mPidsSelfLocked) {
9023            final int size = mPidsSelfLocked.size();
9024            for (int i = 0; i < size; i++) {
9025                final int pid = mPidsSelfLocked.keyAt(i);
9026                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9027                if (proc == null) continue;
9028
9029                final int adj = proc.setAdj;
9030                if (adj > belowAdj && !proc.killedByAm) {
9031                    killUnneededProcessLocked(proc, reason);
9032                    killed = true;
9033                }
9034            }
9035        }
9036        return killed;
9037    }
9038
9039    @Override
9040    public void hang(final IBinder who, boolean allowRestart) {
9041        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9042                != PackageManager.PERMISSION_GRANTED) {
9043            throw new SecurityException("Requires permission "
9044                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9045        }
9046
9047        final IBinder.DeathRecipient death = new DeathRecipient() {
9048            @Override
9049            public void binderDied() {
9050                synchronized (this) {
9051                    notifyAll();
9052                }
9053            }
9054        };
9055
9056        try {
9057            who.linkToDeath(death, 0);
9058        } catch (RemoteException e) {
9059            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9060            return;
9061        }
9062
9063        synchronized (this) {
9064            Watchdog.getInstance().setAllowRestart(allowRestart);
9065            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9066            synchronized (death) {
9067                while (who.isBinderAlive()) {
9068                    try {
9069                        death.wait();
9070                    } catch (InterruptedException e) {
9071                    }
9072                }
9073            }
9074            Watchdog.getInstance().setAllowRestart(true);
9075        }
9076    }
9077
9078    @Override
9079    public void restart() {
9080        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9081                != PackageManager.PERMISSION_GRANTED) {
9082            throw new SecurityException("Requires permission "
9083                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9084        }
9085
9086        Log.i(TAG, "Sending shutdown broadcast...");
9087
9088        BroadcastReceiver br = new BroadcastReceiver() {
9089            @Override public void onReceive(Context context, Intent intent) {
9090                // Now the broadcast is done, finish up the low-level shutdown.
9091                Log.i(TAG, "Shutting down activity manager...");
9092                shutdown(10000);
9093                Log.i(TAG, "Shutdown complete, restarting!");
9094                Process.killProcess(Process.myPid());
9095                System.exit(10);
9096            }
9097        };
9098
9099        // First send the high-level shut down broadcast.
9100        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9101        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9102        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9103        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9104        mContext.sendOrderedBroadcastAsUser(intent,
9105                UserHandle.ALL, null, br, mHandler, 0, null, null);
9106        */
9107        br.onReceive(mContext, intent);
9108    }
9109
9110    private long getLowRamTimeSinceIdle(long now) {
9111        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9112    }
9113
9114    @Override
9115    public void performIdleMaintenance() {
9116        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9117                != PackageManager.PERMISSION_GRANTED) {
9118            throw new SecurityException("Requires permission "
9119                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9120        }
9121
9122        synchronized (this) {
9123            final long now = SystemClock.uptimeMillis();
9124            final long timeSinceLastIdle = now - mLastIdleTime;
9125            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9126            mLastIdleTime = now;
9127            mLowRamTimeSinceLastIdle = 0;
9128            if (mLowRamStartTime != 0) {
9129                mLowRamStartTime = now;
9130            }
9131
9132            StringBuilder sb = new StringBuilder(128);
9133            sb.append("Idle maintenance over ");
9134            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9135            sb.append(" low RAM for ");
9136            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9137            Slog.i(TAG, sb.toString());
9138
9139            // If at least 1/3 of our time since the last idle period has been spent
9140            // with RAM low, then we want to kill processes.
9141            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9142
9143            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9144                ProcessRecord proc = mLruProcesses.get(i);
9145                if (proc.notCachedSinceIdle) {
9146                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9147                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9148                        if (doKilling && proc.initialIdlePss != 0
9149                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9150                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9151                                    + " from " + proc.initialIdlePss + ")");
9152                        }
9153                    }
9154                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9155                    proc.notCachedSinceIdle = true;
9156                    proc.initialIdlePss = 0;
9157                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9158                            mSleeping, now);
9159                }
9160            }
9161
9162            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9163            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9164        }
9165    }
9166
9167    public final void startRunning(String pkg, String cls, String action,
9168            String data) {
9169        synchronized(this) {
9170            if (mStartRunning) {
9171                return;
9172            }
9173            mStartRunning = true;
9174            mTopComponent = pkg != null && cls != null
9175                    ? new ComponentName(pkg, cls) : null;
9176            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9177            mTopData = data;
9178            if (!mSystemReady) {
9179                return;
9180            }
9181        }
9182
9183        systemReady(null);
9184    }
9185
9186    private void retrieveSettings() {
9187        final ContentResolver resolver = mContext.getContentResolver();
9188        String debugApp = Settings.Global.getString(
9189            resolver, Settings.Global.DEBUG_APP);
9190        boolean waitForDebugger = Settings.Global.getInt(
9191            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9192        boolean alwaysFinishActivities = Settings.Global.getInt(
9193            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9194        boolean forceRtl = Settings.Global.getInt(
9195                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9196        // Transfer any global setting for forcing RTL layout, into a System Property
9197        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9198
9199        Configuration configuration = new Configuration();
9200        Settings.System.getConfiguration(resolver, configuration);
9201        if (forceRtl) {
9202            // This will take care of setting the correct layout direction flags
9203            configuration.setLayoutDirection(configuration.locale);
9204        }
9205
9206        synchronized (this) {
9207            mDebugApp = mOrigDebugApp = debugApp;
9208            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9209            mAlwaysFinishActivities = alwaysFinishActivities;
9210            // This happens before any activities are started, so we can
9211            // change mConfiguration in-place.
9212            updateConfigurationLocked(configuration, null, false, true);
9213            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9214        }
9215    }
9216
9217    public boolean testIsSystemReady() {
9218        // no need to synchronize(this) just to read & return the value
9219        return mSystemReady;
9220    }
9221
9222    private static File getCalledPreBootReceiversFile() {
9223        File dataDir = Environment.getDataDirectory();
9224        File systemDir = new File(dataDir, "system");
9225        File fname = new File(systemDir, "called_pre_boots.dat");
9226        return fname;
9227    }
9228
9229    static final int LAST_DONE_VERSION = 10000;
9230
9231    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9232        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9233        File file = getCalledPreBootReceiversFile();
9234        FileInputStream fis = null;
9235        try {
9236            fis = new FileInputStream(file);
9237            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9238            int fvers = dis.readInt();
9239            if (fvers == LAST_DONE_VERSION) {
9240                String vers = dis.readUTF();
9241                String codename = dis.readUTF();
9242                String build = dis.readUTF();
9243                if (android.os.Build.VERSION.RELEASE.equals(vers)
9244                        && android.os.Build.VERSION.CODENAME.equals(codename)
9245                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9246                    int num = dis.readInt();
9247                    while (num > 0) {
9248                        num--;
9249                        String pkg = dis.readUTF();
9250                        String cls = dis.readUTF();
9251                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9252                    }
9253                }
9254            }
9255        } catch (FileNotFoundException e) {
9256        } catch (IOException e) {
9257            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9258        } finally {
9259            if (fis != null) {
9260                try {
9261                    fis.close();
9262                } catch (IOException e) {
9263                }
9264            }
9265        }
9266        return lastDoneReceivers;
9267    }
9268
9269    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9270        File file = getCalledPreBootReceiversFile();
9271        FileOutputStream fos = null;
9272        DataOutputStream dos = null;
9273        try {
9274            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9275            fos = new FileOutputStream(file);
9276            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9277            dos.writeInt(LAST_DONE_VERSION);
9278            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9279            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9280            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9281            dos.writeInt(list.size());
9282            for (int i=0; i<list.size(); i++) {
9283                dos.writeUTF(list.get(i).getPackageName());
9284                dos.writeUTF(list.get(i).getClassName());
9285            }
9286        } catch (IOException e) {
9287            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9288            file.delete();
9289        } finally {
9290            FileUtils.sync(fos);
9291            if (dos != null) {
9292                try {
9293                    dos.close();
9294                } catch (IOException e) {
9295                    // TODO Auto-generated catch block
9296                    e.printStackTrace();
9297                }
9298            }
9299        }
9300    }
9301
9302    public void systemReady(final Runnable goingCallback) {
9303        synchronized(this) {
9304            if (mSystemReady) {
9305                if (goingCallback != null) goingCallback.run();
9306                return;
9307            }
9308
9309            // Check to see if there are any update receivers to run.
9310            if (!mDidUpdate) {
9311                if (mWaitingUpdate) {
9312                    return;
9313                }
9314                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9315                List<ResolveInfo> ris = null;
9316                try {
9317                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9318                            intent, null, 0, 0);
9319                } catch (RemoteException e) {
9320                }
9321                if (ris != null) {
9322                    for (int i=ris.size()-1; i>=0; i--) {
9323                        if ((ris.get(i).activityInfo.applicationInfo.flags
9324                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9325                            ris.remove(i);
9326                        }
9327                    }
9328                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9329
9330                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9331
9332                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9333                    for (int i=0; i<ris.size(); i++) {
9334                        ActivityInfo ai = ris.get(i).activityInfo;
9335                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9336                        if (lastDoneReceivers.contains(comp)) {
9337                            // We already did the pre boot receiver for this app with the current
9338                            // platform version, so don't do it again...
9339                            ris.remove(i);
9340                            i--;
9341                            // ...however, do keep it as one that has been done, so we don't
9342                            // forget about it when rewriting the file of last done receivers.
9343                            doneReceivers.add(comp);
9344                        }
9345                    }
9346
9347                    final int[] users = getUsersLocked();
9348                    for (int i=0; i<ris.size(); i++) {
9349                        ActivityInfo ai = ris.get(i).activityInfo;
9350                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9351                        doneReceivers.add(comp);
9352                        intent.setComponent(comp);
9353                        for (int j=0; j<users.length; j++) {
9354                            IIntentReceiver finisher = null;
9355                            if (i == ris.size()-1 && j == users.length-1) {
9356                                finisher = new IIntentReceiver.Stub() {
9357                                    public void performReceive(Intent intent, int resultCode,
9358                                            String data, Bundle extras, boolean ordered,
9359                                            boolean sticky, int sendingUser) {
9360                                        // The raw IIntentReceiver interface is called
9361                                        // with the AM lock held, so redispatch to
9362                                        // execute our code without the lock.
9363                                        mHandler.post(new Runnable() {
9364                                            public void run() {
9365                                                synchronized (ActivityManagerService.this) {
9366                                                    mDidUpdate = true;
9367                                                }
9368                                                writeLastDonePreBootReceivers(doneReceivers);
9369                                                showBootMessage(mContext.getText(
9370                                                        R.string.android_upgrading_complete),
9371                                                        false);
9372                                                systemReady(goingCallback);
9373                                            }
9374                                        });
9375                                    }
9376                                };
9377                            }
9378                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9379                                    + " for user " + users[j]);
9380                            broadcastIntentLocked(null, null, intent, null, finisher,
9381                                    0, null, null, null, AppOpsManager.OP_NONE,
9382                                    true, false, MY_PID, Process.SYSTEM_UID,
9383                                    users[j]);
9384                            if (finisher != null) {
9385                                mWaitingUpdate = true;
9386                            }
9387                        }
9388                    }
9389                }
9390                if (mWaitingUpdate) {
9391                    return;
9392                }
9393                mDidUpdate = true;
9394            }
9395
9396            mAppOpsService.systemReady();
9397            mSystemReady = true;
9398            if (!mStartRunning) {
9399                return;
9400            }
9401        }
9402
9403        ArrayList<ProcessRecord> procsToKill = null;
9404        synchronized(mPidsSelfLocked) {
9405            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9406                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9407                if (!isAllowedWhileBooting(proc.info)){
9408                    if (procsToKill == null) {
9409                        procsToKill = new ArrayList<ProcessRecord>();
9410                    }
9411                    procsToKill.add(proc);
9412                }
9413            }
9414        }
9415
9416        synchronized(this) {
9417            if (procsToKill != null) {
9418                for (int i=procsToKill.size()-1; i>=0; i--) {
9419                    ProcessRecord proc = procsToKill.get(i);
9420                    Slog.i(TAG, "Removing system update proc: " + proc);
9421                    removeProcessLocked(proc, true, false, "system update done");
9422                }
9423            }
9424
9425            // Now that we have cleaned up any update processes, we
9426            // are ready to start launching real processes and know that
9427            // we won't trample on them any more.
9428            mProcessesReady = true;
9429        }
9430
9431        Slog.i(TAG, "System now ready");
9432        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9433            SystemClock.uptimeMillis());
9434
9435        synchronized(this) {
9436            // Make sure we have no pre-ready processes sitting around.
9437
9438            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9439                ResolveInfo ri = mContext.getPackageManager()
9440                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9441                                STOCK_PM_FLAGS);
9442                CharSequence errorMsg = null;
9443                if (ri != null) {
9444                    ActivityInfo ai = ri.activityInfo;
9445                    ApplicationInfo app = ai.applicationInfo;
9446                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9447                        mTopAction = Intent.ACTION_FACTORY_TEST;
9448                        mTopData = null;
9449                        mTopComponent = new ComponentName(app.packageName,
9450                                ai.name);
9451                    } else {
9452                        errorMsg = mContext.getResources().getText(
9453                                com.android.internal.R.string.factorytest_not_system);
9454                    }
9455                } else {
9456                    errorMsg = mContext.getResources().getText(
9457                            com.android.internal.R.string.factorytest_no_action);
9458                }
9459                if (errorMsg != null) {
9460                    mTopAction = null;
9461                    mTopData = null;
9462                    mTopComponent = null;
9463                    Message msg = Message.obtain();
9464                    msg.what = SHOW_FACTORY_ERROR_MSG;
9465                    msg.getData().putCharSequence("msg", errorMsg);
9466                    mHandler.sendMessage(msg);
9467                }
9468            }
9469        }
9470
9471        retrieveSettings();
9472
9473        synchronized (this) {
9474            readGrantedUriPermissionsLocked();
9475        }
9476
9477        if (goingCallback != null) goingCallback.run();
9478
9479        synchronized (this) {
9480            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9481                try {
9482                    List apps = AppGlobals.getPackageManager().
9483                        getPersistentApplications(STOCK_PM_FLAGS);
9484                    if (apps != null) {
9485                        int N = apps.size();
9486                        int i;
9487                        for (i=0; i<N; i++) {
9488                            ApplicationInfo info
9489                                = (ApplicationInfo)apps.get(i);
9490                            if (info != null &&
9491                                    !info.packageName.equals("android")) {
9492                                addAppLocked(info, false);
9493                            }
9494                        }
9495                    }
9496                } catch (RemoteException ex) {
9497                    // pm is in same process, this will never happen.
9498                }
9499            }
9500
9501            // Start up initial activity.
9502            mBooting = true;
9503
9504            try {
9505                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9506                    Message msg = Message.obtain();
9507                    msg.what = SHOW_UID_ERROR_MSG;
9508                    mHandler.sendMessage(msg);
9509                }
9510            } catch (RemoteException e) {
9511            }
9512
9513            long ident = Binder.clearCallingIdentity();
9514            try {
9515                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9516                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9517                        | Intent.FLAG_RECEIVER_FOREGROUND);
9518                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9519                broadcastIntentLocked(null, null, intent,
9520                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9521                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9522                intent = new Intent(Intent.ACTION_USER_STARTING);
9523                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9524                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9525                broadcastIntentLocked(null, null, intent,
9526                        null, new IIntentReceiver.Stub() {
9527                            @Override
9528                            public void performReceive(Intent intent, int resultCode, String data,
9529                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9530                                    throws RemoteException {
9531                            }
9532                        }, 0, null, null,
9533                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9534                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9535            } finally {
9536                Binder.restoreCallingIdentity(ident);
9537            }
9538            mStackSupervisor.resumeTopActivitiesLocked();
9539            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9540        }
9541    }
9542
9543    private boolean makeAppCrashingLocked(ProcessRecord app,
9544            String shortMsg, String longMsg, String stackTrace) {
9545        app.crashing = true;
9546        app.crashingReport = generateProcessError(app,
9547                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9548        startAppProblemLocked(app);
9549        app.stopFreezingAllLocked();
9550        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9551    }
9552
9553    private void makeAppNotRespondingLocked(ProcessRecord app,
9554            String activity, String shortMsg, String longMsg) {
9555        app.notResponding = true;
9556        app.notRespondingReport = generateProcessError(app,
9557                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9558                activity, shortMsg, longMsg, null);
9559        startAppProblemLocked(app);
9560        app.stopFreezingAllLocked();
9561    }
9562
9563    /**
9564     * Generate a process error record, suitable for attachment to a ProcessRecord.
9565     *
9566     * @param app The ProcessRecord in which the error occurred.
9567     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9568     *                      ActivityManager.AppErrorStateInfo
9569     * @param activity The activity associated with the crash, if known.
9570     * @param shortMsg Short message describing the crash.
9571     * @param longMsg Long message describing the crash.
9572     * @param stackTrace Full crash stack trace, may be null.
9573     *
9574     * @return Returns a fully-formed AppErrorStateInfo record.
9575     */
9576    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9577            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9578        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9579
9580        report.condition = condition;
9581        report.processName = app.processName;
9582        report.pid = app.pid;
9583        report.uid = app.info.uid;
9584        report.tag = activity;
9585        report.shortMsg = shortMsg;
9586        report.longMsg = longMsg;
9587        report.stackTrace = stackTrace;
9588
9589        return report;
9590    }
9591
9592    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9593        synchronized (this) {
9594            app.crashing = false;
9595            app.crashingReport = null;
9596            app.notResponding = false;
9597            app.notRespondingReport = null;
9598            if (app.anrDialog == fromDialog) {
9599                app.anrDialog = null;
9600            }
9601            if (app.waitDialog == fromDialog) {
9602                app.waitDialog = null;
9603            }
9604            if (app.pid > 0 && app.pid != MY_PID) {
9605                handleAppCrashLocked(app, null, null, null);
9606                killUnneededProcessLocked(app, "user request after error");
9607            }
9608        }
9609    }
9610
9611    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9612            String stackTrace) {
9613        long now = SystemClock.uptimeMillis();
9614
9615        Long crashTime;
9616        if (!app.isolated) {
9617            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9618        } else {
9619            crashTime = null;
9620        }
9621        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9622            // This process loses!
9623            Slog.w(TAG, "Process " + app.info.processName
9624                    + " has crashed too many times: killing!");
9625            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9626                    app.userId, app.info.processName, app.uid);
9627            mStackSupervisor.handleAppCrashLocked(app);
9628            if (!app.persistent) {
9629                // We don't want to start this process again until the user
9630                // explicitly does so...  but for persistent process, we really
9631                // need to keep it running.  If a persistent process is actually
9632                // repeatedly crashing, then badness for everyone.
9633                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9634                        app.info.processName);
9635                if (!app.isolated) {
9636                    // XXX We don't have a way to mark isolated processes
9637                    // as bad, since they don't have a peristent identity.
9638                    mBadProcesses.put(app.info.processName, app.uid,
9639                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9640                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9641                }
9642                app.bad = true;
9643                app.removed = true;
9644                // Don't let services in this process be restarted and potentially
9645                // annoy the user repeatedly.  Unless it is persistent, since those
9646                // processes run critical code.
9647                removeProcessLocked(app, false, false, "crash");
9648                mStackSupervisor.resumeTopActivitiesLocked();
9649                return false;
9650            }
9651            mStackSupervisor.resumeTopActivitiesLocked();
9652        } else {
9653            mStackSupervisor.finishTopRunningActivityLocked(app);
9654        }
9655
9656        // Bump up the crash count of any services currently running in the proc.
9657        for (int i=app.services.size()-1; i>=0; i--) {
9658            // Any services running in the application need to be placed
9659            // back in the pending list.
9660            ServiceRecord sr = app.services.valueAt(i);
9661            sr.crashCount++;
9662        }
9663
9664        // If the crashing process is what we consider to be the "home process" and it has been
9665        // replaced by a third-party app, clear the package preferred activities from packages
9666        // with a home activity running in the process to prevent a repeatedly crashing app
9667        // from blocking the user to manually clear the list.
9668        final ArrayList<ActivityRecord> activities = app.activities;
9669        if (app == mHomeProcess && activities.size() > 0
9670                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9671            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9672                final ActivityRecord r = activities.get(activityNdx);
9673                if (r.isHomeActivity()) {
9674                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9675                    try {
9676                        ActivityThread.getPackageManager()
9677                                .clearPackagePreferredActivities(r.packageName);
9678                    } catch (RemoteException c) {
9679                        // pm is in same process, this will never happen.
9680                    }
9681                }
9682            }
9683        }
9684
9685        if (!app.isolated) {
9686            // XXX Can't keep track of crash times for isolated processes,
9687            // because they don't have a perisistent identity.
9688            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9689        }
9690
9691        return true;
9692    }
9693
9694    void startAppProblemLocked(ProcessRecord app) {
9695        if (app.userId == mCurrentUserId) {
9696            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9697                    mContext, app.info.packageName, app.info.flags);
9698        } else {
9699            // If this app is not running under the current user, then we
9700            // can't give it a report button because that would require
9701            // launching the report UI under a different user.
9702            app.errorReportReceiver = null;
9703        }
9704        skipCurrentReceiverLocked(app);
9705    }
9706
9707    void skipCurrentReceiverLocked(ProcessRecord app) {
9708        for (BroadcastQueue queue : mBroadcastQueues) {
9709            queue.skipCurrentReceiverLocked(app);
9710        }
9711    }
9712
9713    /**
9714     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9715     * The application process will exit immediately after this call returns.
9716     * @param app object of the crashing app, null for the system server
9717     * @param crashInfo describing the exception
9718     */
9719    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9720        ProcessRecord r = findAppProcess(app, "Crash");
9721        final String processName = app == null ? "system_server"
9722                : (r == null ? "unknown" : r.processName);
9723
9724        handleApplicationCrashInner("crash", r, processName, crashInfo);
9725    }
9726
9727    /* Native crash reporting uses this inner version because it needs to be somewhat
9728     * decoupled from the AM-managed cleanup lifecycle
9729     */
9730    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9731            ApplicationErrorReport.CrashInfo crashInfo) {
9732        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9733                UserHandle.getUserId(Binder.getCallingUid()), processName,
9734                r == null ? -1 : r.info.flags,
9735                crashInfo.exceptionClassName,
9736                crashInfo.exceptionMessage,
9737                crashInfo.throwFileName,
9738                crashInfo.throwLineNumber);
9739
9740        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9741
9742        crashApplication(r, crashInfo);
9743    }
9744
9745    public void handleApplicationStrictModeViolation(
9746            IBinder app,
9747            int violationMask,
9748            StrictMode.ViolationInfo info) {
9749        ProcessRecord r = findAppProcess(app, "StrictMode");
9750        if (r == null) {
9751            return;
9752        }
9753
9754        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9755            Integer stackFingerprint = info.hashCode();
9756            boolean logIt = true;
9757            synchronized (mAlreadyLoggedViolatedStacks) {
9758                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9759                    logIt = false;
9760                    // TODO: sub-sample into EventLog for these, with
9761                    // the info.durationMillis?  Then we'd get
9762                    // the relative pain numbers, without logging all
9763                    // the stack traces repeatedly.  We'd want to do
9764                    // likewise in the client code, which also does
9765                    // dup suppression, before the Binder call.
9766                } else {
9767                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9768                        mAlreadyLoggedViolatedStacks.clear();
9769                    }
9770                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9771                }
9772            }
9773            if (logIt) {
9774                logStrictModeViolationToDropBox(r, info);
9775            }
9776        }
9777
9778        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9779            AppErrorResult result = new AppErrorResult();
9780            synchronized (this) {
9781                final long origId = Binder.clearCallingIdentity();
9782
9783                Message msg = Message.obtain();
9784                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9785                HashMap<String, Object> data = new HashMap<String, Object>();
9786                data.put("result", result);
9787                data.put("app", r);
9788                data.put("violationMask", violationMask);
9789                data.put("info", info);
9790                msg.obj = data;
9791                mHandler.sendMessage(msg);
9792
9793                Binder.restoreCallingIdentity(origId);
9794            }
9795            int res = result.get();
9796            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9797        }
9798    }
9799
9800    // Depending on the policy in effect, there could be a bunch of
9801    // these in quick succession so we try to batch these together to
9802    // minimize disk writes, number of dropbox entries, and maximize
9803    // compression, by having more fewer, larger records.
9804    private void logStrictModeViolationToDropBox(
9805            ProcessRecord process,
9806            StrictMode.ViolationInfo info) {
9807        if (info == null) {
9808            return;
9809        }
9810        final boolean isSystemApp = process == null ||
9811                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9812                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9813        final String processName = process == null ? "unknown" : process.processName;
9814        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9815        final DropBoxManager dbox = (DropBoxManager)
9816                mContext.getSystemService(Context.DROPBOX_SERVICE);
9817
9818        // Exit early if the dropbox isn't configured to accept this report type.
9819        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9820
9821        boolean bufferWasEmpty;
9822        boolean needsFlush;
9823        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9824        synchronized (sb) {
9825            bufferWasEmpty = sb.length() == 0;
9826            appendDropBoxProcessHeaders(process, processName, sb);
9827            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9828            sb.append("System-App: ").append(isSystemApp).append("\n");
9829            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9830            if (info.violationNumThisLoop != 0) {
9831                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9832            }
9833            if (info.numAnimationsRunning != 0) {
9834                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9835            }
9836            if (info.broadcastIntentAction != null) {
9837                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9838            }
9839            if (info.durationMillis != -1) {
9840                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9841            }
9842            if (info.numInstances != -1) {
9843                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9844            }
9845            if (info.tags != null) {
9846                for (String tag : info.tags) {
9847                    sb.append("Span-Tag: ").append(tag).append("\n");
9848                }
9849            }
9850            sb.append("\n");
9851            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9852                sb.append(info.crashInfo.stackTrace);
9853            }
9854            sb.append("\n");
9855
9856            // Only buffer up to ~64k.  Various logging bits truncate
9857            // things at 128k.
9858            needsFlush = (sb.length() > 64 * 1024);
9859        }
9860
9861        // Flush immediately if the buffer's grown too large, or this
9862        // is a non-system app.  Non-system apps are isolated with a
9863        // different tag & policy and not batched.
9864        //
9865        // Batching is useful during internal testing with
9866        // StrictMode settings turned up high.  Without batching,
9867        // thousands of separate files could be created on boot.
9868        if (!isSystemApp || needsFlush) {
9869            new Thread("Error dump: " + dropboxTag) {
9870                @Override
9871                public void run() {
9872                    String report;
9873                    synchronized (sb) {
9874                        report = sb.toString();
9875                        sb.delete(0, sb.length());
9876                        sb.trimToSize();
9877                    }
9878                    if (report.length() != 0) {
9879                        dbox.addText(dropboxTag, report);
9880                    }
9881                }
9882            }.start();
9883            return;
9884        }
9885
9886        // System app batching:
9887        if (!bufferWasEmpty) {
9888            // An existing dropbox-writing thread is outstanding, so
9889            // we don't need to start it up.  The existing thread will
9890            // catch the buffer appends we just did.
9891            return;
9892        }
9893
9894        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9895        // (After this point, we shouldn't access AMS internal data structures.)
9896        new Thread("Error dump: " + dropboxTag) {
9897            @Override
9898            public void run() {
9899                // 5 second sleep to let stacks arrive and be batched together
9900                try {
9901                    Thread.sleep(5000);  // 5 seconds
9902                } catch (InterruptedException e) {}
9903
9904                String errorReport;
9905                synchronized (mStrictModeBuffer) {
9906                    errorReport = mStrictModeBuffer.toString();
9907                    if (errorReport.length() == 0) {
9908                        return;
9909                    }
9910                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9911                    mStrictModeBuffer.trimToSize();
9912                }
9913                dbox.addText(dropboxTag, errorReport);
9914            }
9915        }.start();
9916    }
9917
9918    /**
9919     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9920     * @param app object of the crashing app, null for the system server
9921     * @param tag reported by the caller
9922     * @param crashInfo describing the context of the error
9923     * @return true if the process should exit immediately (WTF is fatal)
9924     */
9925    public boolean handleApplicationWtf(IBinder app, String tag,
9926            ApplicationErrorReport.CrashInfo crashInfo) {
9927        ProcessRecord r = findAppProcess(app, "WTF");
9928        final String processName = app == null ? "system_server"
9929                : (r == null ? "unknown" : r.processName);
9930
9931        EventLog.writeEvent(EventLogTags.AM_WTF,
9932                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9933                processName,
9934                r == null ? -1 : r.info.flags,
9935                tag, crashInfo.exceptionMessage);
9936
9937        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9938
9939        if (r != null && r.pid != Process.myPid() &&
9940                Settings.Global.getInt(mContext.getContentResolver(),
9941                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9942            crashApplication(r, crashInfo);
9943            return true;
9944        } else {
9945            return false;
9946        }
9947    }
9948
9949    /**
9950     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9951     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9952     */
9953    private ProcessRecord findAppProcess(IBinder app, String reason) {
9954        if (app == null) {
9955            return null;
9956        }
9957
9958        synchronized (this) {
9959            final int NP = mProcessNames.getMap().size();
9960            for (int ip=0; ip<NP; ip++) {
9961                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9962                final int NA = apps.size();
9963                for (int ia=0; ia<NA; ia++) {
9964                    ProcessRecord p = apps.valueAt(ia);
9965                    if (p.thread != null && p.thread.asBinder() == app) {
9966                        return p;
9967                    }
9968                }
9969            }
9970
9971            Slog.w(TAG, "Can't find mystery application for " + reason
9972                    + " from pid=" + Binder.getCallingPid()
9973                    + " uid=" + Binder.getCallingUid() + ": " + app);
9974            return null;
9975        }
9976    }
9977
9978    /**
9979     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9980     * to append various headers to the dropbox log text.
9981     */
9982    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9983            StringBuilder sb) {
9984        // Watchdog thread ends up invoking this function (with
9985        // a null ProcessRecord) to add the stack file to dropbox.
9986        // Do not acquire a lock on this (am) in such cases, as it
9987        // could cause a potential deadlock, if and when watchdog
9988        // is invoked due to unavailability of lock on am and it
9989        // would prevent watchdog from killing system_server.
9990        if (process == null) {
9991            sb.append("Process: ").append(processName).append("\n");
9992            return;
9993        }
9994        // Note: ProcessRecord 'process' is guarded by the service
9995        // instance.  (notably process.pkgList, which could otherwise change
9996        // concurrently during execution of this method)
9997        synchronized (this) {
9998            sb.append("Process: ").append(processName).append("\n");
9999            int flags = process.info.flags;
10000            IPackageManager pm = AppGlobals.getPackageManager();
10001            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10002            for (int ip=0; ip<process.pkgList.size(); ip++) {
10003                String pkg = process.pkgList.keyAt(ip);
10004                sb.append("Package: ").append(pkg);
10005                try {
10006                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10007                    if (pi != null) {
10008                        sb.append(" v").append(pi.versionCode);
10009                        if (pi.versionName != null) {
10010                            sb.append(" (").append(pi.versionName).append(")");
10011                        }
10012                    }
10013                } catch (RemoteException e) {
10014                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10015                }
10016                sb.append("\n");
10017            }
10018        }
10019    }
10020
10021    private static String processClass(ProcessRecord process) {
10022        if (process == null || process.pid == MY_PID) {
10023            return "system_server";
10024        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10025            return "system_app";
10026        } else {
10027            return "data_app";
10028        }
10029    }
10030
10031    /**
10032     * Write a description of an error (crash, WTF, ANR) to the drop box.
10033     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10034     * @param process which caused the error, null means the system server
10035     * @param activity which triggered the error, null if unknown
10036     * @param parent activity related to the error, null if unknown
10037     * @param subject line related to the error, null if absent
10038     * @param report in long form describing the error, null if absent
10039     * @param logFile to include in the report, null if none
10040     * @param crashInfo giving an application stack trace, null if absent
10041     */
10042    public void addErrorToDropBox(String eventType,
10043            ProcessRecord process, String processName, ActivityRecord activity,
10044            ActivityRecord parent, String subject,
10045            final String report, final File logFile,
10046            final ApplicationErrorReport.CrashInfo crashInfo) {
10047        // NOTE -- this must never acquire the ActivityManagerService lock,
10048        // otherwise the watchdog may be prevented from resetting the system.
10049
10050        final String dropboxTag = processClass(process) + "_" + eventType;
10051        final DropBoxManager dbox = (DropBoxManager)
10052                mContext.getSystemService(Context.DROPBOX_SERVICE);
10053
10054        // Exit early if the dropbox isn't configured to accept this report type.
10055        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10056
10057        final StringBuilder sb = new StringBuilder(1024);
10058        appendDropBoxProcessHeaders(process, processName, sb);
10059        if (activity != null) {
10060            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10061        }
10062        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10063            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10064        }
10065        if (parent != null && parent != activity) {
10066            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10067        }
10068        if (subject != null) {
10069            sb.append("Subject: ").append(subject).append("\n");
10070        }
10071        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10072        if (Debug.isDebuggerConnected()) {
10073            sb.append("Debugger: Connected\n");
10074        }
10075        sb.append("\n");
10076
10077        // Do the rest in a worker thread to avoid blocking the caller on I/O
10078        // (After this point, we shouldn't access AMS internal data structures.)
10079        Thread worker = new Thread("Error dump: " + dropboxTag) {
10080            @Override
10081            public void run() {
10082                if (report != null) {
10083                    sb.append(report);
10084                }
10085                if (logFile != null) {
10086                    try {
10087                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10088                                    "\n\n[[TRUNCATED]]"));
10089                    } catch (IOException e) {
10090                        Slog.e(TAG, "Error reading " + logFile, e);
10091                    }
10092                }
10093                if (crashInfo != null && crashInfo.stackTrace != null) {
10094                    sb.append(crashInfo.stackTrace);
10095                }
10096
10097                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10098                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10099                if (lines > 0) {
10100                    sb.append("\n");
10101
10102                    // Merge several logcat streams, and take the last N lines
10103                    InputStreamReader input = null;
10104                    try {
10105                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10106                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10107                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10108
10109                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10110                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10111                        input = new InputStreamReader(logcat.getInputStream());
10112
10113                        int num;
10114                        char[] buf = new char[8192];
10115                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10116                    } catch (IOException e) {
10117                        Slog.e(TAG, "Error running logcat", e);
10118                    } finally {
10119                        if (input != null) try { input.close(); } catch (IOException e) {}
10120                    }
10121                }
10122
10123                dbox.addText(dropboxTag, sb.toString());
10124            }
10125        };
10126
10127        if (process == null) {
10128            // If process is null, we are being called from some internal code
10129            // and may be about to die -- run this synchronously.
10130            worker.run();
10131        } else {
10132            worker.start();
10133        }
10134    }
10135
10136    /**
10137     * Bring up the "unexpected error" dialog box for a crashing app.
10138     * Deal with edge cases (intercepts from instrumented applications,
10139     * ActivityController, error intent receivers, that sort of thing).
10140     * @param r the application crashing
10141     * @param crashInfo describing the failure
10142     */
10143    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10144        long timeMillis = System.currentTimeMillis();
10145        String shortMsg = crashInfo.exceptionClassName;
10146        String longMsg = crashInfo.exceptionMessage;
10147        String stackTrace = crashInfo.stackTrace;
10148        if (shortMsg != null && longMsg != null) {
10149            longMsg = shortMsg + ": " + longMsg;
10150        } else if (shortMsg != null) {
10151            longMsg = shortMsg;
10152        }
10153
10154        AppErrorResult result = new AppErrorResult();
10155        synchronized (this) {
10156            if (mController != null) {
10157                try {
10158                    String name = r != null ? r.processName : null;
10159                    int pid = r != null ? r.pid : Binder.getCallingPid();
10160                    if (!mController.appCrashed(name, pid,
10161                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10162                        Slog.w(TAG, "Force-killing crashed app " + name
10163                                + " at watcher's request");
10164                        Process.killProcess(pid);
10165                        return;
10166                    }
10167                } catch (RemoteException e) {
10168                    mController = null;
10169                    Watchdog.getInstance().setActivityController(null);
10170                }
10171            }
10172
10173            final long origId = Binder.clearCallingIdentity();
10174
10175            // If this process is running instrumentation, finish it.
10176            if (r != null && r.instrumentationClass != null) {
10177                Slog.w(TAG, "Error in app " + r.processName
10178                      + " running instrumentation " + r.instrumentationClass + ":");
10179                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10180                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10181                Bundle info = new Bundle();
10182                info.putString("shortMsg", shortMsg);
10183                info.putString("longMsg", longMsg);
10184                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10185                Binder.restoreCallingIdentity(origId);
10186                return;
10187            }
10188
10189            // If we can't identify the process or it's already exceeded its crash quota,
10190            // quit right away without showing a crash dialog.
10191            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10192                Binder.restoreCallingIdentity(origId);
10193                return;
10194            }
10195
10196            Message msg = Message.obtain();
10197            msg.what = SHOW_ERROR_MSG;
10198            HashMap data = new HashMap();
10199            data.put("result", result);
10200            data.put("app", r);
10201            msg.obj = data;
10202            mHandler.sendMessage(msg);
10203
10204            Binder.restoreCallingIdentity(origId);
10205        }
10206
10207        int res = result.get();
10208
10209        Intent appErrorIntent = null;
10210        synchronized (this) {
10211            if (r != null && !r.isolated) {
10212                // XXX Can't keep track of crash time for isolated processes,
10213                // since they don't have a persistent identity.
10214                mProcessCrashTimes.put(r.info.processName, r.uid,
10215                        SystemClock.uptimeMillis());
10216            }
10217            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10218                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10219            }
10220        }
10221
10222        if (appErrorIntent != null) {
10223            try {
10224                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10225            } catch (ActivityNotFoundException e) {
10226                Slog.w(TAG, "bug report receiver dissappeared", e);
10227            }
10228        }
10229    }
10230
10231    Intent createAppErrorIntentLocked(ProcessRecord r,
10232            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10233        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10234        if (report == null) {
10235            return null;
10236        }
10237        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10238        result.setComponent(r.errorReportReceiver);
10239        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10240        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10241        return result;
10242    }
10243
10244    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10245            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10246        if (r.errorReportReceiver == null) {
10247            return null;
10248        }
10249
10250        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10251            return null;
10252        }
10253
10254        ApplicationErrorReport report = new ApplicationErrorReport();
10255        report.packageName = r.info.packageName;
10256        report.installerPackageName = r.errorReportReceiver.getPackageName();
10257        report.processName = r.processName;
10258        report.time = timeMillis;
10259        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10260
10261        if (r.crashing || r.forceCrashReport) {
10262            report.type = ApplicationErrorReport.TYPE_CRASH;
10263            report.crashInfo = crashInfo;
10264        } else if (r.notResponding) {
10265            report.type = ApplicationErrorReport.TYPE_ANR;
10266            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10267
10268            report.anrInfo.activity = r.notRespondingReport.tag;
10269            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10270            report.anrInfo.info = r.notRespondingReport.longMsg;
10271        }
10272
10273        return report;
10274    }
10275
10276    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10277        enforceNotIsolatedCaller("getProcessesInErrorState");
10278        // assume our apps are happy - lazy create the list
10279        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10280
10281        final boolean allUsers = ActivityManager.checkUidPermission(
10282                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10283                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10284        int userId = UserHandle.getUserId(Binder.getCallingUid());
10285
10286        synchronized (this) {
10287
10288            // iterate across all processes
10289            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10290                ProcessRecord app = mLruProcesses.get(i);
10291                if (!allUsers && app.userId != userId) {
10292                    continue;
10293                }
10294                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10295                    // This one's in trouble, so we'll generate a report for it
10296                    // crashes are higher priority (in case there's a crash *and* an anr)
10297                    ActivityManager.ProcessErrorStateInfo report = null;
10298                    if (app.crashing) {
10299                        report = app.crashingReport;
10300                    } else if (app.notResponding) {
10301                        report = app.notRespondingReport;
10302                    }
10303
10304                    if (report != null) {
10305                        if (errList == null) {
10306                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10307                        }
10308                        errList.add(report);
10309                    } else {
10310                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10311                                " crashing = " + app.crashing +
10312                                " notResponding = " + app.notResponding);
10313                    }
10314                }
10315            }
10316        }
10317
10318        return errList;
10319    }
10320
10321    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10322        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10323            if (currApp != null) {
10324                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10325            }
10326            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10327        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10328            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10329        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10330            if (currApp != null) {
10331                currApp.lru = 0;
10332            }
10333            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10334        } else if (adj >= ProcessList.SERVICE_ADJ) {
10335            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10336        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10337            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10338        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10339            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10340        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10341            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10342        } else {
10343            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10344        }
10345    }
10346
10347    private void fillInProcMemInfo(ProcessRecord app,
10348            ActivityManager.RunningAppProcessInfo outInfo) {
10349        outInfo.pid = app.pid;
10350        outInfo.uid = app.info.uid;
10351        if (mHeavyWeightProcess == app) {
10352            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10353        }
10354        if (app.persistent) {
10355            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10356        }
10357        if (app.activities.size() > 0) {
10358            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10359        }
10360        outInfo.lastTrimLevel = app.trimMemoryLevel;
10361        int adj = app.curAdj;
10362        outInfo.importance = oomAdjToImportance(adj, outInfo);
10363        outInfo.importanceReasonCode = app.adjTypeCode;
10364    }
10365
10366    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10367        enforceNotIsolatedCaller("getRunningAppProcesses");
10368        // Lazy instantiation of list
10369        List<ActivityManager.RunningAppProcessInfo> runList = null;
10370        final boolean allUsers = ActivityManager.checkUidPermission(
10371                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10372                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10373        int userId = UserHandle.getUserId(Binder.getCallingUid());
10374        synchronized (this) {
10375            // Iterate across all processes
10376            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10377                ProcessRecord app = mLruProcesses.get(i);
10378                if (!allUsers && app.userId != userId) {
10379                    continue;
10380                }
10381                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10382                    // Generate process state info for running application
10383                    ActivityManager.RunningAppProcessInfo currApp =
10384                        new ActivityManager.RunningAppProcessInfo(app.processName,
10385                                app.pid, app.getPackageList());
10386                    fillInProcMemInfo(app, currApp);
10387                    if (app.adjSource instanceof ProcessRecord) {
10388                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10389                        currApp.importanceReasonImportance = oomAdjToImportance(
10390                                app.adjSourceOom, null);
10391                    } else if (app.adjSource instanceof ActivityRecord) {
10392                        ActivityRecord r = (ActivityRecord)app.adjSource;
10393                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10394                    }
10395                    if (app.adjTarget instanceof ComponentName) {
10396                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10397                    }
10398                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10399                    //        + " lru=" + currApp.lru);
10400                    if (runList == null) {
10401                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10402                    }
10403                    runList.add(currApp);
10404                }
10405            }
10406        }
10407        return runList;
10408    }
10409
10410    public List<ApplicationInfo> getRunningExternalApplications() {
10411        enforceNotIsolatedCaller("getRunningExternalApplications");
10412        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10413        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10414        if (runningApps != null && runningApps.size() > 0) {
10415            Set<String> extList = new HashSet<String>();
10416            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10417                if (app.pkgList != null) {
10418                    for (String pkg : app.pkgList) {
10419                        extList.add(pkg);
10420                    }
10421                }
10422            }
10423            IPackageManager pm = AppGlobals.getPackageManager();
10424            for (String pkg : extList) {
10425                try {
10426                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10427                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10428                        retList.add(info);
10429                    }
10430                } catch (RemoteException e) {
10431                }
10432            }
10433        }
10434        return retList;
10435    }
10436
10437    @Override
10438    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10439        enforceNotIsolatedCaller("getMyMemoryState");
10440        synchronized (this) {
10441            ProcessRecord proc;
10442            synchronized (mPidsSelfLocked) {
10443                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10444            }
10445            fillInProcMemInfo(proc, outInfo);
10446        }
10447    }
10448
10449    @Override
10450    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10451        if (checkCallingPermission(android.Manifest.permission.DUMP)
10452                != PackageManager.PERMISSION_GRANTED) {
10453            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10454                    + Binder.getCallingPid()
10455                    + ", uid=" + Binder.getCallingUid()
10456                    + " without permission "
10457                    + android.Manifest.permission.DUMP);
10458            return;
10459        }
10460
10461        boolean dumpAll = false;
10462        boolean dumpClient = false;
10463        String dumpPackage = null;
10464
10465        int opti = 0;
10466        while (opti < args.length) {
10467            String opt = args[opti];
10468            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10469                break;
10470            }
10471            opti++;
10472            if ("-a".equals(opt)) {
10473                dumpAll = true;
10474            } else if ("-c".equals(opt)) {
10475                dumpClient = true;
10476            } else if ("-h".equals(opt)) {
10477                pw.println("Activity manager dump options:");
10478                pw.println("  [-a] [-c] [-h] [cmd] ...");
10479                pw.println("  cmd may be one of:");
10480                pw.println("    a[ctivities]: activity stack state");
10481                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10482                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10483                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10484                pw.println("    o[om]: out of memory management");
10485                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10486                pw.println("    provider [COMP_SPEC]: provider client-side state");
10487                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10488                pw.println("    service [COMP_SPEC]: service client-side state");
10489                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10490                pw.println("    all: dump all activities");
10491                pw.println("    top: dump the top activity");
10492                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10493                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10494                pw.println("    a partial substring in a component name, a");
10495                pw.println("    hex object identifier.");
10496                pw.println("  -a: include all available server state.");
10497                pw.println("  -c: include client state.");
10498                return;
10499            } else {
10500                pw.println("Unknown argument: " + opt + "; use -h for help");
10501            }
10502        }
10503
10504        long origId = Binder.clearCallingIdentity();
10505        boolean more = false;
10506        // Is the caller requesting to dump a particular piece of data?
10507        if (opti < args.length) {
10508            String cmd = args[opti];
10509            opti++;
10510            if ("activities".equals(cmd) || "a".equals(cmd)) {
10511                synchronized (this) {
10512                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10513                }
10514            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10515                String[] newArgs;
10516                String name;
10517                if (opti >= args.length) {
10518                    name = null;
10519                    newArgs = EMPTY_STRING_ARRAY;
10520                } else {
10521                    name = args[opti];
10522                    opti++;
10523                    newArgs = new String[args.length - opti];
10524                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10525                            args.length - opti);
10526                }
10527                synchronized (this) {
10528                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10529                }
10530            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10531                String[] newArgs;
10532                String name;
10533                if (opti >= args.length) {
10534                    name = null;
10535                    newArgs = EMPTY_STRING_ARRAY;
10536                } else {
10537                    name = args[opti];
10538                    opti++;
10539                    newArgs = new String[args.length - opti];
10540                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10541                            args.length - opti);
10542                }
10543                synchronized (this) {
10544                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10545                }
10546            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10547                String[] newArgs;
10548                String name;
10549                if (opti >= args.length) {
10550                    name = null;
10551                    newArgs = EMPTY_STRING_ARRAY;
10552                } else {
10553                    name = args[opti];
10554                    opti++;
10555                    newArgs = new String[args.length - opti];
10556                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10557                            args.length - opti);
10558                }
10559                synchronized (this) {
10560                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10561                }
10562            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10563                synchronized (this) {
10564                    dumpOomLocked(fd, pw, args, opti, true);
10565                }
10566            } else if ("provider".equals(cmd)) {
10567                String[] newArgs;
10568                String name;
10569                if (opti >= args.length) {
10570                    name = null;
10571                    newArgs = EMPTY_STRING_ARRAY;
10572                } else {
10573                    name = args[opti];
10574                    opti++;
10575                    newArgs = new String[args.length - opti];
10576                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10577                }
10578                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10579                    pw.println("No providers match: " + name);
10580                    pw.println("Use -h for help.");
10581                }
10582            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10583                synchronized (this) {
10584                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10585                }
10586            } else if ("service".equals(cmd)) {
10587                String[] newArgs;
10588                String name;
10589                if (opti >= args.length) {
10590                    name = null;
10591                    newArgs = EMPTY_STRING_ARRAY;
10592                } else {
10593                    name = args[opti];
10594                    opti++;
10595                    newArgs = new String[args.length - opti];
10596                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10597                            args.length - opti);
10598                }
10599                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10600                    pw.println("No services match: " + name);
10601                    pw.println("Use -h for help.");
10602                }
10603            } else if ("package".equals(cmd)) {
10604                String[] newArgs;
10605                if (opti >= args.length) {
10606                    pw.println("package: no package name specified");
10607                    pw.println("Use -h for help.");
10608                } else {
10609                    dumpPackage = args[opti];
10610                    opti++;
10611                    newArgs = new String[args.length - opti];
10612                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10613                            args.length - opti);
10614                    args = newArgs;
10615                    opti = 0;
10616                    more = true;
10617                }
10618            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10619                synchronized (this) {
10620                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10621                }
10622            } else {
10623                // Dumping a single activity?
10624                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10625                    pw.println("Bad activity command, or no activities match: " + cmd);
10626                    pw.println("Use -h for help.");
10627                }
10628            }
10629            if (!more) {
10630                Binder.restoreCallingIdentity(origId);
10631                return;
10632            }
10633        }
10634
10635        // No piece of data specified, dump everything.
10636        synchronized (this) {
10637            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10638            pw.println();
10639            if (dumpAll) {
10640                pw.println("-------------------------------------------------------------------------------");
10641            }
10642            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10643            pw.println();
10644            if (dumpAll) {
10645                pw.println("-------------------------------------------------------------------------------");
10646            }
10647            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10648            pw.println();
10649            if (dumpAll) {
10650                pw.println("-------------------------------------------------------------------------------");
10651            }
10652            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10653            pw.println();
10654            if (dumpAll) {
10655                pw.println("-------------------------------------------------------------------------------");
10656            }
10657            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10658            pw.println();
10659            if (dumpAll) {
10660                pw.println("-------------------------------------------------------------------------------");
10661            }
10662            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10663        }
10664        Binder.restoreCallingIdentity(origId);
10665    }
10666
10667    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10668            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10669        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10670
10671        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10672                dumpPackage);
10673        boolean needSep = printedAnything;
10674
10675        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10676                dumpPackage, needSep, "  mFocusedActivity: ");
10677        if (printed) {
10678            printedAnything = true;
10679            needSep = false;
10680        }
10681
10682        if (dumpPackage == null) {
10683            if (needSep) {
10684                pw.println();
10685            }
10686            needSep = true;
10687            printedAnything = true;
10688            mStackSupervisor.dump(pw, "  ");
10689        }
10690
10691        if (mRecentTasks.size() > 0) {
10692            boolean printedHeader = false;
10693
10694            final int N = mRecentTasks.size();
10695            for (int i=0; i<N; i++) {
10696                TaskRecord tr = mRecentTasks.get(i);
10697                if (dumpPackage != null) {
10698                    if (tr.realActivity == null ||
10699                            !dumpPackage.equals(tr.realActivity)) {
10700                        continue;
10701                    }
10702                }
10703                if (!printedHeader) {
10704                    if (needSep) {
10705                        pw.println();
10706                    }
10707                    pw.println("  Recent tasks:");
10708                    printedHeader = true;
10709                    printedAnything = true;
10710                }
10711                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10712                        pw.println(tr);
10713                if (dumpAll) {
10714                    mRecentTasks.get(i).dump(pw, "    ");
10715                }
10716            }
10717        }
10718
10719        if (!printedAnything) {
10720            pw.println("  (nothing)");
10721        }
10722    }
10723
10724    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10725            int opti, boolean dumpAll, String dumpPackage) {
10726        boolean needSep = false;
10727        boolean printedAnything = false;
10728        int numPers = 0;
10729
10730        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10731
10732        if (dumpAll) {
10733            final int NP = mProcessNames.getMap().size();
10734            for (int ip=0; ip<NP; ip++) {
10735                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10736                final int NA = procs.size();
10737                for (int ia=0; ia<NA; ia++) {
10738                    ProcessRecord r = procs.valueAt(ia);
10739                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10740                        continue;
10741                    }
10742                    if (!needSep) {
10743                        pw.println("  All known processes:");
10744                        needSep = true;
10745                        printedAnything = true;
10746                    }
10747                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10748                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10749                        pw.print(" "); pw.println(r);
10750                    r.dump(pw, "    ");
10751                    if (r.persistent) {
10752                        numPers++;
10753                    }
10754                }
10755            }
10756        }
10757
10758        if (mIsolatedProcesses.size() > 0) {
10759            boolean printed = false;
10760            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10761                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10762                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10763                    continue;
10764                }
10765                if (!printed) {
10766                    if (needSep) {
10767                        pw.println();
10768                    }
10769                    pw.println("  Isolated process list (sorted by uid):");
10770                    printedAnything = true;
10771                    printed = true;
10772                    needSep = true;
10773                }
10774                pw.println(String.format("%sIsolated #%2d: %s",
10775                        "    ", i, r.toString()));
10776            }
10777        }
10778
10779        if (mLruProcesses.size() > 0) {
10780            if (needSep) {
10781                pw.println();
10782            }
10783            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10784                    pw.print(" total, non-act at ");
10785                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10786                    pw.print(", non-svc at ");
10787                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10788                    pw.println("):");
10789            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10790            needSep = true;
10791            printedAnything = true;
10792        }
10793
10794        if (dumpAll || dumpPackage != null) {
10795            synchronized (mPidsSelfLocked) {
10796                boolean printed = false;
10797                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10798                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10799                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10800                        continue;
10801                    }
10802                    if (!printed) {
10803                        if (needSep) pw.println();
10804                        needSep = true;
10805                        pw.println("  PID mappings:");
10806                        printed = true;
10807                        printedAnything = true;
10808                    }
10809                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10810                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10811                }
10812            }
10813        }
10814
10815        if (mForegroundProcesses.size() > 0) {
10816            synchronized (mPidsSelfLocked) {
10817                boolean printed = false;
10818                for (int i=0; i<mForegroundProcesses.size(); i++) {
10819                    ProcessRecord r = mPidsSelfLocked.get(
10820                            mForegroundProcesses.valueAt(i).pid);
10821                    if (dumpPackage != null && (r == null
10822                            || !r.pkgList.containsKey(dumpPackage))) {
10823                        continue;
10824                    }
10825                    if (!printed) {
10826                        if (needSep) pw.println();
10827                        needSep = true;
10828                        pw.println("  Foreground Processes:");
10829                        printed = true;
10830                        printedAnything = true;
10831                    }
10832                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10833                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10834                }
10835            }
10836        }
10837
10838        if (mPersistentStartingProcesses.size() > 0) {
10839            if (needSep) pw.println();
10840            needSep = true;
10841            printedAnything = true;
10842            pw.println("  Persisent processes that are starting:");
10843            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10844                    "Starting Norm", "Restarting PERS", dumpPackage);
10845        }
10846
10847        if (mRemovedProcesses.size() > 0) {
10848            if (needSep) pw.println();
10849            needSep = true;
10850            printedAnything = true;
10851            pw.println("  Processes that are being removed:");
10852            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10853                    "Removed Norm", "Removed PERS", dumpPackage);
10854        }
10855
10856        if (mProcessesOnHold.size() > 0) {
10857            if (needSep) pw.println();
10858            needSep = true;
10859            printedAnything = true;
10860            pw.println("  Processes that are on old until the system is ready:");
10861            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10862                    "OnHold Norm", "OnHold PERS", dumpPackage);
10863        }
10864
10865        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10866
10867        if (mProcessCrashTimes.getMap().size() > 0) {
10868            boolean printed = false;
10869            long now = SystemClock.uptimeMillis();
10870            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10871            final int NP = pmap.size();
10872            for (int ip=0; ip<NP; ip++) {
10873                String pname = pmap.keyAt(ip);
10874                SparseArray<Long> uids = pmap.valueAt(ip);
10875                final int N = uids.size();
10876                for (int i=0; i<N; i++) {
10877                    int puid = uids.keyAt(i);
10878                    ProcessRecord r = mProcessNames.get(pname, puid);
10879                    if (dumpPackage != null && (r == null
10880                            || !r.pkgList.containsKey(dumpPackage))) {
10881                        continue;
10882                    }
10883                    if (!printed) {
10884                        if (needSep) pw.println();
10885                        needSep = true;
10886                        pw.println("  Time since processes crashed:");
10887                        printed = true;
10888                        printedAnything = true;
10889                    }
10890                    pw.print("    Process "); pw.print(pname);
10891                            pw.print(" uid "); pw.print(puid);
10892                            pw.print(": last crashed ");
10893                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10894                            pw.println(" ago");
10895                }
10896            }
10897        }
10898
10899        if (mBadProcesses.getMap().size() > 0) {
10900            boolean printed = false;
10901            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10902            final int NP = pmap.size();
10903            for (int ip=0; ip<NP; ip++) {
10904                String pname = pmap.keyAt(ip);
10905                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10906                final int N = uids.size();
10907                for (int i=0; i<N; i++) {
10908                    int puid = uids.keyAt(i);
10909                    ProcessRecord r = mProcessNames.get(pname, puid);
10910                    if (dumpPackage != null && (r == null
10911                            || !r.pkgList.containsKey(dumpPackage))) {
10912                        continue;
10913                    }
10914                    if (!printed) {
10915                        if (needSep) pw.println();
10916                        needSep = true;
10917                        pw.println("  Bad processes:");
10918                        printedAnything = true;
10919                    }
10920                    BadProcessInfo info = uids.valueAt(i);
10921                    pw.print("    Bad process "); pw.print(pname);
10922                            pw.print(" uid "); pw.print(puid);
10923                            pw.print(": crashed at time "); pw.println(info.time);
10924                    if (info.shortMsg != null) {
10925                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10926                    }
10927                    if (info.longMsg != null) {
10928                        pw.print("      Long msg: "); pw.println(info.longMsg);
10929                    }
10930                    if (info.stack != null) {
10931                        pw.println("      Stack:");
10932                        int lastPos = 0;
10933                        for (int pos=0; pos<info.stack.length(); pos++) {
10934                            if (info.stack.charAt(pos) == '\n') {
10935                                pw.print("        ");
10936                                pw.write(info.stack, lastPos, pos-lastPos);
10937                                pw.println();
10938                                lastPos = pos+1;
10939                            }
10940                        }
10941                        if (lastPos < info.stack.length()) {
10942                            pw.print("        ");
10943                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10944                            pw.println();
10945                        }
10946                    }
10947                }
10948            }
10949        }
10950
10951        if (dumpPackage == null) {
10952            pw.println();
10953            needSep = false;
10954            pw.println("  mStartedUsers:");
10955            for (int i=0; i<mStartedUsers.size(); i++) {
10956                UserStartedState uss = mStartedUsers.valueAt(i);
10957                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10958                        pw.print(": "); uss.dump("", pw);
10959            }
10960            pw.print("  mStartedUserArray: [");
10961            for (int i=0; i<mStartedUserArray.length; i++) {
10962                if (i > 0) pw.print(", ");
10963                pw.print(mStartedUserArray[i]);
10964            }
10965            pw.println("]");
10966            pw.print("  mUserLru: [");
10967            for (int i=0; i<mUserLru.size(); i++) {
10968                if (i > 0) pw.print(", ");
10969                pw.print(mUserLru.get(i));
10970            }
10971            pw.println("]");
10972            if (dumpAll) {
10973                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10974            }
10975        }
10976        if (mHomeProcess != null && (dumpPackage == null
10977                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10978            if (needSep) {
10979                pw.println();
10980                needSep = false;
10981            }
10982            pw.println("  mHomeProcess: " + mHomeProcess);
10983        }
10984        if (mPreviousProcess != null && (dumpPackage == null
10985                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10986            if (needSep) {
10987                pw.println();
10988                needSep = false;
10989            }
10990            pw.println("  mPreviousProcess: " + mPreviousProcess);
10991        }
10992        if (dumpAll) {
10993            StringBuilder sb = new StringBuilder(128);
10994            sb.append("  mPreviousProcessVisibleTime: ");
10995            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10996            pw.println(sb);
10997        }
10998        if (mHeavyWeightProcess != null && (dumpPackage == null
10999                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11000            if (needSep) {
11001                pw.println();
11002                needSep = false;
11003            }
11004            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11005        }
11006        if (dumpPackage == null) {
11007            pw.println("  mConfiguration: " + mConfiguration);
11008        }
11009        if (dumpAll) {
11010            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11011            if (mCompatModePackages.getPackages().size() > 0) {
11012                boolean printed = false;
11013                for (Map.Entry<String, Integer> entry
11014                        : mCompatModePackages.getPackages().entrySet()) {
11015                    String pkg = entry.getKey();
11016                    int mode = entry.getValue();
11017                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11018                        continue;
11019                    }
11020                    if (!printed) {
11021                        pw.println("  mScreenCompatPackages:");
11022                        printed = true;
11023                    }
11024                    pw.print("    "); pw.print(pkg); pw.print(": ");
11025                            pw.print(mode); pw.println();
11026                }
11027            }
11028        }
11029        if (dumpPackage == null) {
11030            if (mSleeping || mWentToSleep || mLockScreenShown) {
11031                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11032                        + " mLockScreenShown " + mLockScreenShown);
11033            }
11034            if (mShuttingDown) {
11035                pw.println("  mShuttingDown=" + mShuttingDown);
11036            }
11037        }
11038        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11039                || mOrigWaitForDebugger) {
11040            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11041                    || dumpPackage.equals(mOrigDebugApp)) {
11042                if (needSep) {
11043                    pw.println();
11044                    needSep = false;
11045                }
11046                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11047                        + " mDebugTransient=" + mDebugTransient
11048                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11049            }
11050        }
11051        if (mOpenGlTraceApp != null) {
11052            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11053                if (needSep) {
11054                    pw.println();
11055                    needSep = false;
11056                }
11057                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11058            }
11059        }
11060        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11061                || mProfileFd != null) {
11062            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11063                if (needSep) {
11064                    pw.println();
11065                    needSep = false;
11066                }
11067                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11068                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11069                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11070                        + mAutoStopProfiler);
11071            }
11072        }
11073        if (dumpPackage == null) {
11074            if (mAlwaysFinishActivities || mController != null) {
11075                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11076                        + " mController=" + mController);
11077            }
11078            if (dumpAll) {
11079                pw.println("  Total persistent processes: " + numPers);
11080                pw.println("  mStartRunning=" + mStartRunning
11081                        + " mProcessesReady=" + mProcessesReady
11082                        + " mSystemReady=" + mSystemReady);
11083                pw.println("  mBooting=" + mBooting
11084                        + " mBooted=" + mBooted
11085                        + " mFactoryTest=" + mFactoryTest);
11086                pw.print("  mLastPowerCheckRealtime=");
11087                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11088                        pw.println("");
11089                pw.print("  mLastPowerCheckUptime=");
11090                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11091                        pw.println("");
11092                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11093                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11094                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11095                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11096                        + " (" + mLruProcesses.size() + " total)"
11097                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11098                        + " mNumServiceProcs=" + mNumServiceProcs
11099                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11100                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11101                        + " mLastMemoryLevel" + mLastMemoryLevel
11102                        + " mLastNumProcesses" + mLastNumProcesses);
11103                long now = SystemClock.uptimeMillis();
11104                pw.print("  mLastIdleTime=");
11105                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11106                        pw.print(" mLowRamSinceLastIdle=");
11107                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11108                        pw.println();
11109            }
11110        }
11111
11112        if (!printedAnything) {
11113            pw.println("  (nothing)");
11114        }
11115    }
11116
11117    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11118            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11119        if (mProcessesToGc.size() > 0) {
11120            boolean printed = false;
11121            long now = SystemClock.uptimeMillis();
11122            for (int i=0; i<mProcessesToGc.size(); i++) {
11123                ProcessRecord proc = mProcessesToGc.get(i);
11124                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11125                    continue;
11126                }
11127                if (!printed) {
11128                    if (needSep) pw.println();
11129                    needSep = true;
11130                    pw.println("  Processes that are waiting to GC:");
11131                    printed = true;
11132                }
11133                pw.print("    Process "); pw.println(proc);
11134                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11135                        pw.print(", last gced=");
11136                        pw.print(now-proc.lastRequestedGc);
11137                        pw.print(" ms ago, last lowMem=");
11138                        pw.print(now-proc.lastLowMemory);
11139                        pw.println(" ms ago");
11140
11141            }
11142        }
11143        return needSep;
11144    }
11145
11146    void printOomLevel(PrintWriter pw, String name, int adj) {
11147        pw.print("    ");
11148        if (adj >= 0) {
11149            pw.print(' ');
11150            if (adj < 10) pw.print(' ');
11151        } else {
11152            if (adj > -10) pw.print(' ');
11153        }
11154        pw.print(adj);
11155        pw.print(": ");
11156        pw.print(name);
11157        pw.print(" (");
11158        pw.print(mProcessList.getMemLevel(adj)/1024);
11159        pw.println(" kB)");
11160    }
11161
11162    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11163            int opti, boolean dumpAll) {
11164        boolean needSep = false;
11165
11166        if (mLruProcesses.size() > 0) {
11167            if (needSep) pw.println();
11168            needSep = true;
11169            pw.println("  OOM levels:");
11170            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11171            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11172            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11173            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11174            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11175            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11176            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11177            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11178            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11179            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11180            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11181            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11182            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11183
11184            if (needSep) pw.println();
11185            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11186                    pw.print(" total, non-act at ");
11187                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11188                    pw.print(", non-svc at ");
11189                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11190                    pw.println("):");
11191            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11192            needSep = true;
11193        }
11194
11195        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11196
11197        pw.println();
11198        pw.println("  mHomeProcess: " + mHomeProcess);
11199        pw.println("  mPreviousProcess: " + mPreviousProcess);
11200        if (mHeavyWeightProcess != null) {
11201            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11202        }
11203
11204        return true;
11205    }
11206
11207    /**
11208     * There are three ways to call this:
11209     *  - no provider specified: dump all the providers
11210     *  - a flattened component name that matched an existing provider was specified as the
11211     *    first arg: dump that one provider
11212     *  - the first arg isn't the flattened component name of an existing provider:
11213     *    dump all providers whose component contains the first arg as a substring
11214     */
11215    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11216            int opti, boolean dumpAll) {
11217        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11218    }
11219
11220    static class ItemMatcher {
11221        ArrayList<ComponentName> components;
11222        ArrayList<String> strings;
11223        ArrayList<Integer> objects;
11224        boolean all;
11225
11226        ItemMatcher() {
11227            all = true;
11228        }
11229
11230        void build(String name) {
11231            ComponentName componentName = ComponentName.unflattenFromString(name);
11232            if (componentName != null) {
11233                if (components == null) {
11234                    components = new ArrayList<ComponentName>();
11235                }
11236                components.add(componentName);
11237                all = false;
11238            } else {
11239                int objectId = 0;
11240                // Not a '/' separated full component name; maybe an object ID?
11241                try {
11242                    objectId = Integer.parseInt(name, 16);
11243                    if (objects == null) {
11244                        objects = new ArrayList<Integer>();
11245                    }
11246                    objects.add(objectId);
11247                    all = false;
11248                } catch (RuntimeException e) {
11249                    // Not an integer; just do string match.
11250                    if (strings == null) {
11251                        strings = new ArrayList<String>();
11252                    }
11253                    strings.add(name);
11254                    all = false;
11255                }
11256            }
11257        }
11258
11259        int build(String[] args, int opti) {
11260            for (; opti<args.length; opti++) {
11261                String name = args[opti];
11262                if ("--".equals(name)) {
11263                    return opti+1;
11264                }
11265                build(name);
11266            }
11267            return opti;
11268        }
11269
11270        boolean match(Object object, ComponentName comp) {
11271            if (all) {
11272                return true;
11273            }
11274            if (components != null) {
11275                for (int i=0; i<components.size(); i++) {
11276                    if (components.get(i).equals(comp)) {
11277                        return true;
11278                    }
11279                }
11280            }
11281            if (objects != null) {
11282                for (int i=0; i<objects.size(); i++) {
11283                    if (System.identityHashCode(object) == objects.get(i)) {
11284                        return true;
11285                    }
11286                }
11287            }
11288            if (strings != null) {
11289                String flat = comp.flattenToString();
11290                for (int i=0; i<strings.size(); i++) {
11291                    if (flat.contains(strings.get(i))) {
11292                        return true;
11293                    }
11294                }
11295            }
11296            return false;
11297        }
11298    }
11299
11300    /**
11301     * There are three things that cmd can be:
11302     *  - a flattened component name that matches an existing activity
11303     *  - the cmd arg isn't the flattened component name of an existing activity:
11304     *    dump all activity whose component contains the cmd as a substring
11305     *  - A hex number of the ActivityRecord object instance.
11306     */
11307    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11308            int opti, boolean dumpAll) {
11309        ArrayList<ActivityRecord> activities;
11310
11311        synchronized (this) {
11312            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11313        }
11314
11315        if (activities.size() <= 0) {
11316            return false;
11317        }
11318
11319        String[] newArgs = new String[args.length - opti];
11320        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11321
11322        TaskRecord lastTask = null;
11323        boolean needSep = false;
11324        for (int i=activities.size()-1; i>=0; i--) {
11325            ActivityRecord r = activities.get(i);
11326            if (needSep) {
11327                pw.println();
11328            }
11329            needSep = true;
11330            synchronized (this) {
11331                if (lastTask != r.task) {
11332                    lastTask = r.task;
11333                    pw.print("TASK "); pw.print(lastTask.affinity);
11334                            pw.print(" id="); pw.println(lastTask.taskId);
11335                    if (dumpAll) {
11336                        lastTask.dump(pw, "  ");
11337                    }
11338                }
11339            }
11340            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11341        }
11342        return true;
11343    }
11344
11345    /**
11346     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11347     * there is a thread associated with the activity.
11348     */
11349    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11350            final ActivityRecord r, String[] args, boolean dumpAll) {
11351        String innerPrefix = prefix + "  ";
11352        synchronized (this) {
11353            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11354                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11355                    pw.print(" pid=");
11356                    if (r.app != null) pw.println(r.app.pid);
11357                    else pw.println("(not running)");
11358            if (dumpAll) {
11359                r.dump(pw, innerPrefix);
11360            }
11361        }
11362        if (r.app != null && r.app.thread != null) {
11363            // flush anything that is already in the PrintWriter since the thread is going
11364            // to write to the file descriptor directly
11365            pw.flush();
11366            try {
11367                TransferPipe tp = new TransferPipe();
11368                try {
11369                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11370                            r.appToken, innerPrefix, args);
11371                    tp.go(fd);
11372                } finally {
11373                    tp.kill();
11374                }
11375            } catch (IOException e) {
11376                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11377            } catch (RemoteException e) {
11378                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11379            }
11380        }
11381    }
11382
11383    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11384            int opti, boolean dumpAll, String dumpPackage) {
11385        boolean needSep = false;
11386        boolean onlyHistory = false;
11387        boolean printedAnything = false;
11388
11389        if ("history".equals(dumpPackage)) {
11390            if (opti < args.length && "-s".equals(args[opti])) {
11391                dumpAll = false;
11392            }
11393            onlyHistory = true;
11394            dumpPackage = null;
11395        }
11396
11397        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11398        if (!onlyHistory && dumpAll) {
11399            if (mRegisteredReceivers.size() > 0) {
11400                boolean printed = false;
11401                Iterator it = mRegisteredReceivers.values().iterator();
11402                while (it.hasNext()) {
11403                    ReceiverList r = (ReceiverList)it.next();
11404                    if (dumpPackage != null && (r.app == null ||
11405                            !dumpPackage.equals(r.app.info.packageName))) {
11406                        continue;
11407                    }
11408                    if (!printed) {
11409                        pw.println("  Registered Receivers:");
11410                        needSep = true;
11411                        printed = true;
11412                        printedAnything = true;
11413                    }
11414                    pw.print("  * "); pw.println(r);
11415                    r.dump(pw, "    ");
11416                }
11417            }
11418
11419            if (mReceiverResolver.dump(pw, needSep ?
11420                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11421                    "    ", dumpPackage, false)) {
11422                needSep = true;
11423                printedAnything = true;
11424            }
11425        }
11426
11427        for (BroadcastQueue q : mBroadcastQueues) {
11428            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11429            printedAnything |= needSep;
11430        }
11431
11432        needSep = true;
11433
11434        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11435            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11436                if (needSep) {
11437                    pw.println();
11438                }
11439                needSep = true;
11440                printedAnything = true;
11441                pw.print("  Sticky broadcasts for user ");
11442                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11443                StringBuilder sb = new StringBuilder(128);
11444                for (Map.Entry<String, ArrayList<Intent>> ent
11445                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11446                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11447                    if (dumpAll) {
11448                        pw.println(":");
11449                        ArrayList<Intent> intents = ent.getValue();
11450                        final int N = intents.size();
11451                        for (int i=0; i<N; i++) {
11452                            sb.setLength(0);
11453                            sb.append("    Intent: ");
11454                            intents.get(i).toShortString(sb, false, true, false, false);
11455                            pw.println(sb.toString());
11456                            Bundle bundle = intents.get(i).getExtras();
11457                            if (bundle != null) {
11458                                pw.print("      ");
11459                                pw.println(bundle.toString());
11460                            }
11461                        }
11462                    } else {
11463                        pw.println("");
11464                    }
11465                }
11466            }
11467        }
11468
11469        if (!onlyHistory && dumpAll) {
11470            pw.println();
11471            for (BroadcastQueue queue : mBroadcastQueues) {
11472                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11473                        + queue.mBroadcastsScheduled);
11474            }
11475            pw.println("  mHandler:");
11476            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11477            needSep = true;
11478            printedAnything = true;
11479        }
11480
11481        if (!printedAnything) {
11482            pw.println("  (nothing)");
11483        }
11484    }
11485
11486    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11487            int opti, boolean dumpAll, String dumpPackage) {
11488        boolean needSep;
11489        boolean printedAnything = false;
11490
11491        ItemMatcher matcher = new ItemMatcher();
11492        matcher.build(args, opti);
11493
11494        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11495
11496        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11497        printedAnything |= needSep;
11498
11499        if (mLaunchingProviders.size() > 0) {
11500            boolean printed = false;
11501            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11502                ContentProviderRecord r = mLaunchingProviders.get(i);
11503                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11504                    continue;
11505                }
11506                if (!printed) {
11507                    if (needSep) pw.println();
11508                    needSep = true;
11509                    pw.println("  Launching content providers:");
11510                    printed = true;
11511                    printedAnything = true;
11512                }
11513                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11514                        pw.println(r);
11515            }
11516        }
11517
11518        if (mGrantedUriPermissions.size() > 0) {
11519            boolean printed = false;
11520            int dumpUid = -2;
11521            if (dumpPackage != null) {
11522                try {
11523                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11524                } catch (NameNotFoundException e) {
11525                    dumpUid = -1;
11526                }
11527            }
11528            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11529                int uid = mGrantedUriPermissions.keyAt(i);
11530                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11531                    continue;
11532                }
11533                ArrayMap<Uri, UriPermission> perms
11534                        = mGrantedUriPermissions.valueAt(i);
11535                if (!printed) {
11536                    if (needSep) pw.println();
11537                    needSep = true;
11538                    pw.println("  Granted Uri Permissions:");
11539                    printed = true;
11540                    printedAnything = true;
11541                }
11542                pw.print("  * UID "); pw.print(uid);
11543                        pw.println(" holds:");
11544                for (UriPermission perm : perms.values()) {
11545                    pw.print("    "); pw.println(perm);
11546                    if (dumpAll) {
11547                        perm.dump(pw, "      ");
11548                    }
11549                }
11550            }
11551        }
11552
11553        if (!printedAnything) {
11554            pw.println("  (nothing)");
11555        }
11556    }
11557
11558    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11559            int opti, boolean dumpAll, String dumpPackage) {
11560        boolean printed = false;
11561
11562        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11563
11564        if (mIntentSenderRecords.size() > 0) {
11565            Iterator<WeakReference<PendingIntentRecord>> it
11566                    = mIntentSenderRecords.values().iterator();
11567            while (it.hasNext()) {
11568                WeakReference<PendingIntentRecord> ref = it.next();
11569                PendingIntentRecord rec = ref != null ? ref.get(): null;
11570                if (dumpPackage != null && (rec == null
11571                        || !dumpPackage.equals(rec.key.packageName))) {
11572                    continue;
11573                }
11574                printed = true;
11575                if (rec != null) {
11576                    pw.print("  * "); pw.println(rec);
11577                    if (dumpAll) {
11578                        rec.dump(pw, "    ");
11579                    }
11580                } else {
11581                    pw.print("  * "); pw.println(ref);
11582                }
11583            }
11584        }
11585
11586        if (!printed) {
11587            pw.println("  (nothing)");
11588        }
11589    }
11590
11591    private static final int dumpProcessList(PrintWriter pw,
11592            ActivityManagerService service, List list,
11593            String prefix, String normalLabel, String persistentLabel,
11594            String dumpPackage) {
11595        int numPers = 0;
11596        final int N = list.size()-1;
11597        for (int i=N; i>=0; i--) {
11598            ProcessRecord r = (ProcessRecord)list.get(i);
11599            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11600                continue;
11601            }
11602            pw.println(String.format("%s%s #%2d: %s",
11603                    prefix, (r.persistent ? persistentLabel : normalLabel),
11604                    i, r.toString()));
11605            if (r.persistent) {
11606                numPers++;
11607            }
11608        }
11609        return numPers;
11610    }
11611
11612    private static final boolean dumpProcessOomList(PrintWriter pw,
11613            ActivityManagerService service, List<ProcessRecord> origList,
11614            String prefix, String normalLabel, String persistentLabel,
11615            boolean inclDetails, String dumpPackage) {
11616
11617        ArrayList<Pair<ProcessRecord, Integer>> list
11618                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11619        for (int i=0; i<origList.size(); i++) {
11620            ProcessRecord r = origList.get(i);
11621            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11622                continue;
11623            }
11624            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11625        }
11626
11627        if (list.size() <= 0) {
11628            return false;
11629        }
11630
11631        Comparator<Pair<ProcessRecord, Integer>> comparator
11632                = new Comparator<Pair<ProcessRecord, Integer>>() {
11633            @Override
11634            public int compare(Pair<ProcessRecord, Integer> object1,
11635                    Pair<ProcessRecord, Integer> object2) {
11636                if (object1.first.setAdj != object2.first.setAdj) {
11637                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11638                }
11639                if (object1.second.intValue() != object2.second.intValue()) {
11640                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11641                }
11642                return 0;
11643            }
11644        };
11645
11646        Collections.sort(list, comparator);
11647
11648        final long curRealtime = SystemClock.elapsedRealtime();
11649        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11650        final long curUptime = SystemClock.uptimeMillis();
11651        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11652
11653        for (int i=list.size()-1; i>=0; i--) {
11654            ProcessRecord r = list.get(i).first;
11655            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11656            char schedGroup;
11657            switch (r.setSchedGroup) {
11658                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11659                    schedGroup = 'B';
11660                    break;
11661                case Process.THREAD_GROUP_DEFAULT:
11662                    schedGroup = 'F';
11663                    break;
11664                default:
11665                    schedGroup = '?';
11666                    break;
11667            }
11668            char foreground;
11669            if (r.foregroundActivities) {
11670                foreground = 'A';
11671            } else if (r.foregroundServices) {
11672                foreground = 'S';
11673            } else {
11674                foreground = ' ';
11675            }
11676            String procState = ProcessList.makeProcStateString(r.curProcState);
11677            pw.print(prefix);
11678            pw.print(r.persistent ? persistentLabel : normalLabel);
11679            pw.print(" #");
11680            int num = (origList.size()-1)-list.get(i).second;
11681            if (num < 10) pw.print(' ');
11682            pw.print(num);
11683            pw.print(": ");
11684            pw.print(oomAdj);
11685            pw.print(' ');
11686            pw.print(schedGroup);
11687            pw.print('/');
11688            pw.print(foreground);
11689            pw.print('/');
11690            pw.print(procState);
11691            pw.print(" trm:");
11692            if (r.trimMemoryLevel < 10) pw.print(' ');
11693            pw.print(r.trimMemoryLevel);
11694            pw.print(' ');
11695            pw.print(r.toShortString());
11696            pw.print(" (");
11697            pw.print(r.adjType);
11698            pw.println(')');
11699            if (r.adjSource != null || r.adjTarget != null) {
11700                pw.print(prefix);
11701                pw.print("    ");
11702                if (r.adjTarget instanceof ComponentName) {
11703                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11704                } else if (r.adjTarget != null) {
11705                    pw.print(r.adjTarget.toString());
11706                } else {
11707                    pw.print("{null}");
11708                }
11709                pw.print("<=");
11710                if (r.adjSource instanceof ProcessRecord) {
11711                    pw.print("Proc{");
11712                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11713                    pw.println("}");
11714                } else if (r.adjSource != null) {
11715                    pw.println(r.adjSource.toString());
11716                } else {
11717                    pw.println("{null}");
11718                }
11719            }
11720            if (inclDetails) {
11721                pw.print(prefix);
11722                pw.print("    ");
11723                pw.print("oom: max="); pw.print(r.maxAdj);
11724                pw.print(" curRaw="); pw.print(r.curRawAdj);
11725                pw.print(" setRaw="); pw.print(r.setRawAdj);
11726                pw.print(" cur="); pw.print(r.curAdj);
11727                pw.print(" set="); pw.println(r.setAdj);
11728                pw.print(prefix);
11729                pw.print("    ");
11730                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11731                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11732                pw.print(" lastPss="); pw.print(r.lastPss);
11733                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11734                pw.print(prefix);
11735                pw.print("    ");
11736                pw.print("keeping="); pw.print(r.keeping);
11737                pw.print(" cached="); pw.print(r.cached);
11738                pw.print(" empty="); pw.print(r.empty);
11739                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11740
11741                if (!r.keeping) {
11742                    if (r.lastWakeTime != 0) {
11743                        long wtime;
11744                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11745                        synchronized (stats) {
11746                            wtime = stats.getProcessWakeTime(r.info.uid,
11747                                    r.pid, curRealtime);
11748                        }
11749                        long timeUsed = wtime - r.lastWakeTime;
11750                        pw.print(prefix);
11751                        pw.print("    ");
11752                        pw.print("keep awake over ");
11753                        TimeUtils.formatDuration(realtimeSince, pw);
11754                        pw.print(" used ");
11755                        TimeUtils.formatDuration(timeUsed, pw);
11756                        pw.print(" (");
11757                        pw.print((timeUsed*100)/realtimeSince);
11758                        pw.println("%)");
11759                    }
11760                    if (r.lastCpuTime != 0) {
11761                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11762                        pw.print(prefix);
11763                        pw.print("    ");
11764                        pw.print("run cpu over ");
11765                        TimeUtils.formatDuration(uptimeSince, pw);
11766                        pw.print(" used ");
11767                        TimeUtils.formatDuration(timeUsed, pw);
11768                        pw.print(" (");
11769                        pw.print((timeUsed*100)/uptimeSince);
11770                        pw.println("%)");
11771                    }
11772                }
11773            }
11774        }
11775        return true;
11776    }
11777
11778    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11779        ArrayList<ProcessRecord> procs;
11780        synchronized (this) {
11781            if (args != null && args.length > start
11782                    && args[start].charAt(0) != '-') {
11783                procs = new ArrayList<ProcessRecord>();
11784                int pid = -1;
11785                try {
11786                    pid = Integer.parseInt(args[start]);
11787                } catch (NumberFormatException e) {
11788                }
11789                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11790                    ProcessRecord proc = mLruProcesses.get(i);
11791                    if (proc.pid == pid) {
11792                        procs.add(proc);
11793                    } else if (proc.processName.equals(args[start])) {
11794                        procs.add(proc);
11795                    }
11796                }
11797                if (procs.size() <= 0) {
11798                    return null;
11799                }
11800            } else {
11801                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11802            }
11803        }
11804        return procs;
11805    }
11806
11807    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11808            PrintWriter pw, String[] args) {
11809        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11810        if (procs == null) {
11811            pw.println("No process found for: " + args[0]);
11812            return;
11813        }
11814
11815        long uptime = SystemClock.uptimeMillis();
11816        long realtime = SystemClock.elapsedRealtime();
11817        pw.println("Applications Graphics Acceleration Info:");
11818        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11819
11820        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11821            ProcessRecord r = procs.get(i);
11822            if (r.thread != null) {
11823                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11824                pw.flush();
11825                try {
11826                    TransferPipe tp = new TransferPipe();
11827                    try {
11828                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11829                        tp.go(fd);
11830                    } finally {
11831                        tp.kill();
11832                    }
11833                } catch (IOException e) {
11834                    pw.println("Failure while dumping the app: " + r);
11835                    pw.flush();
11836                } catch (RemoteException e) {
11837                    pw.println("Got a RemoteException while dumping the app " + r);
11838                    pw.flush();
11839                }
11840            }
11841        }
11842    }
11843
11844    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11845        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11846        if (procs == null) {
11847            pw.println("No process found for: " + args[0]);
11848            return;
11849        }
11850
11851        pw.println("Applications Database Info:");
11852
11853        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11854            ProcessRecord r = procs.get(i);
11855            if (r.thread != null) {
11856                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11857                pw.flush();
11858                try {
11859                    TransferPipe tp = new TransferPipe();
11860                    try {
11861                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11862                        tp.go(fd);
11863                    } finally {
11864                        tp.kill();
11865                    }
11866                } catch (IOException e) {
11867                    pw.println("Failure while dumping the app: " + r);
11868                    pw.flush();
11869                } catch (RemoteException e) {
11870                    pw.println("Got a RemoteException while dumping the app " + r);
11871                    pw.flush();
11872                }
11873            }
11874        }
11875    }
11876
11877    final static class MemItem {
11878        final boolean isProc;
11879        final String label;
11880        final String shortLabel;
11881        final long pss;
11882        final int id;
11883        final boolean hasActivities;
11884        ArrayList<MemItem> subitems;
11885
11886        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11887                boolean _hasActivities) {
11888            isProc = true;
11889            label = _label;
11890            shortLabel = _shortLabel;
11891            pss = _pss;
11892            id = _id;
11893            hasActivities = _hasActivities;
11894        }
11895
11896        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11897            isProc = false;
11898            label = _label;
11899            shortLabel = _shortLabel;
11900            pss = _pss;
11901            id = _id;
11902            hasActivities = false;
11903        }
11904    }
11905
11906    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11907            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11908        if (sort && !isCompact) {
11909            Collections.sort(items, new Comparator<MemItem>() {
11910                @Override
11911                public int compare(MemItem lhs, MemItem rhs) {
11912                    if (lhs.pss < rhs.pss) {
11913                        return 1;
11914                    } else if (lhs.pss > rhs.pss) {
11915                        return -1;
11916                    }
11917                    return 0;
11918                }
11919            });
11920        }
11921
11922        for (int i=0; i<items.size(); i++) {
11923            MemItem mi = items.get(i);
11924            if (!isCompact) {
11925                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11926            } else if (mi.isProc) {
11927                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11928                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11929                pw.println(mi.hasActivities ? ",a" : ",e");
11930            } else {
11931                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11932                pw.println(mi.pss);
11933            }
11934            if (mi.subitems != null) {
11935                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11936                        true, isCompact);
11937            }
11938        }
11939    }
11940
11941    // These are in KB.
11942    static final long[] DUMP_MEM_BUCKETS = new long[] {
11943        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11944        120*1024, 160*1024, 200*1024,
11945        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11946        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11947    };
11948
11949    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11950            boolean stackLike) {
11951        int start = label.lastIndexOf('.');
11952        if (start >= 0) start++;
11953        else start = 0;
11954        int end = label.length();
11955        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11956            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11957                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11958                out.append(bucket);
11959                out.append(stackLike ? "MB." : "MB ");
11960                out.append(label, start, end);
11961                return;
11962            }
11963        }
11964        out.append(memKB/1024);
11965        out.append(stackLike ? "MB." : "MB ");
11966        out.append(label, start, end);
11967    }
11968
11969    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11970            ProcessList.NATIVE_ADJ,
11971            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11972            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11973            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11974            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11975            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11976    };
11977    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11978            "Native",
11979            "System", "Persistent", "Foreground",
11980            "Visible", "Perceptible",
11981            "Heavy Weight", "Backup",
11982            "A Services", "Home",
11983            "Previous", "B Services", "Cached"
11984    };
11985    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11986            "native",
11987            "sys", "pers", "fore",
11988            "vis", "percept",
11989            "heavy", "backup",
11990            "servicea", "home",
11991            "prev", "serviceb", "cached"
11992    };
11993
11994    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11995            long realtime, boolean isCheckinRequest, boolean isCompact) {
11996        if (isCheckinRequest || isCompact) {
11997            // short checkin version
11998            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11999        } else {
12000            pw.println("Applications Memory Usage (kB):");
12001            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12002        }
12003    }
12004
12005    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12006            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12007        boolean dumpDetails = false;
12008        boolean dumpFullDetails = false;
12009        boolean dumpDalvik = false;
12010        boolean oomOnly = false;
12011        boolean isCompact = false;
12012        boolean localOnly = false;
12013
12014        int opti = 0;
12015        while (opti < args.length) {
12016            String opt = args[opti];
12017            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12018                break;
12019            }
12020            opti++;
12021            if ("-a".equals(opt)) {
12022                dumpDetails = true;
12023                dumpFullDetails = true;
12024                dumpDalvik = true;
12025            } else if ("-d".equals(opt)) {
12026                dumpDalvik = true;
12027            } else if ("-c".equals(opt)) {
12028                isCompact = true;
12029            } else if ("--oom".equals(opt)) {
12030                oomOnly = true;
12031            } else if ("--local".equals(opt)) {
12032                localOnly = true;
12033            } else if ("-h".equals(opt)) {
12034                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12035                pw.println("  -a: include all available information for each process.");
12036                pw.println("  -d: include dalvik details when dumping process details.");
12037                pw.println("  -c: dump in a compact machine-parseable representation.");
12038                pw.println("  --oom: only show processes organized by oom adj.");
12039                pw.println("  --local: only collect details locally, don't call process.");
12040                pw.println("If [process] is specified it can be the name or ");
12041                pw.println("pid of a specific process to dump.");
12042                return;
12043            } else {
12044                pw.println("Unknown argument: " + opt + "; use -h for help");
12045            }
12046        }
12047
12048        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12049        long uptime = SystemClock.uptimeMillis();
12050        long realtime = SystemClock.elapsedRealtime();
12051        final long[] tmpLong = new long[1];
12052
12053        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12054        if (procs == null) {
12055            // No Java processes.  Maybe they want to print a native process.
12056            if (args != null && args.length > opti
12057                    && args[opti].charAt(0) != '-') {
12058                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12059                        = new ArrayList<ProcessCpuTracker.Stats>();
12060                updateCpuStatsNow();
12061                int findPid = -1;
12062                try {
12063                    findPid = Integer.parseInt(args[opti]);
12064                } catch (NumberFormatException e) {
12065                }
12066                synchronized (mProcessCpuThread) {
12067                    final int N = mProcessCpuTracker.countStats();
12068                    for (int i=0; i<N; i++) {
12069                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12070                        if (st.pid == findPid || (st.baseName != null
12071                                && st.baseName.equals(args[opti]))) {
12072                            nativeProcs.add(st);
12073                        }
12074                    }
12075                }
12076                if (nativeProcs.size() > 0) {
12077                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12078                            isCompact);
12079                    Debug.MemoryInfo mi = null;
12080                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12081                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12082                        final int pid = r.pid;
12083                        if (!isCheckinRequest && dumpDetails) {
12084                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12085                        }
12086                        if (mi == null) {
12087                            mi = new Debug.MemoryInfo();
12088                        }
12089                        if (dumpDetails || (!brief && !oomOnly)) {
12090                            Debug.getMemoryInfo(pid, mi);
12091                        } else {
12092                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12093                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12094                        }
12095                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12096                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12097                        if (isCheckinRequest) {
12098                            pw.println();
12099                        }
12100                    }
12101                    return;
12102                }
12103            }
12104            pw.println("No process found for: " + args[opti]);
12105            return;
12106        }
12107
12108        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12109            dumpDetails = true;
12110        }
12111
12112        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12113
12114        String[] innerArgs = new String[args.length-opti];
12115        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12116
12117        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12118        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12119        long nativePss=0, dalvikPss=0, otherPss=0;
12120        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12121
12122        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12123        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12124                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12125
12126        long totalPss = 0;
12127        long cachedPss = 0;
12128
12129        Debug.MemoryInfo mi = null;
12130        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12131            final ProcessRecord r = procs.get(i);
12132            final IApplicationThread thread;
12133            final int pid;
12134            final int oomAdj;
12135            final boolean hasActivities;
12136            synchronized (this) {
12137                thread = r.thread;
12138                pid = r.pid;
12139                oomAdj = r.getSetAdjWithServices();
12140                hasActivities = r.activities.size() > 0;
12141            }
12142            if (thread != null) {
12143                if (!isCheckinRequest && dumpDetails) {
12144                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12145                }
12146                if (mi == null) {
12147                    mi = new Debug.MemoryInfo();
12148                }
12149                if (dumpDetails || (!brief && !oomOnly)) {
12150                    Debug.getMemoryInfo(pid, mi);
12151                } else {
12152                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12153                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12154                }
12155                if (dumpDetails) {
12156                    if (localOnly) {
12157                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12158                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12159                        if (isCheckinRequest) {
12160                            pw.println();
12161                        }
12162                    } else {
12163                        try {
12164                            pw.flush();
12165                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12166                                    dumpDalvik, innerArgs);
12167                        } catch (RemoteException e) {
12168                            if (!isCheckinRequest) {
12169                                pw.println("Got RemoteException!");
12170                                pw.flush();
12171                            }
12172                        }
12173                    }
12174                }
12175
12176                final long myTotalPss = mi.getTotalPss();
12177                final long myTotalUss = mi.getTotalUss();
12178
12179                synchronized (this) {
12180                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12181                        // Record this for posterity if the process has been stable.
12182                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12183                    }
12184                }
12185
12186                if (!isCheckinRequest && mi != null) {
12187                    totalPss += myTotalPss;
12188                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12189                            (hasActivities ? " / activities)" : ")"),
12190                            r.processName, myTotalPss, pid, hasActivities);
12191                    procMems.add(pssItem);
12192                    procMemsMap.put(pid, pssItem);
12193
12194                    nativePss += mi.nativePss;
12195                    dalvikPss += mi.dalvikPss;
12196                    otherPss += mi.otherPss;
12197                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12198                        long mem = mi.getOtherPss(j);
12199                        miscPss[j] += mem;
12200                        otherPss -= mem;
12201                    }
12202
12203                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12204                        cachedPss += myTotalPss;
12205                    }
12206
12207                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12208                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12209                                || oomIndex == (oomPss.length-1)) {
12210                            oomPss[oomIndex] += myTotalPss;
12211                            if (oomProcs[oomIndex] == null) {
12212                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12213                            }
12214                            oomProcs[oomIndex].add(pssItem);
12215                            break;
12216                        }
12217                    }
12218                }
12219            }
12220        }
12221
12222        if (!isCheckinRequest && procs.size() > 1) {
12223            // If we are showing aggregations, also look for native processes to
12224            // include so that our aggregations are more accurate.
12225            updateCpuStatsNow();
12226            synchronized (mProcessCpuThread) {
12227                final int N = mProcessCpuTracker.countStats();
12228                for (int i=0; i<N; i++) {
12229                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12230                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12231                        if (mi == null) {
12232                            mi = new Debug.MemoryInfo();
12233                        }
12234                        if (!brief && !oomOnly) {
12235                            Debug.getMemoryInfo(st.pid, mi);
12236                        } else {
12237                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12238                            mi.nativePrivateDirty = (int)tmpLong[0];
12239                        }
12240
12241                        final long myTotalPss = mi.getTotalPss();
12242                        totalPss += myTotalPss;
12243
12244                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12245                                st.name, myTotalPss, st.pid, false);
12246                        procMems.add(pssItem);
12247
12248                        nativePss += mi.nativePss;
12249                        dalvikPss += mi.dalvikPss;
12250                        otherPss += mi.otherPss;
12251                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12252                            long mem = mi.getOtherPss(j);
12253                            miscPss[j] += mem;
12254                            otherPss -= mem;
12255                        }
12256                        oomPss[0] += myTotalPss;
12257                        if (oomProcs[0] == null) {
12258                            oomProcs[0] = new ArrayList<MemItem>();
12259                        }
12260                        oomProcs[0].add(pssItem);
12261                    }
12262                }
12263            }
12264
12265            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12266
12267            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12268            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12269            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12270            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12271                String label = Debug.MemoryInfo.getOtherLabel(j);
12272                catMems.add(new MemItem(label, label, miscPss[j], j));
12273            }
12274
12275            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12276            for (int j=0; j<oomPss.length; j++) {
12277                if (oomPss[j] != 0) {
12278                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12279                            : DUMP_MEM_OOM_LABEL[j];
12280                    MemItem item = new MemItem(label, label, oomPss[j],
12281                            DUMP_MEM_OOM_ADJ[j]);
12282                    item.subitems = oomProcs[j];
12283                    oomMems.add(item);
12284                }
12285            }
12286
12287            if (!brief && !oomOnly && !isCompact) {
12288                pw.println();
12289                pw.println("Total PSS by process:");
12290                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12291                pw.println();
12292            }
12293            if (!isCompact) {
12294                pw.println("Total PSS by OOM adjustment:");
12295            }
12296            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12297            if (!brief && !oomOnly) {
12298                PrintWriter out = categoryPw != null ? categoryPw : pw;
12299                if (!isCompact) {
12300                    out.println();
12301                    out.println("Total PSS by category:");
12302                }
12303                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12304            }
12305            if (!isCompact) {
12306                pw.println();
12307            }
12308            MemInfoReader memInfo = new MemInfoReader();
12309            memInfo.readMemInfo();
12310            if (!brief) {
12311                if (!isCompact) {
12312                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12313                    pw.print(" kB (status ");
12314                    switch (mLastMemoryLevel) {
12315                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12316                            pw.println("normal)");
12317                            break;
12318                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12319                            pw.println("moderate)");
12320                            break;
12321                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12322                            pw.println("low)");
12323                            break;
12324                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12325                            pw.println("critical)");
12326                            break;
12327                        default:
12328                            pw.print(mLastMemoryLevel);
12329                            pw.println(")");
12330                            break;
12331                    }
12332                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12333                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12334                            pw.print(cachedPss); pw.print(" cached pss + ");
12335                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12336                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12337                } else {
12338                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12339                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12340                            + memInfo.getFreeSizeKb()); pw.print(",");
12341                    pw.println(totalPss - cachedPss);
12342                }
12343            }
12344            if (!isCompact) {
12345                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12346                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12347                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12348                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12349                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12350                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12351                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12352                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12353                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12354                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12355                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12356            }
12357            if (!brief) {
12358                if (memInfo.getZramTotalSizeKb() != 0) {
12359                    if (!isCompact) {
12360                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12361                                pw.print(" kB physical used for ");
12362                                pw.print(memInfo.getSwapTotalSizeKb()
12363                                        - memInfo.getSwapFreeSizeKb());
12364                                pw.print(" kB in swap (");
12365                                pw.print(memInfo.getSwapTotalSizeKb());
12366                                pw.println(" kB total swap)");
12367                    } else {
12368                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12369                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12370                                pw.println(memInfo.getSwapFreeSizeKb());
12371                    }
12372                }
12373                final int[] SINGLE_LONG_FORMAT = new int[] {
12374                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12375                };
12376                long[] longOut = new long[1];
12377                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12378                        SINGLE_LONG_FORMAT, null, longOut, null);
12379                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12380                longOut[0] = 0;
12381                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12382                        SINGLE_LONG_FORMAT, null, longOut, null);
12383                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12384                longOut[0] = 0;
12385                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12386                        SINGLE_LONG_FORMAT, null, longOut, null);
12387                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12388                longOut[0] = 0;
12389                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12390                        SINGLE_LONG_FORMAT, null, longOut, null);
12391                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12392                if (!isCompact) {
12393                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12394                        pw.print("      KSM: "); pw.print(sharing);
12395                                pw.print(" kB saved from shared ");
12396                                pw.print(shared); pw.println(" kB");
12397                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12398                                pw.print(voltile); pw.println(" kB volatile");
12399                    }
12400                    pw.print("   Tuning: ");
12401                    pw.print(ActivityManager.staticGetMemoryClass());
12402                    pw.print(" (large ");
12403                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12404                    pw.print("), oom ");
12405                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12406                    pw.print(" kB");
12407                    pw.print(", restore limit ");
12408                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12409                    pw.print(" kB");
12410                    if (ActivityManager.isLowRamDeviceStatic()) {
12411                        pw.print(" (low-ram)");
12412                    }
12413                    if (ActivityManager.isHighEndGfx()) {
12414                        pw.print(" (high-end-gfx)");
12415                    }
12416                    pw.println();
12417                } else {
12418                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12419                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12420                    pw.println(voltile);
12421                    pw.print("tuning,");
12422                    pw.print(ActivityManager.staticGetMemoryClass());
12423                    pw.print(',');
12424                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12425                    pw.print(',');
12426                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12427                    if (ActivityManager.isLowRamDeviceStatic()) {
12428                        pw.print(",low-ram");
12429                    }
12430                    if (ActivityManager.isHighEndGfx()) {
12431                        pw.print(",high-end-gfx");
12432                    }
12433                    pw.println();
12434                }
12435            }
12436        }
12437    }
12438
12439    /**
12440     * Searches array of arguments for the specified string
12441     * @param args array of argument strings
12442     * @param value value to search for
12443     * @return true if the value is contained in the array
12444     */
12445    private static boolean scanArgs(String[] args, String value) {
12446        if (args != null) {
12447            for (String arg : args) {
12448                if (value.equals(arg)) {
12449                    return true;
12450                }
12451            }
12452        }
12453        return false;
12454    }
12455
12456    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12457            ContentProviderRecord cpr, boolean always) {
12458        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12459
12460        if (!inLaunching || always) {
12461            synchronized (cpr) {
12462                cpr.launchingApp = null;
12463                cpr.notifyAll();
12464            }
12465            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12466            String names[] = cpr.info.authority.split(";");
12467            for (int j = 0; j < names.length; j++) {
12468                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12469            }
12470        }
12471
12472        for (int i=0; i<cpr.connections.size(); i++) {
12473            ContentProviderConnection conn = cpr.connections.get(i);
12474            if (conn.waiting) {
12475                // If this connection is waiting for the provider, then we don't
12476                // need to mess with its process unless we are always removing
12477                // or for some reason the provider is not currently launching.
12478                if (inLaunching && !always) {
12479                    continue;
12480                }
12481            }
12482            ProcessRecord capp = conn.client;
12483            conn.dead = true;
12484            if (conn.stableCount > 0) {
12485                if (!capp.persistent && capp.thread != null
12486                        && capp.pid != 0
12487                        && capp.pid != MY_PID) {
12488                    killUnneededProcessLocked(capp, "depends on provider "
12489                            + cpr.name.flattenToShortString()
12490                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12491                }
12492            } else if (capp.thread != null && conn.provider.provider != null) {
12493                try {
12494                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12495                } catch (RemoteException e) {
12496                }
12497                // In the protocol here, we don't expect the client to correctly
12498                // clean up this connection, we'll just remove it.
12499                cpr.connections.remove(i);
12500                conn.client.conProviders.remove(conn);
12501            }
12502        }
12503
12504        if (inLaunching && always) {
12505            mLaunchingProviders.remove(cpr);
12506        }
12507        return inLaunching;
12508    }
12509
12510    /**
12511     * Main code for cleaning up a process when it has gone away.  This is
12512     * called both as a result of the process dying, or directly when stopping
12513     * a process when running in single process mode.
12514     */
12515    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12516            boolean restarting, boolean allowRestart, int index) {
12517        if (index >= 0) {
12518            removeLruProcessLocked(app);
12519            ProcessList.remove(app.pid);
12520        }
12521
12522        mProcessesToGc.remove(app);
12523        mPendingPssProcesses.remove(app);
12524
12525        // Dismiss any open dialogs.
12526        if (app.crashDialog != null && !app.forceCrashReport) {
12527            app.crashDialog.dismiss();
12528            app.crashDialog = null;
12529        }
12530        if (app.anrDialog != null) {
12531            app.anrDialog.dismiss();
12532            app.anrDialog = null;
12533        }
12534        if (app.waitDialog != null) {
12535            app.waitDialog.dismiss();
12536            app.waitDialog = null;
12537        }
12538
12539        app.crashing = false;
12540        app.notResponding = false;
12541
12542        app.resetPackageList(mProcessStats);
12543        app.unlinkDeathRecipient();
12544        app.makeInactive(mProcessStats);
12545        app.forcingToForeground = null;
12546        updateProcessForegroundLocked(app, false, false);
12547        app.foregroundActivities = false;
12548        app.hasShownUi = false;
12549        app.hasAboveClient = false;
12550
12551        mServices.killServicesLocked(app, allowRestart);
12552
12553        boolean restart = false;
12554
12555        // Remove published content providers.
12556        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12557            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12558            final boolean always = app.bad || !allowRestart;
12559            if (removeDyingProviderLocked(app, cpr, always) || always) {
12560                // We left the provider in the launching list, need to
12561                // restart it.
12562                restart = true;
12563            }
12564
12565            cpr.provider = null;
12566            cpr.proc = null;
12567        }
12568        app.pubProviders.clear();
12569
12570        // Take care of any launching providers waiting for this process.
12571        if (checkAppInLaunchingProvidersLocked(app, false)) {
12572            restart = true;
12573        }
12574
12575        // Unregister from connected content providers.
12576        if (!app.conProviders.isEmpty()) {
12577            for (int i=0; i<app.conProviders.size(); i++) {
12578                ContentProviderConnection conn = app.conProviders.get(i);
12579                conn.provider.connections.remove(conn);
12580            }
12581            app.conProviders.clear();
12582        }
12583
12584        // At this point there may be remaining entries in mLaunchingProviders
12585        // where we were the only one waiting, so they are no longer of use.
12586        // Look for these and clean up if found.
12587        // XXX Commented out for now.  Trying to figure out a way to reproduce
12588        // the actual situation to identify what is actually going on.
12589        if (false) {
12590            for (int i=0; i<mLaunchingProviders.size(); i++) {
12591                ContentProviderRecord cpr = (ContentProviderRecord)
12592                        mLaunchingProviders.get(i);
12593                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12594                    synchronized (cpr) {
12595                        cpr.launchingApp = null;
12596                        cpr.notifyAll();
12597                    }
12598                }
12599            }
12600        }
12601
12602        skipCurrentReceiverLocked(app);
12603
12604        // Unregister any receivers.
12605        for (int i=app.receivers.size()-1; i>=0; i--) {
12606            removeReceiverLocked(app.receivers.valueAt(i));
12607        }
12608        app.receivers.clear();
12609
12610        // If the app is undergoing backup, tell the backup manager about it
12611        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12612            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12613                    + mBackupTarget.appInfo + " died during backup");
12614            try {
12615                IBackupManager bm = IBackupManager.Stub.asInterface(
12616                        ServiceManager.getService(Context.BACKUP_SERVICE));
12617                bm.agentDisconnected(app.info.packageName);
12618            } catch (RemoteException e) {
12619                // can't happen; backup manager is local
12620            }
12621        }
12622
12623        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12624            ProcessChangeItem item = mPendingProcessChanges.get(i);
12625            if (item.pid == app.pid) {
12626                mPendingProcessChanges.remove(i);
12627                mAvailProcessChanges.add(item);
12628            }
12629        }
12630        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12631
12632        // If the caller is restarting this app, then leave it in its
12633        // current lists and let the caller take care of it.
12634        if (restarting) {
12635            return;
12636        }
12637
12638        if (!app.persistent || app.isolated) {
12639            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12640                    "Removing non-persistent process during cleanup: " + app);
12641            mProcessNames.remove(app.processName, app.uid);
12642            mIsolatedProcesses.remove(app.uid);
12643            if (mHeavyWeightProcess == app) {
12644                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12645                        mHeavyWeightProcess.userId, 0));
12646                mHeavyWeightProcess = null;
12647            }
12648        } else if (!app.removed) {
12649            // This app is persistent, so we need to keep its record around.
12650            // If it is not already on the pending app list, add it there
12651            // and start a new process for it.
12652            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12653                mPersistentStartingProcesses.add(app);
12654                restart = true;
12655            }
12656        }
12657        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12658                "Clean-up removing on hold: " + app);
12659        mProcessesOnHold.remove(app);
12660
12661        if (app == mHomeProcess) {
12662            mHomeProcess = null;
12663        }
12664        if (app == mPreviousProcess) {
12665            mPreviousProcess = null;
12666        }
12667
12668        if (restart && !app.isolated) {
12669            // We have components that still need to be running in the
12670            // process, so re-launch it.
12671            mProcessNames.put(app.processName, app.uid, app);
12672            startProcessLocked(app, "restart", app.processName);
12673        } else if (app.pid > 0 && app.pid != MY_PID) {
12674            // Goodbye!
12675            boolean removed;
12676            synchronized (mPidsSelfLocked) {
12677                mPidsSelfLocked.remove(app.pid);
12678                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12679            }
12680            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12681                    app.processName, app.info.uid);
12682            if (app.isolated) {
12683                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12684            }
12685            app.setPid(0);
12686        }
12687    }
12688
12689    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12690        // Look through the content providers we are waiting to have launched,
12691        // and if any run in this process then either schedule a restart of
12692        // the process or kill the client waiting for it if this process has
12693        // gone bad.
12694        int NL = mLaunchingProviders.size();
12695        boolean restart = false;
12696        for (int i=0; i<NL; i++) {
12697            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12698            if (cpr.launchingApp == app) {
12699                if (!alwaysBad && !app.bad) {
12700                    restart = true;
12701                } else {
12702                    removeDyingProviderLocked(app, cpr, true);
12703                    // cpr should have been removed from mLaunchingProviders
12704                    NL = mLaunchingProviders.size();
12705                    i--;
12706                }
12707            }
12708        }
12709        return restart;
12710    }
12711
12712    // =========================================================
12713    // SERVICES
12714    // =========================================================
12715
12716    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12717            int flags) {
12718        enforceNotIsolatedCaller("getServices");
12719        synchronized (this) {
12720            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12721        }
12722    }
12723
12724    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12725        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12726        synchronized (this) {
12727            return mServices.getRunningServiceControlPanelLocked(name);
12728        }
12729    }
12730
12731    public ComponentName startService(IApplicationThread caller, Intent service,
12732            String resolvedType, int userId) {
12733        enforceNotIsolatedCaller("startService");
12734        // Refuse possible leaked file descriptors
12735        if (service != null && service.hasFileDescriptors() == true) {
12736            throw new IllegalArgumentException("File descriptors passed in Intent");
12737        }
12738
12739        if (DEBUG_SERVICE)
12740            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12741        synchronized(this) {
12742            final int callingPid = Binder.getCallingPid();
12743            final int callingUid = Binder.getCallingUid();
12744            final long origId = Binder.clearCallingIdentity();
12745            ComponentName res = mServices.startServiceLocked(caller, service,
12746                    resolvedType, callingPid, callingUid, userId);
12747            Binder.restoreCallingIdentity(origId);
12748            return res;
12749        }
12750    }
12751
12752    ComponentName startServiceInPackage(int uid,
12753            Intent service, String resolvedType, int userId) {
12754        synchronized(this) {
12755            if (DEBUG_SERVICE)
12756                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12757            final long origId = Binder.clearCallingIdentity();
12758            ComponentName res = mServices.startServiceLocked(null, service,
12759                    resolvedType, -1, uid, userId);
12760            Binder.restoreCallingIdentity(origId);
12761            return res;
12762        }
12763    }
12764
12765    public int stopService(IApplicationThread caller, Intent service,
12766            String resolvedType, int userId) {
12767        enforceNotIsolatedCaller("stopService");
12768        // Refuse possible leaked file descriptors
12769        if (service != null && service.hasFileDescriptors() == true) {
12770            throw new IllegalArgumentException("File descriptors passed in Intent");
12771        }
12772
12773        synchronized(this) {
12774            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12775        }
12776    }
12777
12778    public IBinder peekService(Intent service, String resolvedType) {
12779        enforceNotIsolatedCaller("peekService");
12780        // Refuse possible leaked file descriptors
12781        if (service != null && service.hasFileDescriptors() == true) {
12782            throw new IllegalArgumentException("File descriptors passed in Intent");
12783        }
12784        synchronized(this) {
12785            return mServices.peekServiceLocked(service, resolvedType);
12786        }
12787    }
12788
12789    public boolean stopServiceToken(ComponentName className, IBinder token,
12790            int startId) {
12791        synchronized(this) {
12792            return mServices.stopServiceTokenLocked(className, token, startId);
12793        }
12794    }
12795
12796    public void setServiceForeground(ComponentName className, IBinder token,
12797            int id, Notification notification, boolean removeNotification) {
12798        synchronized(this) {
12799            mServices.setServiceForegroundLocked(className, token, id, notification,
12800                    removeNotification);
12801        }
12802    }
12803
12804    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12805            boolean requireFull, String name, String callerPackage) {
12806        final int callingUserId = UserHandle.getUserId(callingUid);
12807        if (callingUserId != userId) {
12808            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12809                if ((requireFull || checkComponentPermission(
12810                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12811                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12812                        && checkComponentPermission(
12813                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12814                                callingPid, callingUid, -1, true)
12815                                != PackageManager.PERMISSION_GRANTED) {
12816                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12817                        // In this case, they would like to just execute as their
12818                        // owner user instead of failing.
12819                        userId = callingUserId;
12820                    } else {
12821                        StringBuilder builder = new StringBuilder(128);
12822                        builder.append("Permission Denial: ");
12823                        builder.append(name);
12824                        if (callerPackage != null) {
12825                            builder.append(" from ");
12826                            builder.append(callerPackage);
12827                        }
12828                        builder.append(" asks to run as user ");
12829                        builder.append(userId);
12830                        builder.append(" but is calling from user ");
12831                        builder.append(UserHandle.getUserId(callingUid));
12832                        builder.append("; this requires ");
12833                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12834                        if (!requireFull) {
12835                            builder.append(" or ");
12836                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12837                        }
12838                        String msg = builder.toString();
12839                        Slog.w(TAG, msg);
12840                        throw new SecurityException(msg);
12841                    }
12842                }
12843            }
12844            if (userId == UserHandle.USER_CURRENT
12845                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12846                // Note that we may be accessing this outside of a lock...
12847                // shouldn't be a big deal, if this is being called outside
12848                // of a locked context there is intrinsically a race with
12849                // the value the caller will receive and someone else changing it.
12850                userId = mCurrentUserId;
12851            }
12852            if (!allowAll && userId < 0) {
12853                throw new IllegalArgumentException(
12854                        "Call does not support special user #" + userId);
12855            }
12856        }
12857        return userId;
12858    }
12859
12860    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12861            String className, int flags) {
12862        boolean result = false;
12863        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12864            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12865                if (ActivityManager.checkUidPermission(
12866                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12867                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12868                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12869                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12870                            + " requests FLAG_SINGLE_USER, but app does not hold "
12871                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12872                    Slog.w(TAG, msg);
12873                    throw new SecurityException(msg);
12874                }
12875                result = true;
12876            }
12877        } else if (componentProcessName == aInfo.packageName) {
12878            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12879        } else if ("system".equals(componentProcessName)) {
12880            result = true;
12881        }
12882        if (DEBUG_MU) {
12883            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12884                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12885        }
12886        return result;
12887    }
12888
12889    public int bindService(IApplicationThread caller, IBinder token,
12890            Intent service, String resolvedType,
12891            IServiceConnection connection, int flags, int userId) {
12892        enforceNotIsolatedCaller("bindService");
12893        // Refuse possible leaked file descriptors
12894        if (service != null && service.hasFileDescriptors() == true) {
12895            throw new IllegalArgumentException("File descriptors passed in Intent");
12896        }
12897
12898        synchronized(this) {
12899            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12900                    connection, flags, userId);
12901        }
12902    }
12903
12904    public boolean unbindService(IServiceConnection connection) {
12905        synchronized (this) {
12906            return mServices.unbindServiceLocked(connection);
12907        }
12908    }
12909
12910    public void publishService(IBinder token, Intent intent, IBinder service) {
12911        // Refuse possible leaked file descriptors
12912        if (intent != null && intent.hasFileDescriptors() == true) {
12913            throw new IllegalArgumentException("File descriptors passed in Intent");
12914        }
12915
12916        synchronized(this) {
12917            if (!(token instanceof ServiceRecord)) {
12918                throw new IllegalArgumentException("Invalid service token");
12919            }
12920            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12921        }
12922    }
12923
12924    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12925        // Refuse possible leaked file descriptors
12926        if (intent != null && intent.hasFileDescriptors() == true) {
12927            throw new IllegalArgumentException("File descriptors passed in Intent");
12928        }
12929
12930        synchronized(this) {
12931            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12932        }
12933    }
12934
12935    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12936        synchronized(this) {
12937            if (!(token instanceof ServiceRecord)) {
12938                throw new IllegalArgumentException("Invalid service token");
12939            }
12940            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12941        }
12942    }
12943
12944    // =========================================================
12945    // BACKUP AND RESTORE
12946    // =========================================================
12947
12948    // Cause the target app to be launched if necessary and its backup agent
12949    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12950    // activity manager to announce its creation.
12951    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12952        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12953        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12954
12955        synchronized(this) {
12956            // !!! TODO: currently no check here that we're already bound
12957            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12958            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12959            synchronized (stats) {
12960                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12961            }
12962
12963            // Backup agent is now in use, its package can't be stopped.
12964            try {
12965                AppGlobals.getPackageManager().setPackageStoppedState(
12966                        app.packageName, false, UserHandle.getUserId(app.uid));
12967            } catch (RemoteException e) {
12968            } catch (IllegalArgumentException e) {
12969                Slog.w(TAG, "Failed trying to unstop package "
12970                        + app.packageName + ": " + e);
12971            }
12972
12973            BackupRecord r = new BackupRecord(ss, app, backupMode);
12974            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12975                    ? new ComponentName(app.packageName, app.backupAgentName)
12976                    : new ComponentName("android", "FullBackupAgent");
12977            // startProcessLocked() returns existing proc's record if it's already running
12978            ProcessRecord proc = startProcessLocked(app.processName, app,
12979                    false, 0, "backup", hostingName, false, false, false);
12980            if (proc == null) {
12981                Slog.e(TAG, "Unable to start backup agent process " + r);
12982                return false;
12983            }
12984
12985            r.app = proc;
12986            mBackupTarget = r;
12987            mBackupAppName = app.packageName;
12988
12989            // Try not to kill the process during backup
12990            updateOomAdjLocked(proc);
12991
12992            // If the process is already attached, schedule the creation of the backup agent now.
12993            // If it is not yet live, this will be done when it attaches to the framework.
12994            if (proc.thread != null) {
12995                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12996                try {
12997                    proc.thread.scheduleCreateBackupAgent(app,
12998                            compatibilityInfoForPackageLocked(app), backupMode);
12999                } catch (RemoteException e) {
13000                    // Will time out on the backup manager side
13001                }
13002            } else {
13003                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13004            }
13005            // Invariants: at this point, the target app process exists and the application
13006            // is either already running or in the process of coming up.  mBackupTarget and
13007            // mBackupAppName describe the app, so that when it binds back to the AM we
13008            // know that it's scheduled for a backup-agent operation.
13009        }
13010
13011        return true;
13012    }
13013
13014    @Override
13015    public void clearPendingBackup() {
13016        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13017        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13018
13019        synchronized (this) {
13020            mBackupTarget = null;
13021            mBackupAppName = null;
13022        }
13023    }
13024
13025    // A backup agent has just come up
13026    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13027        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13028                + " = " + agent);
13029
13030        synchronized(this) {
13031            if (!agentPackageName.equals(mBackupAppName)) {
13032                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13033                return;
13034            }
13035        }
13036
13037        long oldIdent = Binder.clearCallingIdentity();
13038        try {
13039            IBackupManager bm = IBackupManager.Stub.asInterface(
13040                    ServiceManager.getService(Context.BACKUP_SERVICE));
13041            bm.agentConnected(agentPackageName, agent);
13042        } catch (RemoteException e) {
13043            // can't happen; the backup manager service is local
13044        } catch (Exception e) {
13045            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13046            e.printStackTrace();
13047        } finally {
13048            Binder.restoreCallingIdentity(oldIdent);
13049        }
13050    }
13051
13052    // done with this agent
13053    public void unbindBackupAgent(ApplicationInfo appInfo) {
13054        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13055        if (appInfo == null) {
13056            Slog.w(TAG, "unbind backup agent for null app");
13057            return;
13058        }
13059
13060        synchronized(this) {
13061            try {
13062                if (mBackupAppName == null) {
13063                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13064                    return;
13065                }
13066
13067                if (!mBackupAppName.equals(appInfo.packageName)) {
13068                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13069                    return;
13070                }
13071
13072                // Not backing this app up any more; reset its OOM adjustment
13073                final ProcessRecord proc = mBackupTarget.app;
13074                updateOomAdjLocked(proc);
13075
13076                // If the app crashed during backup, 'thread' will be null here
13077                if (proc.thread != null) {
13078                    try {
13079                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13080                                compatibilityInfoForPackageLocked(appInfo));
13081                    } catch (Exception e) {
13082                        Slog.e(TAG, "Exception when unbinding backup agent:");
13083                        e.printStackTrace();
13084                    }
13085                }
13086            } finally {
13087                mBackupTarget = null;
13088                mBackupAppName = null;
13089            }
13090        }
13091    }
13092    // =========================================================
13093    // BROADCASTS
13094    // =========================================================
13095
13096    private final List getStickiesLocked(String action, IntentFilter filter,
13097            List cur, int userId) {
13098        final ContentResolver resolver = mContext.getContentResolver();
13099        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13100        if (stickies == null) {
13101            return cur;
13102        }
13103        final ArrayList<Intent> list = stickies.get(action);
13104        if (list == null) {
13105            return cur;
13106        }
13107        int N = list.size();
13108        for (int i=0; i<N; i++) {
13109            Intent intent = list.get(i);
13110            if (filter.match(resolver, intent, true, TAG) >= 0) {
13111                if (cur == null) {
13112                    cur = new ArrayList<Intent>();
13113                }
13114                cur.add(intent);
13115            }
13116        }
13117        return cur;
13118    }
13119
13120    boolean isPendingBroadcastProcessLocked(int pid) {
13121        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13122                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13123    }
13124
13125    void skipPendingBroadcastLocked(int pid) {
13126            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13127            for (BroadcastQueue queue : mBroadcastQueues) {
13128                queue.skipPendingBroadcastLocked(pid);
13129            }
13130    }
13131
13132    // The app just attached; send any pending broadcasts that it should receive
13133    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13134        boolean didSomething = false;
13135        for (BroadcastQueue queue : mBroadcastQueues) {
13136            didSomething |= queue.sendPendingBroadcastsLocked(app);
13137        }
13138        return didSomething;
13139    }
13140
13141    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13142            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13143        enforceNotIsolatedCaller("registerReceiver");
13144        int callingUid;
13145        int callingPid;
13146        synchronized(this) {
13147            ProcessRecord callerApp = null;
13148            if (caller != null) {
13149                callerApp = getRecordForAppLocked(caller);
13150                if (callerApp == null) {
13151                    throw new SecurityException(
13152                            "Unable to find app for caller " + caller
13153                            + " (pid=" + Binder.getCallingPid()
13154                            + ") when registering receiver " + receiver);
13155                }
13156                if (callerApp.info.uid != Process.SYSTEM_UID &&
13157                        !callerApp.pkgList.containsKey(callerPackage) &&
13158                        !"android".equals(callerPackage)) {
13159                    throw new SecurityException("Given caller package " + callerPackage
13160                            + " is not running in process " + callerApp);
13161                }
13162                callingUid = callerApp.info.uid;
13163                callingPid = callerApp.pid;
13164            } else {
13165                callerPackage = null;
13166                callingUid = Binder.getCallingUid();
13167                callingPid = Binder.getCallingPid();
13168            }
13169
13170            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13171                    true, true, "registerReceiver", callerPackage);
13172
13173            List allSticky = null;
13174
13175            // Look for any matching sticky broadcasts...
13176            Iterator actions = filter.actionsIterator();
13177            if (actions != null) {
13178                while (actions.hasNext()) {
13179                    String action = (String)actions.next();
13180                    allSticky = getStickiesLocked(action, filter, allSticky,
13181                            UserHandle.USER_ALL);
13182                    allSticky = getStickiesLocked(action, filter, allSticky,
13183                            UserHandle.getUserId(callingUid));
13184                }
13185            } else {
13186                allSticky = getStickiesLocked(null, filter, allSticky,
13187                        UserHandle.USER_ALL);
13188                allSticky = getStickiesLocked(null, filter, allSticky,
13189                        UserHandle.getUserId(callingUid));
13190            }
13191
13192            // The first sticky in the list is returned directly back to
13193            // the client.
13194            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13195
13196            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13197                    + ": " + sticky);
13198
13199            if (receiver == null) {
13200                return sticky;
13201            }
13202
13203            ReceiverList rl
13204                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13205            if (rl == null) {
13206                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13207                        userId, receiver);
13208                if (rl.app != null) {
13209                    rl.app.receivers.add(rl);
13210                } else {
13211                    try {
13212                        receiver.asBinder().linkToDeath(rl, 0);
13213                    } catch (RemoteException e) {
13214                        return sticky;
13215                    }
13216                    rl.linkedToDeath = true;
13217                }
13218                mRegisteredReceivers.put(receiver.asBinder(), rl);
13219            } else if (rl.uid != callingUid) {
13220                throw new IllegalArgumentException(
13221                        "Receiver requested to register for uid " + callingUid
13222                        + " was previously registered for uid " + rl.uid);
13223            } else if (rl.pid != callingPid) {
13224                throw new IllegalArgumentException(
13225                        "Receiver requested to register for pid " + callingPid
13226                        + " was previously registered for pid " + rl.pid);
13227            } else if (rl.userId != userId) {
13228                throw new IllegalArgumentException(
13229                        "Receiver requested to register for user " + userId
13230                        + " was previously registered for user " + rl.userId);
13231            }
13232            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13233                    permission, callingUid, userId);
13234            rl.add(bf);
13235            if (!bf.debugCheck()) {
13236                Slog.w(TAG, "==> For Dynamic broadast");
13237            }
13238            mReceiverResolver.addFilter(bf);
13239
13240            // Enqueue broadcasts for all existing stickies that match
13241            // this filter.
13242            if (allSticky != null) {
13243                ArrayList receivers = new ArrayList();
13244                receivers.add(bf);
13245
13246                int N = allSticky.size();
13247                for (int i=0; i<N; i++) {
13248                    Intent intent = (Intent)allSticky.get(i);
13249                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13250                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13251                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13252                            null, null, false, true, true, -1);
13253                    queue.enqueueParallelBroadcastLocked(r);
13254                    queue.scheduleBroadcastsLocked();
13255                }
13256            }
13257
13258            return sticky;
13259        }
13260    }
13261
13262    public void unregisterReceiver(IIntentReceiver receiver) {
13263        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13264
13265        final long origId = Binder.clearCallingIdentity();
13266        try {
13267            boolean doTrim = false;
13268
13269            synchronized(this) {
13270                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13271                if (rl != null) {
13272                    if (rl.curBroadcast != null) {
13273                        BroadcastRecord r = rl.curBroadcast;
13274                        final boolean doNext = finishReceiverLocked(
13275                                receiver.asBinder(), r.resultCode, r.resultData,
13276                                r.resultExtras, r.resultAbort);
13277                        if (doNext) {
13278                            doTrim = true;
13279                            r.queue.processNextBroadcast(false);
13280                        }
13281                    }
13282
13283                    if (rl.app != null) {
13284                        rl.app.receivers.remove(rl);
13285                    }
13286                    removeReceiverLocked(rl);
13287                    if (rl.linkedToDeath) {
13288                        rl.linkedToDeath = false;
13289                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13290                    }
13291                }
13292            }
13293
13294            // If we actually concluded any broadcasts, we might now be able
13295            // to trim the recipients' apps from our working set
13296            if (doTrim) {
13297                trimApplications();
13298                return;
13299            }
13300
13301        } finally {
13302            Binder.restoreCallingIdentity(origId);
13303        }
13304    }
13305
13306    void removeReceiverLocked(ReceiverList rl) {
13307        mRegisteredReceivers.remove(rl.receiver.asBinder());
13308        int N = rl.size();
13309        for (int i=0; i<N; i++) {
13310            mReceiverResolver.removeFilter(rl.get(i));
13311        }
13312    }
13313
13314    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13315        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13316            ProcessRecord r = mLruProcesses.get(i);
13317            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13318                try {
13319                    r.thread.dispatchPackageBroadcast(cmd, packages);
13320                } catch (RemoteException ex) {
13321                }
13322            }
13323        }
13324    }
13325
13326    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13327            int[] users) {
13328        List<ResolveInfo> receivers = null;
13329        try {
13330            HashSet<ComponentName> singleUserReceivers = null;
13331            boolean scannedFirstReceivers = false;
13332            for (int user : users) {
13333                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13334                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13335                if (user != 0 && newReceivers != null) {
13336                    // If this is not the primary user, we need to check for
13337                    // any receivers that should be filtered out.
13338                    for (int i=0; i<newReceivers.size(); i++) {
13339                        ResolveInfo ri = newReceivers.get(i);
13340                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13341                            newReceivers.remove(i);
13342                            i--;
13343                        }
13344                    }
13345                }
13346                if (newReceivers != null && newReceivers.size() == 0) {
13347                    newReceivers = null;
13348                }
13349                if (receivers == null) {
13350                    receivers = newReceivers;
13351                } else if (newReceivers != null) {
13352                    // We need to concatenate the additional receivers
13353                    // found with what we have do far.  This would be easy,
13354                    // but we also need to de-dup any receivers that are
13355                    // singleUser.
13356                    if (!scannedFirstReceivers) {
13357                        // Collect any single user receivers we had already retrieved.
13358                        scannedFirstReceivers = true;
13359                        for (int i=0; i<receivers.size(); i++) {
13360                            ResolveInfo ri = receivers.get(i);
13361                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13362                                ComponentName cn = new ComponentName(
13363                                        ri.activityInfo.packageName, ri.activityInfo.name);
13364                                if (singleUserReceivers == null) {
13365                                    singleUserReceivers = new HashSet<ComponentName>();
13366                                }
13367                                singleUserReceivers.add(cn);
13368                            }
13369                        }
13370                    }
13371                    // Add the new results to the existing results, tracking
13372                    // and de-dupping single user receivers.
13373                    for (int i=0; i<newReceivers.size(); i++) {
13374                        ResolveInfo ri = newReceivers.get(i);
13375                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13376                            ComponentName cn = new ComponentName(
13377                                    ri.activityInfo.packageName, ri.activityInfo.name);
13378                            if (singleUserReceivers == null) {
13379                                singleUserReceivers = new HashSet<ComponentName>();
13380                            }
13381                            if (!singleUserReceivers.contains(cn)) {
13382                                singleUserReceivers.add(cn);
13383                                receivers.add(ri);
13384                            }
13385                        } else {
13386                            receivers.add(ri);
13387                        }
13388                    }
13389                }
13390            }
13391        } catch (RemoteException ex) {
13392            // pm is in same process, this will never happen.
13393        }
13394        return receivers;
13395    }
13396
13397    private final int broadcastIntentLocked(ProcessRecord callerApp,
13398            String callerPackage, Intent intent, String resolvedType,
13399            IIntentReceiver resultTo, int resultCode, String resultData,
13400            Bundle map, String requiredPermission, int appOp,
13401            boolean ordered, boolean sticky, int callingPid, int callingUid,
13402            int userId) {
13403        intent = new Intent(intent);
13404
13405        // By default broadcasts do not go to stopped apps.
13406        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13407
13408        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13409            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13410            + " ordered=" + ordered + " userid=" + userId);
13411        if ((resultTo != null) && !ordered) {
13412            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13413        }
13414
13415        userId = handleIncomingUser(callingPid, callingUid, userId,
13416                true, false, "broadcast", callerPackage);
13417
13418        // Make sure that the user who is receiving this broadcast is started.
13419        // If not, we will just skip it.
13420        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13421            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13422                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13423                Slog.w(TAG, "Skipping broadcast of " + intent
13424                        + ": user " + userId + " is stopped");
13425                return ActivityManager.BROADCAST_SUCCESS;
13426            }
13427        }
13428
13429        /*
13430         * Prevent non-system code (defined here to be non-persistent
13431         * processes) from sending protected broadcasts.
13432         */
13433        int callingAppId = UserHandle.getAppId(callingUid);
13434        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13435            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13436            callingUid == 0) {
13437            // Always okay.
13438        } else if (callerApp == null || !callerApp.persistent) {
13439            try {
13440                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13441                        intent.getAction())) {
13442                    String msg = "Permission Denial: not allowed to send broadcast "
13443                            + intent.getAction() + " from pid="
13444                            + callingPid + ", uid=" + callingUid;
13445                    Slog.w(TAG, msg);
13446                    throw new SecurityException(msg);
13447                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13448                    // Special case for compatibility: we don't want apps to send this,
13449                    // but historically it has not been protected and apps may be using it
13450                    // to poke their own app widget.  So, instead of making it protected,
13451                    // just limit it to the caller.
13452                    if (callerApp == null) {
13453                        String msg = "Permission Denial: not allowed to send broadcast "
13454                                + intent.getAction() + " from unknown caller.";
13455                        Slog.w(TAG, msg);
13456                        throw new SecurityException(msg);
13457                    } else if (intent.getComponent() != null) {
13458                        // They are good enough to send to an explicit component...  verify
13459                        // it is being sent to the calling app.
13460                        if (!intent.getComponent().getPackageName().equals(
13461                                callerApp.info.packageName)) {
13462                            String msg = "Permission Denial: not allowed to send broadcast "
13463                                    + intent.getAction() + " to "
13464                                    + intent.getComponent().getPackageName() + " from "
13465                                    + callerApp.info.packageName;
13466                            Slog.w(TAG, msg);
13467                            throw new SecurityException(msg);
13468                        }
13469                    } else {
13470                        // Limit broadcast to their own package.
13471                        intent.setPackage(callerApp.info.packageName);
13472                    }
13473                }
13474            } catch (RemoteException e) {
13475                Slog.w(TAG, "Remote exception", e);
13476                return ActivityManager.BROADCAST_SUCCESS;
13477            }
13478        }
13479
13480        // Handle special intents: if this broadcast is from the package
13481        // manager about a package being removed, we need to remove all of
13482        // its activities from the history stack.
13483        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13484                intent.getAction());
13485        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13486                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13487                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13488                || uidRemoved) {
13489            if (checkComponentPermission(
13490                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13491                    callingPid, callingUid, -1, true)
13492                    == PackageManager.PERMISSION_GRANTED) {
13493                if (uidRemoved) {
13494                    final Bundle intentExtras = intent.getExtras();
13495                    final int uid = intentExtras != null
13496                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13497                    if (uid >= 0) {
13498                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13499                        synchronized (bs) {
13500                            bs.removeUidStatsLocked(uid);
13501                        }
13502                        mAppOpsService.uidRemoved(uid);
13503                    }
13504                } else {
13505                    // If resources are unavailable just force stop all
13506                    // those packages and flush the attribute cache as well.
13507                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13508                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13509                        if (list != null && (list.length > 0)) {
13510                            for (String pkg : list) {
13511                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13512                                        "storage unmount");
13513                            }
13514                            sendPackageBroadcastLocked(
13515                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13516                        }
13517                    } else {
13518                        Uri data = intent.getData();
13519                        String ssp;
13520                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13521                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13522                                    intent.getAction());
13523                            boolean fullUninstall = removed &&
13524                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13525                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13526                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13527                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13528                                        false, fullUninstall, userId,
13529                                        removed ? "pkg removed" : "pkg changed");
13530                            }
13531                            if (removed) {
13532                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13533                                        new String[] {ssp}, userId);
13534                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13535                                    mAppOpsService.packageRemoved(
13536                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13537
13538                                    // Remove all permissions granted from/to this package
13539                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13540                                }
13541                            }
13542                        }
13543                    }
13544                }
13545            } else {
13546                String msg = "Permission Denial: " + intent.getAction()
13547                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13548                        + ", uid=" + callingUid + ")"
13549                        + " requires "
13550                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13551                Slog.w(TAG, msg);
13552                throw new SecurityException(msg);
13553            }
13554
13555        // Special case for adding a package: by default turn on compatibility
13556        // mode.
13557        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13558            Uri data = intent.getData();
13559            String ssp;
13560            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13561                mCompatModePackages.handlePackageAddedLocked(ssp,
13562                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13563            }
13564        }
13565
13566        /*
13567         * If this is the time zone changed action, queue up a message that will reset the timezone
13568         * of all currently running processes. This message will get queued up before the broadcast
13569         * happens.
13570         */
13571        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13572            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13573        }
13574
13575        /*
13576         * If the user set the time, let all running processes know.
13577         */
13578        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13579            final int is24Hour = intent.getBooleanExtra(
13580                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13581            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13582        }
13583
13584        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13585            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13586        }
13587
13588        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13589            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13590            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13591        }
13592
13593        // Add to the sticky list if requested.
13594        if (sticky) {
13595            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13596                    callingPid, callingUid)
13597                    != PackageManager.PERMISSION_GRANTED) {
13598                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13599                        + callingPid + ", uid=" + callingUid
13600                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13601                Slog.w(TAG, msg);
13602                throw new SecurityException(msg);
13603            }
13604            if (requiredPermission != null) {
13605                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13606                        + " and enforce permission " + requiredPermission);
13607                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13608            }
13609            if (intent.getComponent() != null) {
13610                throw new SecurityException(
13611                        "Sticky broadcasts can't target a specific component");
13612            }
13613            // We use userId directly here, since the "all" target is maintained
13614            // as a separate set of sticky broadcasts.
13615            if (userId != UserHandle.USER_ALL) {
13616                // But first, if this is not a broadcast to all users, then
13617                // make sure it doesn't conflict with an existing broadcast to
13618                // all users.
13619                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13620                        UserHandle.USER_ALL);
13621                if (stickies != null) {
13622                    ArrayList<Intent> list = stickies.get(intent.getAction());
13623                    if (list != null) {
13624                        int N = list.size();
13625                        int i;
13626                        for (i=0; i<N; i++) {
13627                            if (intent.filterEquals(list.get(i))) {
13628                                throw new IllegalArgumentException(
13629                                        "Sticky broadcast " + intent + " for user "
13630                                        + userId + " conflicts with existing global broadcast");
13631                            }
13632                        }
13633                    }
13634                }
13635            }
13636            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13637            if (stickies == null) {
13638                stickies = new ArrayMap<String, ArrayList<Intent>>();
13639                mStickyBroadcasts.put(userId, stickies);
13640            }
13641            ArrayList<Intent> list = stickies.get(intent.getAction());
13642            if (list == null) {
13643                list = new ArrayList<Intent>();
13644                stickies.put(intent.getAction(), list);
13645            }
13646            int N = list.size();
13647            int i;
13648            for (i=0; i<N; i++) {
13649                if (intent.filterEquals(list.get(i))) {
13650                    // This sticky already exists, replace it.
13651                    list.set(i, new Intent(intent));
13652                    break;
13653                }
13654            }
13655            if (i >= N) {
13656                list.add(new Intent(intent));
13657            }
13658        }
13659
13660        int[] users;
13661        if (userId == UserHandle.USER_ALL) {
13662            // Caller wants broadcast to go to all started users.
13663            users = mStartedUserArray;
13664        } else {
13665            // Caller wants broadcast to go to one specific user.
13666            users = new int[] {userId};
13667        }
13668
13669        // Figure out who all will receive this broadcast.
13670        List receivers = null;
13671        List<BroadcastFilter> registeredReceivers = null;
13672        // Need to resolve the intent to interested receivers...
13673        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13674                 == 0) {
13675            receivers = collectReceiverComponents(intent, resolvedType, users);
13676        }
13677        if (intent.getComponent() == null) {
13678            registeredReceivers = mReceiverResolver.queryIntent(intent,
13679                    resolvedType, false, userId);
13680        }
13681
13682        final boolean replacePending =
13683                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13684
13685        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13686                + " replacePending=" + replacePending);
13687
13688        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13689        if (!ordered && NR > 0) {
13690            // If we are not serializing this broadcast, then send the
13691            // registered receivers separately so they don't wait for the
13692            // components to be launched.
13693            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13694            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13695                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13696                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13697                    ordered, sticky, false, userId);
13698            if (DEBUG_BROADCAST) Slog.v(
13699                    TAG, "Enqueueing parallel broadcast " + r);
13700            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13701            if (!replaced) {
13702                queue.enqueueParallelBroadcastLocked(r);
13703                queue.scheduleBroadcastsLocked();
13704            }
13705            registeredReceivers = null;
13706            NR = 0;
13707        }
13708
13709        // Merge into one list.
13710        int ir = 0;
13711        if (receivers != null) {
13712            // A special case for PACKAGE_ADDED: do not allow the package
13713            // being added to see this broadcast.  This prevents them from
13714            // using this as a back door to get run as soon as they are
13715            // installed.  Maybe in the future we want to have a special install
13716            // broadcast or such for apps, but we'd like to deliberately make
13717            // this decision.
13718            String skipPackages[] = null;
13719            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13720                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13721                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13722                Uri data = intent.getData();
13723                if (data != null) {
13724                    String pkgName = data.getSchemeSpecificPart();
13725                    if (pkgName != null) {
13726                        skipPackages = new String[] { pkgName };
13727                    }
13728                }
13729            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13730                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13731            }
13732            if (skipPackages != null && (skipPackages.length > 0)) {
13733                for (String skipPackage : skipPackages) {
13734                    if (skipPackage != null) {
13735                        int NT = receivers.size();
13736                        for (int it=0; it<NT; it++) {
13737                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13738                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13739                                receivers.remove(it);
13740                                it--;
13741                                NT--;
13742                            }
13743                        }
13744                    }
13745                }
13746            }
13747
13748            int NT = receivers != null ? receivers.size() : 0;
13749            int it = 0;
13750            ResolveInfo curt = null;
13751            BroadcastFilter curr = null;
13752            while (it < NT && ir < NR) {
13753                if (curt == null) {
13754                    curt = (ResolveInfo)receivers.get(it);
13755                }
13756                if (curr == null) {
13757                    curr = registeredReceivers.get(ir);
13758                }
13759                if (curr.getPriority() >= curt.priority) {
13760                    // Insert this broadcast record into the final list.
13761                    receivers.add(it, curr);
13762                    ir++;
13763                    curr = null;
13764                    it++;
13765                    NT++;
13766                } else {
13767                    // Skip to the next ResolveInfo in the final list.
13768                    it++;
13769                    curt = null;
13770                }
13771            }
13772        }
13773        while (ir < NR) {
13774            if (receivers == null) {
13775                receivers = new ArrayList();
13776            }
13777            receivers.add(registeredReceivers.get(ir));
13778            ir++;
13779        }
13780
13781        if ((receivers != null && receivers.size() > 0)
13782                || resultTo != null) {
13783            BroadcastQueue queue = broadcastQueueForIntent(intent);
13784            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13785                    callerPackage, callingPid, callingUid, resolvedType,
13786                    requiredPermission, appOp, receivers, resultTo, resultCode,
13787                    resultData, map, ordered, sticky, false, userId);
13788            if (DEBUG_BROADCAST) Slog.v(
13789                    TAG, "Enqueueing ordered broadcast " + r
13790                    + ": prev had " + queue.mOrderedBroadcasts.size());
13791            if (DEBUG_BROADCAST) {
13792                int seq = r.intent.getIntExtra("seq", -1);
13793                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13794            }
13795            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13796            if (!replaced) {
13797                queue.enqueueOrderedBroadcastLocked(r);
13798                queue.scheduleBroadcastsLocked();
13799            }
13800        }
13801
13802        return ActivityManager.BROADCAST_SUCCESS;
13803    }
13804
13805    final Intent verifyBroadcastLocked(Intent intent) {
13806        // Refuse possible leaked file descriptors
13807        if (intent != null && intent.hasFileDescriptors() == true) {
13808            throw new IllegalArgumentException("File descriptors passed in Intent");
13809        }
13810
13811        int flags = intent.getFlags();
13812
13813        if (!mProcessesReady) {
13814            // if the caller really truly claims to know what they're doing, go
13815            // ahead and allow the broadcast without launching any receivers
13816            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13817                intent = new Intent(intent);
13818                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13819            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13820                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13821                        + " before boot completion");
13822                throw new IllegalStateException("Cannot broadcast before boot completed");
13823            }
13824        }
13825
13826        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13827            throw new IllegalArgumentException(
13828                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13829        }
13830
13831        return intent;
13832    }
13833
13834    public final int broadcastIntent(IApplicationThread caller,
13835            Intent intent, String resolvedType, IIntentReceiver resultTo,
13836            int resultCode, String resultData, Bundle map,
13837            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13838        enforceNotIsolatedCaller("broadcastIntent");
13839        synchronized(this) {
13840            intent = verifyBroadcastLocked(intent);
13841
13842            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13843            final int callingPid = Binder.getCallingPid();
13844            final int callingUid = Binder.getCallingUid();
13845            final long origId = Binder.clearCallingIdentity();
13846            int res = broadcastIntentLocked(callerApp,
13847                    callerApp != null ? callerApp.info.packageName : null,
13848                    intent, resolvedType, resultTo,
13849                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13850                    callingPid, callingUid, userId);
13851            Binder.restoreCallingIdentity(origId);
13852            return res;
13853        }
13854    }
13855
13856    int broadcastIntentInPackage(String packageName, int uid,
13857            Intent intent, String resolvedType, IIntentReceiver resultTo,
13858            int resultCode, String resultData, Bundle map,
13859            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13860        synchronized(this) {
13861            intent = verifyBroadcastLocked(intent);
13862
13863            final long origId = Binder.clearCallingIdentity();
13864            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13865                    resultTo, resultCode, resultData, map, requiredPermission,
13866                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13867            Binder.restoreCallingIdentity(origId);
13868            return res;
13869        }
13870    }
13871
13872    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13873        // Refuse possible leaked file descriptors
13874        if (intent != null && intent.hasFileDescriptors() == true) {
13875            throw new IllegalArgumentException("File descriptors passed in Intent");
13876        }
13877
13878        userId = handleIncomingUser(Binder.getCallingPid(),
13879                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13880
13881        synchronized(this) {
13882            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13883                    != PackageManager.PERMISSION_GRANTED) {
13884                String msg = "Permission Denial: unbroadcastIntent() from pid="
13885                        + Binder.getCallingPid()
13886                        + ", uid=" + Binder.getCallingUid()
13887                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13888                Slog.w(TAG, msg);
13889                throw new SecurityException(msg);
13890            }
13891            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13892            if (stickies != null) {
13893                ArrayList<Intent> list = stickies.get(intent.getAction());
13894                if (list != null) {
13895                    int N = list.size();
13896                    int i;
13897                    for (i=0; i<N; i++) {
13898                        if (intent.filterEquals(list.get(i))) {
13899                            list.remove(i);
13900                            break;
13901                        }
13902                    }
13903                    if (list.size() <= 0) {
13904                        stickies.remove(intent.getAction());
13905                    }
13906                }
13907                if (stickies.size() <= 0) {
13908                    mStickyBroadcasts.remove(userId);
13909                }
13910            }
13911        }
13912    }
13913
13914    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13915            String resultData, Bundle resultExtras, boolean resultAbort) {
13916        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13917        if (r == null) {
13918            Slog.w(TAG, "finishReceiver called but not found on queue");
13919            return false;
13920        }
13921
13922        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13923    }
13924
13925    void backgroundServicesFinishedLocked(int userId) {
13926        for (BroadcastQueue queue : mBroadcastQueues) {
13927            queue.backgroundServicesFinishedLocked(userId);
13928        }
13929    }
13930
13931    public void finishReceiver(IBinder who, int resultCode, String resultData,
13932            Bundle resultExtras, boolean resultAbort) {
13933        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13934
13935        // Refuse possible leaked file descriptors
13936        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13937            throw new IllegalArgumentException("File descriptors passed in Bundle");
13938        }
13939
13940        final long origId = Binder.clearCallingIdentity();
13941        try {
13942            boolean doNext = false;
13943            BroadcastRecord r;
13944
13945            synchronized(this) {
13946                r = broadcastRecordForReceiverLocked(who);
13947                if (r != null) {
13948                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13949                        resultData, resultExtras, resultAbort, true);
13950                }
13951            }
13952
13953            if (doNext) {
13954                r.queue.processNextBroadcast(false);
13955            }
13956            trimApplications();
13957        } finally {
13958            Binder.restoreCallingIdentity(origId);
13959        }
13960    }
13961
13962    // =========================================================
13963    // INSTRUMENTATION
13964    // =========================================================
13965
13966    public boolean startInstrumentation(ComponentName className,
13967            String profileFile, int flags, Bundle arguments,
13968            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13969            int userId) {
13970        enforceNotIsolatedCaller("startInstrumentation");
13971        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13972                userId, false, true, "startInstrumentation", null);
13973        // Refuse possible leaked file descriptors
13974        if (arguments != null && arguments.hasFileDescriptors()) {
13975            throw new IllegalArgumentException("File descriptors passed in Bundle");
13976        }
13977
13978        synchronized(this) {
13979            InstrumentationInfo ii = null;
13980            ApplicationInfo ai = null;
13981            try {
13982                ii = mContext.getPackageManager().getInstrumentationInfo(
13983                    className, STOCK_PM_FLAGS);
13984                ai = AppGlobals.getPackageManager().getApplicationInfo(
13985                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13986            } catch (PackageManager.NameNotFoundException e) {
13987            } catch (RemoteException e) {
13988            }
13989            if (ii == null) {
13990                reportStartInstrumentationFailure(watcher, className,
13991                        "Unable to find instrumentation info for: " + className);
13992                return false;
13993            }
13994            if (ai == null) {
13995                reportStartInstrumentationFailure(watcher, className,
13996                        "Unable to find instrumentation target package: " + ii.targetPackage);
13997                return false;
13998            }
13999
14000            int match = mContext.getPackageManager().checkSignatures(
14001                    ii.targetPackage, ii.packageName);
14002            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14003                String msg = "Permission Denial: starting instrumentation "
14004                        + className + " from pid="
14005                        + Binder.getCallingPid()
14006                        + ", uid=" + Binder.getCallingPid()
14007                        + " not allowed because package " + ii.packageName
14008                        + " does not have a signature matching the target "
14009                        + ii.targetPackage;
14010                reportStartInstrumentationFailure(watcher, className, msg);
14011                throw new SecurityException(msg);
14012            }
14013
14014            final long origId = Binder.clearCallingIdentity();
14015            // Instrumentation can kill and relaunch even persistent processes
14016            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14017                    "start instr");
14018            ProcessRecord app = addAppLocked(ai, false);
14019            app.instrumentationClass = className;
14020            app.instrumentationInfo = ai;
14021            app.instrumentationProfileFile = profileFile;
14022            app.instrumentationArguments = arguments;
14023            app.instrumentationWatcher = watcher;
14024            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14025            app.instrumentationResultClass = className;
14026            Binder.restoreCallingIdentity(origId);
14027        }
14028
14029        return true;
14030    }
14031
14032    /**
14033     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14034     * error to the logs, but if somebody is watching, send the report there too.  This enables
14035     * the "am" command to report errors with more information.
14036     *
14037     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14038     * @param cn The component name of the instrumentation.
14039     * @param report The error report.
14040     */
14041    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14042            ComponentName cn, String report) {
14043        Slog.w(TAG, report);
14044        try {
14045            if (watcher != null) {
14046                Bundle results = new Bundle();
14047                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14048                results.putString("Error", report);
14049                watcher.instrumentationStatus(cn, -1, results);
14050            }
14051        } catch (RemoteException e) {
14052            Slog.w(TAG, e);
14053        }
14054    }
14055
14056    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14057        if (app.instrumentationWatcher != null) {
14058            try {
14059                // NOTE:  IInstrumentationWatcher *must* be oneway here
14060                app.instrumentationWatcher.instrumentationFinished(
14061                    app.instrumentationClass,
14062                    resultCode,
14063                    results);
14064            } catch (RemoteException e) {
14065            }
14066        }
14067        if (app.instrumentationUiAutomationConnection != null) {
14068            try {
14069                app.instrumentationUiAutomationConnection.shutdown();
14070            } catch (RemoteException re) {
14071                /* ignore */
14072            }
14073            // Only a UiAutomation can set this flag and now that
14074            // it is finished we make sure it is reset to its default.
14075            mUserIsMonkey = false;
14076        }
14077        app.instrumentationWatcher = null;
14078        app.instrumentationUiAutomationConnection = null;
14079        app.instrumentationClass = null;
14080        app.instrumentationInfo = null;
14081        app.instrumentationProfileFile = null;
14082        app.instrumentationArguments = null;
14083
14084        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14085                "finished inst");
14086    }
14087
14088    public void finishInstrumentation(IApplicationThread target,
14089            int resultCode, Bundle results) {
14090        int userId = UserHandle.getCallingUserId();
14091        // Refuse possible leaked file descriptors
14092        if (results != null && results.hasFileDescriptors()) {
14093            throw new IllegalArgumentException("File descriptors passed in Intent");
14094        }
14095
14096        synchronized(this) {
14097            ProcessRecord app = getRecordForAppLocked(target);
14098            if (app == null) {
14099                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14100                return;
14101            }
14102            final long origId = Binder.clearCallingIdentity();
14103            finishInstrumentationLocked(app, resultCode, results);
14104            Binder.restoreCallingIdentity(origId);
14105        }
14106    }
14107
14108    // =========================================================
14109    // CONFIGURATION
14110    // =========================================================
14111
14112    public ConfigurationInfo getDeviceConfigurationInfo() {
14113        ConfigurationInfo config = new ConfigurationInfo();
14114        synchronized (this) {
14115            config.reqTouchScreen = mConfiguration.touchscreen;
14116            config.reqKeyboardType = mConfiguration.keyboard;
14117            config.reqNavigation = mConfiguration.navigation;
14118            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14119                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14120                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14121            }
14122            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14123                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14124                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14125            }
14126            config.reqGlEsVersion = GL_ES_VERSION;
14127        }
14128        return config;
14129    }
14130
14131    ActivityStack getFocusedStack() {
14132        return mStackSupervisor.getFocusedStack();
14133    }
14134
14135    public Configuration getConfiguration() {
14136        Configuration ci;
14137        synchronized(this) {
14138            ci = new Configuration(mConfiguration);
14139        }
14140        return ci;
14141    }
14142
14143    public void updatePersistentConfiguration(Configuration values) {
14144        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14145                "updateConfiguration()");
14146        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14147                "updateConfiguration()");
14148        if (values == null) {
14149            throw new NullPointerException("Configuration must not be null");
14150        }
14151
14152        synchronized(this) {
14153            final long origId = Binder.clearCallingIdentity();
14154            updateConfigurationLocked(values, null, true, false);
14155            Binder.restoreCallingIdentity(origId);
14156        }
14157    }
14158
14159    public void updateConfiguration(Configuration values) {
14160        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14161                "updateConfiguration()");
14162
14163        synchronized(this) {
14164            if (values == null && mWindowManager != null) {
14165                // sentinel: fetch the current configuration from the window manager
14166                values = mWindowManager.computeNewConfiguration();
14167            }
14168
14169            if (mWindowManager != null) {
14170                mProcessList.applyDisplaySize(mWindowManager);
14171            }
14172
14173            final long origId = Binder.clearCallingIdentity();
14174            if (values != null) {
14175                Settings.System.clearConfiguration(values);
14176            }
14177            updateConfigurationLocked(values, null, false, false);
14178            Binder.restoreCallingIdentity(origId);
14179        }
14180    }
14181
14182    /**
14183     * Do either or both things: (1) change the current configuration, and (2)
14184     * make sure the given activity is running with the (now) current
14185     * configuration.  Returns true if the activity has been left running, or
14186     * false if <var>starting</var> is being destroyed to match the new
14187     * configuration.
14188     * @param persistent TODO
14189     */
14190    boolean updateConfigurationLocked(Configuration values,
14191            ActivityRecord starting, boolean persistent, boolean initLocale) {
14192        int changes = 0;
14193
14194        if (values != null) {
14195            Configuration newConfig = new Configuration(mConfiguration);
14196            changes = newConfig.updateFrom(values);
14197            if (changes != 0) {
14198                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14199                    Slog.i(TAG, "Updating configuration to: " + values);
14200                }
14201
14202                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14203
14204                if (values.locale != null && !initLocale) {
14205                    saveLocaleLocked(values.locale,
14206                                     !values.locale.equals(mConfiguration.locale),
14207                                     values.userSetLocale);
14208                }
14209
14210                mConfigurationSeq++;
14211                if (mConfigurationSeq <= 0) {
14212                    mConfigurationSeq = 1;
14213                }
14214                newConfig.seq = mConfigurationSeq;
14215                mConfiguration = newConfig;
14216                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14217
14218                final Configuration configCopy = new Configuration(mConfiguration);
14219
14220                // TODO: If our config changes, should we auto dismiss any currently
14221                // showing dialogs?
14222                mShowDialogs = shouldShowDialogs(newConfig);
14223
14224                AttributeCache ac = AttributeCache.instance();
14225                if (ac != null) {
14226                    ac.updateConfiguration(configCopy);
14227                }
14228
14229                // Make sure all resources in our process are updated
14230                // right now, so that anyone who is going to retrieve
14231                // resource values after we return will be sure to get
14232                // the new ones.  This is especially important during
14233                // boot, where the first config change needs to guarantee
14234                // all resources have that config before following boot
14235                // code is executed.
14236                mSystemThread.applyConfigurationToResources(configCopy);
14237
14238                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14239                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14240                    msg.obj = new Configuration(configCopy);
14241                    mHandler.sendMessage(msg);
14242                }
14243
14244                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14245                    ProcessRecord app = mLruProcesses.get(i);
14246                    try {
14247                        if (app.thread != null) {
14248                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14249                                    + app.processName + " new config " + mConfiguration);
14250                            app.thread.scheduleConfigurationChanged(configCopy);
14251                        }
14252                    } catch (Exception e) {
14253                    }
14254                }
14255                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14256                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14257                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14258                        | Intent.FLAG_RECEIVER_FOREGROUND);
14259                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14260                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14261                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14262                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14263                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14264                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14265                    broadcastIntentLocked(null, null, intent,
14266                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14267                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14268                }
14269            }
14270        }
14271
14272        boolean kept = true;
14273        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14274        // mainStack is null during startup.
14275        if (mainStack != null) {
14276            if (changes != 0 && starting == null) {
14277                // If the configuration changed, and the caller is not already
14278                // in the process of starting an activity, then find the top
14279                // activity to check if its configuration needs to change.
14280                starting = mainStack.topRunningActivityLocked(null);
14281            }
14282
14283            if (starting != null) {
14284                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14285                // And we need to make sure at this point that all other activities
14286                // are made visible with the correct configuration.
14287                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14288            }
14289        }
14290
14291        if (values != null && mWindowManager != null) {
14292            mWindowManager.setNewConfiguration(mConfiguration);
14293        }
14294
14295        return kept;
14296    }
14297
14298    /**
14299     * Decide based on the configuration whether we should shouw the ANR,
14300     * crash, etc dialogs.  The idea is that if there is no affordnace to
14301     * press the on-screen buttons, we shouldn't show the dialog.
14302     *
14303     * A thought: SystemUI might also want to get told about this, the Power
14304     * dialog / global actions also might want different behaviors.
14305     */
14306    private static final boolean shouldShowDialogs(Configuration config) {
14307        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14308                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14309    }
14310
14311    /**
14312     * Save the locale.  You must be inside a synchronized (this) block.
14313     */
14314    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14315        if(isDiff) {
14316            SystemProperties.set("user.language", l.getLanguage());
14317            SystemProperties.set("user.region", l.getCountry());
14318        }
14319
14320        if(isPersist) {
14321            SystemProperties.set("persist.sys.language", l.getLanguage());
14322            SystemProperties.set("persist.sys.country", l.getCountry());
14323            SystemProperties.set("persist.sys.localevar", l.getVariant());
14324        }
14325    }
14326
14327    @Override
14328    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14329        ActivityRecord srec = ActivityRecord.forToken(token);
14330        return srec != null && srec.task.affinity != null &&
14331                srec.task.affinity.equals(destAffinity);
14332    }
14333
14334    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14335            Intent resultData) {
14336
14337        synchronized (this) {
14338            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14339            if (stack != null) {
14340                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14341            }
14342            return false;
14343        }
14344    }
14345
14346    public int getLaunchedFromUid(IBinder activityToken) {
14347        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14348        if (srec == null) {
14349            return -1;
14350        }
14351        return srec.launchedFromUid;
14352    }
14353
14354    public String getLaunchedFromPackage(IBinder activityToken) {
14355        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14356        if (srec == null) {
14357            return null;
14358        }
14359        return srec.launchedFromPackage;
14360    }
14361
14362    // =========================================================
14363    // LIFETIME MANAGEMENT
14364    // =========================================================
14365
14366    // Returns which broadcast queue the app is the current [or imminent] receiver
14367    // on, or 'null' if the app is not an active broadcast recipient.
14368    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14369        BroadcastRecord r = app.curReceiver;
14370        if (r != null) {
14371            return r.queue;
14372        }
14373
14374        // It's not the current receiver, but it might be starting up to become one
14375        synchronized (this) {
14376            for (BroadcastQueue queue : mBroadcastQueues) {
14377                r = queue.mPendingBroadcast;
14378                if (r != null && r.curApp == app) {
14379                    // found it; report which queue it's in
14380                    return queue;
14381                }
14382            }
14383        }
14384
14385        return null;
14386    }
14387
14388    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14389            boolean doingAll, long now) {
14390        if (mAdjSeq == app.adjSeq) {
14391            // This adjustment has already been computed.
14392            return app.curRawAdj;
14393        }
14394
14395        if (app.thread == null) {
14396            app.adjSeq = mAdjSeq;
14397            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14398            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14399            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14400        }
14401
14402        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14403        app.adjSource = null;
14404        app.adjTarget = null;
14405        app.empty = false;
14406        app.cached = false;
14407
14408        final int activitiesSize = app.activities.size();
14409
14410        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14411            // The max adjustment doesn't allow this app to be anything
14412            // below foreground, so it is not worth doing work for it.
14413            app.adjType = "fixed";
14414            app.adjSeq = mAdjSeq;
14415            app.curRawAdj = app.maxAdj;
14416            app.foregroundActivities = false;
14417            app.keeping = true;
14418            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14419            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14420            // System process can do UI, and when they do we want to have
14421            // them trim their memory after the user leaves the UI.  To
14422            // facilitate this, here we need to determine whether or not it
14423            // is currently showing UI.
14424            app.systemNoUi = true;
14425            if (app == TOP_APP) {
14426                app.systemNoUi = false;
14427            } else if (activitiesSize > 0) {
14428                for (int j = 0; j < activitiesSize; j++) {
14429                    final ActivityRecord r = app.activities.get(j);
14430                    if (r.visible) {
14431                        app.systemNoUi = false;
14432                    }
14433                }
14434            }
14435            if (!app.systemNoUi) {
14436                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14437            }
14438            return (app.curAdj=app.maxAdj);
14439        }
14440
14441        app.keeping = false;
14442        app.systemNoUi = false;
14443
14444        // Determine the importance of the process, starting with most
14445        // important to least, and assign an appropriate OOM adjustment.
14446        int adj;
14447        int schedGroup;
14448        int procState;
14449        boolean foregroundActivities = false;
14450        boolean interesting = false;
14451        BroadcastQueue queue;
14452        if (app == TOP_APP) {
14453            // The last app on the list is the foreground app.
14454            adj = ProcessList.FOREGROUND_APP_ADJ;
14455            schedGroup = Process.THREAD_GROUP_DEFAULT;
14456            app.adjType = "top-activity";
14457            foregroundActivities = true;
14458            interesting = true;
14459            procState = ActivityManager.PROCESS_STATE_TOP;
14460        } else if (app.instrumentationClass != null) {
14461            // Don't want to kill running instrumentation.
14462            adj = ProcessList.FOREGROUND_APP_ADJ;
14463            schedGroup = Process.THREAD_GROUP_DEFAULT;
14464            app.adjType = "instrumentation";
14465            interesting = true;
14466            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14467        } else if ((queue = isReceivingBroadcast(app)) != null) {
14468            // An app that is currently receiving a broadcast also
14469            // counts as being in the foreground for OOM killer purposes.
14470            // It's placed in a sched group based on the nature of the
14471            // broadcast as reflected by which queue it's active in.
14472            adj = ProcessList.FOREGROUND_APP_ADJ;
14473            schedGroup = (queue == mFgBroadcastQueue)
14474                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14475            app.adjType = "broadcast";
14476            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14477        } else if (app.executingServices.size() > 0) {
14478            // An app that is currently executing a service callback also
14479            // counts as being in the foreground.
14480            adj = ProcessList.FOREGROUND_APP_ADJ;
14481            schedGroup = app.execServicesFg ?
14482                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14483            app.adjType = "exec-service";
14484            procState = ActivityManager.PROCESS_STATE_SERVICE;
14485            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14486        } else {
14487            // As far as we know the process is empty.  We may change our mind later.
14488            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14489            // At this point we don't actually know the adjustment.  Use the cached adj
14490            // value that the caller wants us to.
14491            adj = cachedAdj;
14492            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14493            app.cached = true;
14494            app.empty = true;
14495            app.adjType = "cch-empty";
14496        }
14497
14498        // Examine all activities if not already foreground.
14499        if (!foregroundActivities && activitiesSize > 0) {
14500            for (int j = 0; j < activitiesSize; j++) {
14501                final ActivityRecord r = app.activities.get(j);
14502                if (r.app != app) {
14503                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14504                            + app + "?!?");
14505                    continue;
14506                }
14507                if (r.visible) {
14508                    // App has a visible activity; only upgrade adjustment.
14509                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14510                        adj = ProcessList.VISIBLE_APP_ADJ;
14511                        app.adjType = "visible";
14512                    }
14513                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14514                        procState = ActivityManager.PROCESS_STATE_TOP;
14515                    }
14516                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14517                    app.cached = false;
14518                    app.empty = false;
14519                    foregroundActivities = true;
14520                    break;
14521                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14522                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14523                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14524                        app.adjType = "pausing";
14525                    }
14526                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14527                        procState = ActivityManager.PROCESS_STATE_TOP;
14528                    }
14529                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14530                    app.cached = false;
14531                    app.empty = false;
14532                    foregroundActivities = true;
14533                } else if (r.state == ActivityState.STOPPING) {
14534                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14535                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14536                        app.adjType = "stopping";
14537                    }
14538                    // For the process state, we will at this point consider the
14539                    // process to be cached.  It will be cached either as an activity
14540                    // or empty depending on whether the activity is finishing.  We do
14541                    // this so that we can treat the process as cached for purposes of
14542                    // memory trimming (determing current memory level, trim command to
14543                    // send to process) since there can be an arbitrary number of stopping
14544                    // processes and they should soon all go into the cached state.
14545                    if (!r.finishing) {
14546                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14547                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14548                        }
14549                    }
14550                    app.cached = false;
14551                    app.empty = false;
14552                    foregroundActivities = true;
14553                } else {
14554                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14555                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14556                        app.adjType = "cch-act";
14557                    }
14558                }
14559            }
14560        }
14561
14562        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14563            if (app.foregroundServices) {
14564                // The user is aware of this app, so make it visible.
14565                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14566                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14567                app.cached = false;
14568                app.adjType = "fg-service";
14569                schedGroup = Process.THREAD_GROUP_DEFAULT;
14570            } else if (app.forcingToForeground != null) {
14571                // The user is aware of this app, so make it visible.
14572                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14573                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14574                app.cached = false;
14575                app.adjType = "force-fg";
14576                app.adjSource = app.forcingToForeground;
14577                schedGroup = Process.THREAD_GROUP_DEFAULT;
14578            }
14579        }
14580
14581        if (app.foregroundServices) {
14582            interesting = true;
14583        }
14584
14585        if (app == mHeavyWeightProcess) {
14586            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14587                // We don't want to kill the current heavy-weight process.
14588                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14589                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14590                app.cached = false;
14591                app.adjType = "heavy";
14592            }
14593            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14594                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14595            }
14596        }
14597
14598        if (app == mHomeProcess) {
14599            if (adj > ProcessList.HOME_APP_ADJ) {
14600                // This process is hosting what we currently consider to be the
14601                // home app, so we don't want to let it go into the background.
14602                adj = ProcessList.HOME_APP_ADJ;
14603                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14604                app.cached = false;
14605                app.adjType = "home";
14606            }
14607            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14608                procState = ActivityManager.PROCESS_STATE_HOME;
14609            }
14610        }
14611
14612        if (app == mPreviousProcess && app.activities.size() > 0) {
14613            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14614                // This was the previous process that showed UI to the user.
14615                // We want to try to keep it around more aggressively, to give
14616                // a good experience around switching between two apps.
14617                adj = ProcessList.PREVIOUS_APP_ADJ;
14618                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14619                app.cached = false;
14620                app.adjType = "previous";
14621            }
14622            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14623                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14624            }
14625        }
14626
14627        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14628                + " reason=" + app.adjType);
14629
14630        // By default, we use the computed adjustment.  It may be changed if
14631        // there are applications dependent on our services or providers, but
14632        // this gives us a baseline and makes sure we don't get into an
14633        // infinite recursion.
14634        app.adjSeq = mAdjSeq;
14635        app.curRawAdj = adj;
14636        app.hasStartedServices = false;
14637
14638        if (mBackupTarget != null && app == mBackupTarget.app) {
14639            // If possible we want to avoid killing apps while they're being backed up
14640            if (adj > ProcessList.BACKUP_APP_ADJ) {
14641                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14642                adj = ProcessList.BACKUP_APP_ADJ;
14643                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14644                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14645                }
14646                app.adjType = "backup";
14647                app.cached = false;
14648            }
14649            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14650                procState = ActivityManager.PROCESS_STATE_BACKUP;
14651            }
14652        }
14653
14654        boolean mayBeTop = false;
14655
14656        for (int is = app.services.size()-1;
14657                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14658                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14659                        || procState > ActivityManager.PROCESS_STATE_TOP);
14660                is--) {
14661            ServiceRecord s = app.services.valueAt(is);
14662            if (s.startRequested) {
14663                app.hasStartedServices = true;
14664                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14665                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14666                }
14667                if (app.hasShownUi && app != mHomeProcess) {
14668                    // If this process has shown some UI, let it immediately
14669                    // go to the LRU list because it may be pretty heavy with
14670                    // UI stuff.  We'll tag it with a label just to help
14671                    // debug and understand what is going on.
14672                    if (adj > ProcessList.SERVICE_ADJ) {
14673                        app.adjType = "cch-started-ui-services";
14674                    }
14675                } else {
14676                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14677                        // This service has seen some activity within
14678                        // recent memory, so we will keep its process ahead
14679                        // of the background processes.
14680                        if (adj > ProcessList.SERVICE_ADJ) {
14681                            adj = ProcessList.SERVICE_ADJ;
14682                            app.adjType = "started-services";
14683                            app.cached = false;
14684                        }
14685                    }
14686                    // If we have let the service slide into the background
14687                    // state, still have some text describing what it is doing
14688                    // even though the service no longer has an impact.
14689                    if (adj > ProcessList.SERVICE_ADJ) {
14690                        app.adjType = "cch-started-services";
14691                    }
14692                }
14693                // Don't kill this process because it is doing work; it
14694                // has said it is doing work.
14695                app.keeping = true;
14696            }
14697            for (int conni = s.connections.size()-1;
14698                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14699                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14700                            || procState > ActivityManager.PROCESS_STATE_TOP);
14701                    conni--) {
14702                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14703                for (int i = 0;
14704                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14705                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14706                                || procState > ActivityManager.PROCESS_STATE_TOP);
14707                        i++) {
14708                    // XXX should compute this based on the max of
14709                    // all connected clients.
14710                    ConnectionRecord cr = clist.get(i);
14711                    if (cr.binding.client == app) {
14712                        // Binding to ourself is not interesting.
14713                        continue;
14714                    }
14715                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14716                        ProcessRecord client = cr.binding.client;
14717                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14718                                TOP_APP, doingAll, now);
14719                        int clientProcState = client.curProcState;
14720                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14721                            // If the other app is cached for any reason, for purposes here
14722                            // we are going to consider it empty.  The specific cached state
14723                            // doesn't propagate except under certain conditions.
14724                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14725                        }
14726                        String adjType = null;
14727                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14728                            // Not doing bind OOM management, so treat
14729                            // this guy more like a started service.
14730                            if (app.hasShownUi && app != mHomeProcess) {
14731                                // If this process has shown some UI, let it immediately
14732                                // go to the LRU list because it may be pretty heavy with
14733                                // UI stuff.  We'll tag it with a label just to help
14734                                // debug and understand what is going on.
14735                                if (adj > clientAdj) {
14736                                    adjType = "cch-bound-ui-services";
14737                                }
14738                                app.cached = false;
14739                                clientAdj = adj;
14740                                clientProcState = procState;
14741                            } else {
14742                                if (now >= (s.lastActivity
14743                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14744                                    // This service has not seen activity within
14745                                    // recent memory, so allow it to drop to the
14746                                    // LRU list if there is no other reason to keep
14747                                    // it around.  We'll also tag it with a label just
14748                                    // to help debug and undertand what is going on.
14749                                    if (adj > clientAdj) {
14750                                        adjType = "cch-bound-services";
14751                                    }
14752                                    clientAdj = adj;
14753                                }
14754                            }
14755                        }
14756                        if (adj > clientAdj) {
14757                            // If this process has recently shown UI, and
14758                            // the process that is binding to it is less
14759                            // important than being visible, then we don't
14760                            // care about the binding as much as we care
14761                            // about letting this process get into the LRU
14762                            // list to be killed and restarted if needed for
14763                            // memory.
14764                            if (app.hasShownUi && app != mHomeProcess
14765                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14766                                adjType = "cch-bound-ui-services";
14767                            } else {
14768                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14769                                        |Context.BIND_IMPORTANT)) != 0) {
14770                                    adj = clientAdj;
14771                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14772                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14773                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14774                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14775                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14776                                    adj = clientAdj;
14777                                } else {
14778                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14779                                        adj = ProcessList.VISIBLE_APP_ADJ;
14780                                    }
14781                                }
14782                                if (!client.cached) {
14783                                    app.cached = false;
14784                                }
14785                                if (client.keeping) {
14786                                    app.keeping = true;
14787                                }
14788                                adjType = "service";
14789                            }
14790                        }
14791                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14792                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14793                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14794                            }
14795                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14796                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14797                                    // Special handling of clients who are in the top state.
14798                                    // We *may* want to consider this process to be in the
14799                                    // top state as well, but only if there is not another
14800                                    // reason for it to be running.  Being on the top is a
14801                                    // special state, meaning you are specifically running
14802                                    // for the current top app.  If the process is already
14803                                    // running in the background for some other reason, it
14804                                    // is more important to continue considering it to be
14805                                    // in the background state.
14806                                    mayBeTop = true;
14807                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14808                                } else {
14809                                    // Special handling for above-top states (persistent
14810                                    // processes).  These should not bring the current process
14811                                    // into the top state, since they are not on top.  Instead
14812                                    // give them the best state after that.
14813                                    clientProcState =
14814                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14815                                }
14816                            }
14817                        } else {
14818                            if (clientProcState <
14819                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14820                                clientProcState =
14821                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14822                            }
14823                        }
14824                        if (procState > clientProcState) {
14825                            procState = clientProcState;
14826                        }
14827                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14828                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14829                            app.pendingUiClean = true;
14830                        }
14831                        if (adjType != null) {
14832                            app.adjType = adjType;
14833                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14834                                    .REASON_SERVICE_IN_USE;
14835                            app.adjSource = cr.binding.client;
14836                            app.adjSourceOom = clientAdj;
14837                            app.adjTarget = s.name;
14838                        }
14839                    }
14840                    final ActivityRecord a = cr.activity;
14841                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14842                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14843                                (a.visible || a.state == ActivityState.RESUMED
14844                                 || a.state == ActivityState.PAUSING)) {
14845                            adj = ProcessList.FOREGROUND_APP_ADJ;
14846                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14847                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14848                            }
14849                            app.cached = false;
14850                            app.adjType = "service";
14851                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14852                                    .REASON_SERVICE_IN_USE;
14853                            app.adjSource = a;
14854                            app.adjSourceOom = adj;
14855                            app.adjTarget = s.name;
14856                        }
14857                    }
14858                }
14859            }
14860        }
14861
14862        for (int provi = app.pubProviders.size()-1;
14863                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14864                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14865                        || procState > ActivityManager.PROCESS_STATE_TOP);
14866                provi--) {
14867            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14868            for (int i = cpr.connections.size()-1;
14869                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14870                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14871                            || procState > ActivityManager.PROCESS_STATE_TOP);
14872                    i--) {
14873                ContentProviderConnection conn = cpr.connections.get(i);
14874                ProcessRecord client = conn.client;
14875                if (client == app) {
14876                    // Being our own client is not interesting.
14877                    continue;
14878                }
14879                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14880                int clientProcState = client.curProcState;
14881                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14882                    // If the other app is cached for any reason, for purposes here
14883                    // we are going to consider it empty.
14884                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14885                }
14886                if (adj > clientAdj) {
14887                    if (app.hasShownUi && app != mHomeProcess
14888                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14889                        app.adjType = "cch-ui-provider";
14890                    } else {
14891                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14892                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14893                        app.adjType = "provider";
14894                    }
14895                    app.cached &= client.cached;
14896                    app.keeping |= client.keeping;
14897                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14898                            .REASON_PROVIDER_IN_USE;
14899                    app.adjSource = client;
14900                    app.adjSourceOom = clientAdj;
14901                    app.adjTarget = cpr.name;
14902                }
14903                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14904                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14905                        // Special handling of clients who are in the top state.
14906                        // We *may* want to consider this process to be in the
14907                        // top state as well, but only if there is not another
14908                        // reason for it to be running.  Being on the top is a
14909                        // special state, meaning you are specifically running
14910                        // for the current top app.  If the process is already
14911                        // running in the background for some other reason, it
14912                        // is more important to continue considering it to be
14913                        // in the background state.
14914                        mayBeTop = true;
14915                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14916                    } else {
14917                        // Special handling for above-top states (persistent
14918                        // processes).  These should not bring the current process
14919                        // into the top state, since they are not on top.  Instead
14920                        // give them the best state after that.
14921                        clientProcState =
14922                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14923                    }
14924                }
14925                if (procState > clientProcState) {
14926                    procState = clientProcState;
14927                }
14928                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14929                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14930                }
14931            }
14932            // If the provider has external (non-framework) process
14933            // dependencies, ensure that its adjustment is at least
14934            // FOREGROUND_APP_ADJ.
14935            if (cpr.hasExternalProcessHandles()) {
14936                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14937                    adj = ProcessList.FOREGROUND_APP_ADJ;
14938                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14939                    app.cached = false;
14940                    app.keeping = true;
14941                    app.adjType = "provider";
14942                    app.adjTarget = cpr.name;
14943                }
14944                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14945                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14946                }
14947            }
14948        }
14949
14950        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14951            // A client of one of our services or providers is in the top state.  We
14952            // *may* want to be in the top state, but not if we are already running in
14953            // the background for some other reason.  For the decision here, we are going
14954            // to pick out a few specific states that we want to remain in when a client
14955            // is top (states that tend to be longer-term) and otherwise allow it to go
14956            // to the top state.
14957            switch (procState) {
14958                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14959                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14960                case ActivityManager.PROCESS_STATE_SERVICE:
14961                    // These all are longer-term states, so pull them up to the top
14962                    // of the background states, but not all the way to the top state.
14963                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14964                    break;
14965                default:
14966                    // Otherwise, top is a better choice, so take it.
14967                    procState = ActivityManager.PROCESS_STATE_TOP;
14968                    break;
14969            }
14970        }
14971
14972        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14973            // This is a cached process, but with client activities.  Mark it so.
14974            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14975            app.adjType = "cch-client-act";
14976        }
14977
14978        if (adj == ProcessList.SERVICE_ADJ) {
14979            if (doingAll) {
14980                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14981                mNewNumServiceProcs++;
14982                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14983                if (!app.serviceb) {
14984                    // This service isn't far enough down on the LRU list to
14985                    // normally be a B service, but if we are low on RAM and it
14986                    // is large we want to force it down since we would prefer to
14987                    // keep launcher over it.
14988                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14989                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14990                        app.serviceHighRam = true;
14991                        app.serviceb = true;
14992                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14993                    } else {
14994                        mNewNumAServiceProcs++;
14995                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14996                    }
14997                } else {
14998                    app.serviceHighRam = false;
14999                }
15000            }
15001            if (app.serviceb) {
15002                adj = ProcessList.SERVICE_B_ADJ;
15003            }
15004        }
15005
15006        app.curRawAdj = adj;
15007
15008        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15009        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15010        if (adj > app.maxAdj) {
15011            adj = app.maxAdj;
15012            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15013                schedGroup = Process.THREAD_GROUP_DEFAULT;
15014            }
15015        }
15016        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15017            app.keeping = true;
15018        }
15019
15020        // Do final modification to adj.  Everything we do between here and applying
15021        // the final setAdj must be done in this function, because we will also use
15022        // it when computing the final cached adj later.  Note that we don't need to
15023        // worry about this for max adj above, since max adj will always be used to
15024        // keep it out of the cached vaues.
15025        adj = app.modifyRawOomAdj(adj);
15026
15027        app.curProcState = procState;
15028
15029        int importance = app.memImportance;
15030        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15031            app.curAdj = adj;
15032            app.curSchedGroup = schedGroup;
15033            if (!interesting) {
15034                // For this reporting, if there is not something explicitly
15035                // interesting in this process then we will push it to the
15036                // background importance.
15037                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15038            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15039                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15040            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15041                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15042            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15043                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15044            } else if (adj >= ProcessList.SERVICE_ADJ) {
15045                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15046            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15047                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15048            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15049                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15050            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15051                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15052            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15053                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15054            } else {
15055                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15056            }
15057        }
15058
15059        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15060        if (foregroundActivities != app.foregroundActivities) {
15061            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15062        }
15063        if (changes != 0) {
15064            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15065            app.memImportance = importance;
15066            app.foregroundActivities = foregroundActivities;
15067            int i = mPendingProcessChanges.size()-1;
15068            ProcessChangeItem item = null;
15069            while (i >= 0) {
15070                item = mPendingProcessChanges.get(i);
15071                if (item.pid == app.pid) {
15072                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15073                    break;
15074                }
15075                i--;
15076            }
15077            if (i < 0) {
15078                // No existing item in pending changes; need a new one.
15079                final int NA = mAvailProcessChanges.size();
15080                if (NA > 0) {
15081                    item = mAvailProcessChanges.remove(NA-1);
15082                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15083                } else {
15084                    item = new ProcessChangeItem();
15085                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15086                }
15087                item.changes = 0;
15088                item.pid = app.pid;
15089                item.uid = app.info.uid;
15090                if (mPendingProcessChanges.size() == 0) {
15091                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15092                            "*** Enqueueing dispatch processes changed!");
15093                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15094                }
15095                mPendingProcessChanges.add(item);
15096            }
15097            item.changes |= changes;
15098            item.importance = importance;
15099            item.foregroundActivities = foregroundActivities;
15100            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15101                    + Integer.toHexString(System.identityHashCode(item))
15102                    + " " + app.toShortString() + ": changes=" + item.changes
15103                    + " importance=" + item.importance
15104                    + " foreground=" + item.foregroundActivities
15105                    + " type=" + app.adjType + " source=" + app.adjSource
15106                    + " target=" + app.adjTarget);
15107        }
15108
15109        return app.curRawAdj;
15110    }
15111
15112    /**
15113     * Schedule PSS collection of a process.
15114     */
15115    void requestPssLocked(ProcessRecord proc, int procState) {
15116        if (mPendingPssProcesses.contains(proc)) {
15117            return;
15118        }
15119        if (mPendingPssProcesses.size() == 0) {
15120            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15121        }
15122        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15123        proc.pssProcState = procState;
15124        mPendingPssProcesses.add(proc);
15125    }
15126
15127    /**
15128     * Schedule PSS collection of all processes.
15129     */
15130    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15131        if (!always) {
15132            if (now < (mLastFullPssTime +
15133                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15134                return;
15135            }
15136        }
15137        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15138        mLastFullPssTime = now;
15139        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15140        mPendingPssProcesses.clear();
15141        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15142            ProcessRecord app = mLruProcesses.get(i);
15143            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15144                app.pssProcState = app.setProcState;
15145                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15146                        mSleeping, now);
15147                mPendingPssProcesses.add(app);
15148            }
15149        }
15150        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15151    }
15152
15153    /**
15154     * Ask a given process to GC right now.
15155     */
15156    final void performAppGcLocked(ProcessRecord app) {
15157        try {
15158            app.lastRequestedGc = SystemClock.uptimeMillis();
15159            if (app.thread != null) {
15160                if (app.reportLowMemory) {
15161                    app.reportLowMemory = false;
15162                    app.thread.scheduleLowMemory();
15163                } else {
15164                    app.thread.processInBackground();
15165                }
15166            }
15167        } catch (Exception e) {
15168            // whatever.
15169        }
15170    }
15171
15172    /**
15173     * Returns true if things are idle enough to perform GCs.
15174     */
15175    private final boolean canGcNowLocked() {
15176        boolean processingBroadcasts = false;
15177        for (BroadcastQueue q : mBroadcastQueues) {
15178            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15179                processingBroadcasts = true;
15180            }
15181        }
15182        return !processingBroadcasts
15183                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15184    }
15185
15186    /**
15187     * Perform GCs on all processes that are waiting for it, but only
15188     * if things are idle.
15189     */
15190    final void performAppGcsLocked() {
15191        final int N = mProcessesToGc.size();
15192        if (N <= 0) {
15193            return;
15194        }
15195        if (canGcNowLocked()) {
15196            while (mProcessesToGc.size() > 0) {
15197                ProcessRecord proc = mProcessesToGc.remove(0);
15198                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15199                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15200                            <= SystemClock.uptimeMillis()) {
15201                        // To avoid spamming the system, we will GC processes one
15202                        // at a time, waiting a few seconds between each.
15203                        performAppGcLocked(proc);
15204                        scheduleAppGcsLocked();
15205                        return;
15206                    } else {
15207                        // It hasn't been long enough since we last GCed this
15208                        // process...  put it in the list to wait for its time.
15209                        addProcessToGcListLocked(proc);
15210                        break;
15211                    }
15212                }
15213            }
15214
15215            scheduleAppGcsLocked();
15216        }
15217    }
15218
15219    /**
15220     * If all looks good, perform GCs on all processes waiting for them.
15221     */
15222    final void performAppGcsIfAppropriateLocked() {
15223        if (canGcNowLocked()) {
15224            performAppGcsLocked();
15225            return;
15226        }
15227        // Still not idle, wait some more.
15228        scheduleAppGcsLocked();
15229    }
15230
15231    /**
15232     * Schedule the execution of all pending app GCs.
15233     */
15234    final void scheduleAppGcsLocked() {
15235        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15236
15237        if (mProcessesToGc.size() > 0) {
15238            // Schedule a GC for the time to the next process.
15239            ProcessRecord proc = mProcessesToGc.get(0);
15240            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15241
15242            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15243            long now = SystemClock.uptimeMillis();
15244            if (when < (now+GC_TIMEOUT)) {
15245                when = now + GC_TIMEOUT;
15246            }
15247            mHandler.sendMessageAtTime(msg, when);
15248        }
15249    }
15250
15251    /**
15252     * Add a process to the array of processes waiting to be GCed.  Keeps the
15253     * list in sorted order by the last GC time.  The process can't already be
15254     * on the list.
15255     */
15256    final void addProcessToGcListLocked(ProcessRecord proc) {
15257        boolean added = false;
15258        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15259            if (mProcessesToGc.get(i).lastRequestedGc <
15260                    proc.lastRequestedGc) {
15261                added = true;
15262                mProcessesToGc.add(i+1, proc);
15263                break;
15264            }
15265        }
15266        if (!added) {
15267            mProcessesToGc.add(0, proc);
15268        }
15269    }
15270
15271    /**
15272     * Set up to ask a process to GC itself.  This will either do it
15273     * immediately, or put it on the list of processes to gc the next
15274     * time things are idle.
15275     */
15276    final void scheduleAppGcLocked(ProcessRecord app) {
15277        long now = SystemClock.uptimeMillis();
15278        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15279            return;
15280        }
15281        if (!mProcessesToGc.contains(app)) {
15282            addProcessToGcListLocked(app);
15283            scheduleAppGcsLocked();
15284        }
15285    }
15286
15287    final void checkExcessivePowerUsageLocked(boolean doKills) {
15288        updateCpuStatsNow();
15289
15290        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15291        boolean doWakeKills = doKills;
15292        boolean doCpuKills = doKills;
15293        if (mLastPowerCheckRealtime == 0) {
15294            doWakeKills = false;
15295        }
15296        if (mLastPowerCheckUptime == 0) {
15297            doCpuKills = false;
15298        }
15299        if (stats.isScreenOn()) {
15300            doWakeKills = false;
15301        }
15302        final long curRealtime = SystemClock.elapsedRealtime();
15303        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15304        final long curUptime = SystemClock.uptimeMillis();
15305        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15306        mLastPowerCheckRealtime = curRealtime;
15307        mLastPowerCheckUptime = curUptime;
15308        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15309            doWakeKills = false;
15310        }
15311        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15312            doCpuKills = false;
15313        }
15314        int i = mLruProcesses.size();
15315        while (i > 0) {
15316            i--;
15317            ProcessRecord app = mLruProcesses.get(i);
15318            if (!app.keeping) {
15319                long wtime;
15320                synchronized (stats) {
15321                    wtime = stats.getProcessWakeTime(app.info.uid,
15322                            app.pid, curRealtime);
15323                }
15324                long wtimeUsed = wtime - app.lastWakeTime;
15325                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15326                if (DEBUG_POWER) {
15327                    StringBuilder sb = new StringBuilder(128);
15328                    sb.append("Wake for ");
15329                    app.toShortString(sb);
15330                    sb.append(": over ");
15331                    TimeUtils.formatDuration(realtimeSince, sb);
15332                    sb.append(" used ");
15333                    TimeUtils.formatDuration(wtimeUsed, sb);
15334                    sb.append(" (");
15335                    sb.append((wtimeUsed*100)/realtimeSince);
15336                    sb.append("%)");
15337                    Slog.i(TAG, sb.toString());
15338                    sb.setLength(0);
15339                    sb.append("CPU for ");
15340                    app.toShortString(sb);
15341                    sb.append(": over ");
15342                    TimeUtils.formatDuration(uptimeSince, sb);
15343                    sb.append(" used ");
15344                    TimeUtils.formatDuration(cputimeUsed, sb);
15345                    sb.append(" (");
15346                    sb.append((cputimeUsed*100)/uptimeSince);
15347                    sb.append("%)");
15348                    Slog.i(TAG, sb.toString());
15349                }
15350                // If a process has held a wake lock for more
15351                // than 50% of the time during this period,
15352                // that sounds bad.  Kill!
15353                if (doWakeKills && realtimeSince > 0
15354                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15355                    synchronized (stats) {
15356                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15357                                realtimeSince, wtimeUsed);
15358                    }
15359                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15360                            + " during " + realtimeSince);
15361                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15362                } else if (doCpuKills && uptimeSince > 0
15363                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15364                    synchronized (stats) {
15365                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15366                                uptimeSince, cputimeUsed);
15367                    }
15368                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15369                            + " during " + uptimeSince);
15370                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15371                } else {
15372                    app.lastWakeTime = wtime;
15373                    app.lastCpuTime = app.curCpuTime;
15374                }
15375            }
15376        }
15377    }
15378
15379    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15380            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15381        boolean success = true;
15382
15383        if (app.curRawAdj != app.setRawAdj) {
15384            if (wasKeeping && !app.keeping) {
15385                // This app is no longer something we want to keep.  Note
15386                // its current wake lock time to later know to kill it if
15387                // it is not behaving well.
15388                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15389                synchronized (stats) {
15390                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15391                            app.pid, SystemClock.elapsedRealtime());
15392                }
15393                app.lastCpuTime = app.curCpuTime;
15394            }
15395
15396            app.setRawAdj = app.curRawAdj;
15397        }
15398
15399        if (app.curAdj != app.setAdj) {
15400            ProcessList.setOomAdj(app.pid, app.curAdj);
15401            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15402                TAG, "Set " + app.pid + " " + app.processName +
15403                " adj " + app.curAdj + ": " + app.adjType);
15404            app.setAdj = app.curAdj;
15405        }
15406
15407        if (app.setSchedGroup != app.curSchedGroup) {
15408            app.setSchedGroup = app.curSchedGroup;
15409            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15410                    "Setting process group of " + app.processName
15411                    + " to " + app.curSchedGroup);
15412            if (app.waitingToKill != null &&
15413                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15414                killUnneededProcessLocked(app, app.waitingToKill);
15415                success = false;
15416            } else {
15417                if (true) {
15418                    long oldId = Binder.clearCallingIdentity();
15419                    try {
15420                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15421                    } catch (Exception e) {
15422                        Slog.w(TAG, "Failed setting process group of " + app.pid
15423                                + " to " + app.curSchedGroup);
15424                        e.printStackTrace();
15425                    } finally {
15426                        Binder.restoreCallingIdentity(oldId);
15427                    }
15428                } else {
15429                    if (app.thread != null) {
15430                        try {
15431                            app.thread.setSchedulingGroup(app.curSchedGroup);
15432                        } catch (RemoteException e) {
15433                        }
15434                    }
15435                }
15436                Process.setSwappiness(app.pid,
15437                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15438            }
15439        }
15440        if (app.repProcState != app.curProcState) {
15441            app.repProcState = app.curProcState;
15442            if (!reportingProcessState && app.thread != null) {
15443                try {
15444                    if (false) {
15445                        //RuntimeException h = new RuntimeException("here");
15446                        Slog.i(TAG, "Sending new process state " + app.repProcState
15447                                + " to " + app /*, h*/);
15448                    }
15449                    app.thread.setProcessState(app.repProcState);
15450                } catch (RemoteException e) {
15451                }
15452            }
15453        }
15454        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15455                app.setProcState)) {
15456            app.lastStateTime = now;
15457            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15458                    mSleeping, now);
15459            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15460                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15461                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15462                    + (app.nextPssTime-now) + ": " + app);
15463        } else {
15464            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15465                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15466                requestPssLocked(app, app.setProcState);
15467                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15468                        mSleeping, now);
15469            } else if (false && DEBUG_PSS) {
15470                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15471            }
15472        }
15473        if (app.setProcState != app.curProcState) {
15474            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15475                    "Proc state change of " + app.processName
15476                    + " to " + app.curProcState);
15477            app.setProcState = app.curProcState;
15478            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15479                app.notCachedSinceIdle = false;
15480            }
15481            if (!doingAll) {
15482                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15483            } else {
15484                app.procStateChanged = true;
15485            }
15486        }
15487        return success;
15488    }
15489
15490    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15491        if (proc.thread != null && proc.baseProcessTracker != null) {
15492            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15493        }
15494    }
15495
15496    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15497            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15498        if (app.thread == null) {
15499            return false;
15500        }
15501
15502        final boolean wasKeeping = app.keeping;
15503
15504        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15505
15506        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15507                reportingProcessState, now);
15508    }
15509
15510    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15511            boolean oomAdj) {
15512        if (isForeground != proc.foregroundServices) {
15513            proc.foregroundServices = isForeground;
15514            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15515                    proc.info.uid);
15516            if (isForeground) {
15517                if (curProcs == null) {
15518                    curProcs = new ArrayList<ProcessRecord>();
15519                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15520                }
15521                if (!curProcs.contains(proc)) {
15522                    curProcs.add(proc);
15523                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15524                            proc.info.packageName, proc.info.uid);
15525                }
15526            } else {
15527                if (curProcs != null) {
15528                    if (curProcs.remove(proc)) {
15529                        mBatteryStatsService.noteEvent(
15530                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15531                                proc.info.packageName, proc.info.uid);
15532                        if (curProcs.size() <= 0) {
15533                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15534                        }
15535                    }
15536                }
15537            }
15538            if (oomAdj) {
15539                updateOomAdjLocked();
15540            }
15541        }
15542    }
15543
15544    private final ActivityRecord resumedAppLocked() {
15545        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15546        String pkg;
15547        int uid;
15548        if (act != null) {
15549            pkg = act.packageName;
15550            uid = act.info.applicationInfo.uid;
15551        } else {
15552            pkg = null;
15553            uid = -1;
15554        }
15555        // Has the UID or resumed package name changed?
15556        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15557                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15558            if (mCurResumedPackage != null) {
15559                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15560                        mCurResumedPackage, mCurResumedUid);
15561            }
15562            mCurResumedPackage = pkg;
15563            mCurResumedUid = uid;
15564            if (mCurResumedPackage != null) {
15565                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15566                        mCurResumedPackage, mCurResumedUid);
15567            }
15568        }
15569        return act;
15570    }
15571
15572    final boolean updateOomAdjLocked(ProcessRecord app) {
15573        return updateOomAdjLocked(app, false);
15574    }
15575
15576    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15577        final ActivityRecord TOP_ACT = resumedAppLocked();
15578        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15579        final boolean wasCached = app.cached;
15580
15581        mAdjSeq++;
15582
15583        // This is the desired cached adjusment we want to tell it to use.
15584        // If our app is currently cached, we know it, and that is it.  Otherwise,
15585        // we don't know it yet, and it needs to now be cached we will then
15586        // need to do a complete oom adj.
15587        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15588                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15589        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15590                SystemClock.uptimeMillis());
15591        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15592            // Changed to/from cached state, so apps after it in the LRU
15593            // list may also be changed.
15594            updateOomAdjLocked();
15595        }
15596        return success;
15597    }
15598
15599    final void updateOomAdjLocked() {
15600        final ActivityRecord TOP_ACT = resumedAppLocked();
15601        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15602        final long now = SystemClock.uptimeMillis();
15603        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15604        final int N = mLruProcesses.size();
15605
15606        if (false) {
15607            RuntimeException e = new RuntimeException();
15608            e.fillInStackTrace();
15609            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15610        }
15611
15612        mAdjSeq++;
15613        mNewNumServiceProcs = 0;
15614        mNewNumAServiceProcs = 0;
15615
15616        final int emptyProcessLimit;
15617        final int cachedProcessLimit;
15618        if (mProcessLimit <= 0) {
15619            emptyProcessLimit = cachedProcessLimit = 0;
15620        } else if (mProcessLimit == 1) {
15621            emptyProcessLimit = 1;
15622            cachedProcessLimit = 0;
15623        } else {
15624            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15625            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15626        }
15627
15628        // Let's determine how many processes we have running vs.
15629        // how many slots we have for background processes; we may want
15630        // to put multiple processes in a slot of there are enough of
15631        // them.
15632        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15633                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15634        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15635        if (numEmptyProcs > cachedProcessLimit) {
15636            // If there are more empty processes than our limit on cached
15637            // processes, then use the cached process limit for the factor.
15638            // This ensures that the really old empty processes get pushed
15639            // down to the bottom, so if we are running low on memory we will
15640            // have a better chance at keeping around more cached processes
15641            // instead of a gazillion empty processes.
15642            numEmptyProcs = cachedProcessLimit;
15643        }
15644        int emptyFactor = numEmptyProcs/numSlots;
15645        if (emptyFactor < 1) emptyFactor = 1;
15646        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15647        if (cachedFactor < 1) cachedFactor = 1;
15648        int stepCached = 0;
15649        int stepEmpty = 0;
15650        int numCached = 0;
15651        int numEmpty = 0;
15652        int numTrimming = 0;
15653
15654        mNumNonCachedProcs = 0;
15655        mNumCachedHiddenProcs = 0;
15656
15657        // First update the OOM adjustment for each of the
15658        // application processes based on their current state.
15659        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15660        int nextCachedAdj = curCachedAdj+1;
15661        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15662        int nextEmptyAdj = curEmptyAdj+2;
15663        for (int i=N-1; i>=0; i--) {
15664            ProcessRecord app = mLruProcesses.get(i);
15665            if (!app.killedByAm && app.thread != null) {
15666                app.procStateChanged = false;
15667                final boolean wasKeeping = app.keeping;
15668                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15669
15670                // If we haven't yet assigned the final cached adj
15671                // to the process, do that now.
15672                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15673                    switch (app.curProcState) {
15674                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15675                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15676                            // This process is a cached process holding activities...
15677                            // assign it the next cached value for that type, and then
15678                            // step that cached level.
15679                            app.curRawAdj = curCachedAdj;
15680                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15681                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15682                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15683                                    + ")");
15684                            if (curCachedAdj != nextCachedAdj) {
15685                                stepCached++;
15686                                if (stepCached >= cachedFactor) {
15687                                    stepCached = 0;
15688                                    curCachedAdj = nextCachedAdj;
15689                                    nextCachedAdj += 2;
15690                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15691                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15692                                    }
15693                                }
15694                            }
15695                            break;
15696                        default:
15697                            // For everything else, assign next empty cached process
15698                            // level and bump that up.  Note that this means that
15699                            // long-running services that have dropped down to the
15700                            // cached level will be treated as empty (since their process
15701                            // state is still as a service), which is what we want.
15702                            app.curRawAdj = curEmptyAdj;
15703                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15704                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15705                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15706                                    + ")");
15707                            if (curEmptyAdj != nextEmptyAdj) {
15708                                stepEmpty++;
15709                                if (stepEmpty >= emptyFactor) {
15710                                    stepEmpty = 0;
15711                                    curEmptyAdj = nextEmptyAdj;
15712                                    nextEmptyAdj += 2;
15713                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15714                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15715                                    }
15716                                }
15717                            }
15718                            break;
15719                    }
15720                }
15721
15722                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15723
15724                // Count the number of process types.
15725                switch (app.curProcState) {
15726                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15727                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15728                        mNumCachedHiddenProcs++;
15729                        numCached++;
15730                        if (numCached > cachedProcessLimit) {
15731                            killUnneededProcessLocked(app, "cached #" + numCached);
15732                        }
15733                        break;
15734                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15735                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15736                                && app.lastActivityTime < oldTime) {
15737                            killUnneededProcessLocked(app, "empty for "
15738                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15739                                    / 1000) + "s");
15740                        } else {
15741                            numEmpty++;
15742                            if (numEmpty > emptyProcessLimit) {
15743                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15744                            }
15745                        }
15746                        break;
15747                    default:
15748                        mNumNonCachedProcs++;
15749                        break;
15750                }
15751
15752                if (app.isolated && app.services.size() <= 0) {
15753                    // If this is an isolated process, and there are no
15754                    // services running in it, then the process is no longer
15755                    // needed.  We agressively kill these because we can by
15756                    // definition not re-use the same process again, and it is
15757                    // good to avoid having whatever code was running in them
15758                    // left sitting around after no longer needed.
15759                    killUnneededProcessLocked(app, "isolated not needed");
15760                }
15761
15762                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15763                        && !app.killedByAm) {
15764                    numTrimming++;
15765                }
15766            }
15767        }
15768
15769        mNumServiceProcs = mNewNumServiceProcs;
15770
15771        // Now determine the memory trimming level of background processes.
15772        // Unfortunately we need to start at the back of the list to do this
15773        // properly.  We only do this if the number of background apps we
15774        // are managing to keep around is less than half the maximum we desire;
15775        // if we are keeping a good number around, we'll let them use whatever
15776        // memory they want.
15777        final int numCachedAndEmpty = numCached + numEmpty;
15778        int memFactor;
15779        if (numCached <= ProcessList.TRIM_CACHED_APPS
15780                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15781            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15782                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15783            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15784                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15785            } else {
15786                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15787            }
15788        } else {
15789            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15790        }
15791        // We always allow the memory level to go up (better).  We only allow it to go
15792        // down if we are in a state where that is allowed, *and* the total number of processes
15793        // has gone down since last time.
15794        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15795                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15796                + " last=" + mLastNumProcesses);
15797        if (memFactor > mLastMemoryLevel) {
15798            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15799                memFactor = mLastMemoryLevel;
15800                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15801            }
15802        }
15803        mLastMemoryLevel = memFactor;
15804        mLastNumProcesses = mLruProcesses.size();
15805        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15806        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15807        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15808            if (mLowRamStartTime == 0) {
15809                mLowRamStartTime = now;
15810            }
15811            int step = 0;
15812            int fgTrimLevel;
15813            switch (memFactor) {
15814                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15815                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15816                    break;
15817                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15818                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15819                    break;
15820                default:
15821                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15822                    break;
15823            }
15824            int factor = numTrimming/3;
15825            int minFactor = 2;
15826            if (mHomeProcess != null) minFactor++;
15827            if (mPreviousProcess != null) minFactor++;
15828            if (factor < minFactor) factor = minFactor;
15829            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15830            for (int i=N-1; i>=0; i--) {
15831                ProcessRecord app = mLruProcesses.get(i);
15832                if (allChanged || app.procStateChanged) {
15833                    setProcessTrackerState(app, trackerMemFactor, now);
15834                    app.procStateChanged = false;
15835                }
15836                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15837                        && !app.killedByAm) {
15838                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15839                        try {
15840                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15841                                    "Trimming memory of " + app.processName
15842                                    + " to " + curLevel);
15843                            app.thread.scheduleTrimMemory(curLevel);
15844                        } catch (RemoteException e) {
15845                        }
15846                        if (false) {
15847                            // For now we won't do this; our memory trimming seems
15848                            // to be good enough at this point that destroying
15849                            // activities causes more harm than good.
15850                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15851                                    && app != mHomeProcess && app != mPreviousProcess) {
15852                                // Need to do this on its own message because the stack may not
15853                                // be in a consistent state at this point.
15854                                // For these apps we will also finish their activities
15855                                // to help them free memory.
15856                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15857                            }
15858                        }
15859                    }
15860                    app.trimMemoryLevel = curLevel;
15861                    step++;
15862                    if (step >= factor) {
15863                        step = 0;
15864                        switch (curLevel) {
15865                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15866                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15867                                break;
15868                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15869                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15870                                break;
15871                        }
15872                    }
15873                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15874                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15875                            && app.thread != null) {
15876                        try {
15877                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15878                                    "Trimming memory of heavy-weight " + app.processName
15879                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15880                            app.thread.scheduleTrimMemory(
15881                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15882                        } catch (RemoteException e) {
15883                        }
15884                    }
15885                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15886                } else {
15887                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15888                            || app.systemNoUi) && app.pendingUiClean) {
15889                        // If this application is now in the background and it
15890                        // had done UI, then give it the special trim level to
15891                        // have it free UI resources.
15892                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15893                        if (app.trimMemoryLevel < level && app.thread != null) {
15894                            try {
15895                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15896                                        "Trimming memory of bg-ui " + app.processName
15897                                        + " to " + level);
15898                                app.thread.scheduleTrimMemory(level);
15899                            } catch (RemoteException e) {
15900                            }
15901                        }
15902                        app.pendingUiClean = false;
15903                    }
15904                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15905                        try {
15906                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15907                                    "Trimming memory of fg " + app.processName
15908                                    + " to " + fgTrimLevel);
15909                            app.thread.scheduleTrimMemory(fgTrimLevel);
15910                        } catch (RemoteException e) {
15911                        }
15912                    }
15913                    app.trimMemoryLevel = fgTrimLevel;
15914                }
15915            }
15916        } else {
15917            if (mLowRamStartTime != 0) {
15918                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15919                mLowRamStartTime = 0;
15920            }
15921            for (int i=N-1; i>=0; i--) {
15922                ProcessRecord app = mLruProcesses.get(i);
15923                if (allChanged || app.procStateChanged) {
15924                    setProcessTrackerState(app, trackerMemFactor, now);
15925                    app.procStateChanged = false;
15926                }
15927                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15928                        || app.systemNoUi) && app.pendingUiClean) {
15929                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15930                            && app.thread != null) {
15931                        try {
15932                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15933                                    "Trimming memory of ui hidden " + app.processName
15934                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15935                            app.thread.scheduleTrimMemory(
15936                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15937                        } catch (RemoteException e) {
15938                        }
15939                    }
15940                    app.pendingUiClean = false;
15941                }
15942                app.trimMemoryLevel = 0;
15943            }
15944        }
15945
15946        if (mAlwaysFinishActivities) {
15947            // Need to do this on its own message because the stack may not
15948            // be in a consistent state at this point.
15949            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15950        }
15951
15952        if (allChanged) {
15953            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15954        }
15955
15956        if (mProcessStats.shouldWriteNowLocked(now)) {
15957            mHandler.post(new Runnable() {
15958                @Override public void run() {
15959                    synchronized (ActivityManagerService.this) {
15960                        mProcessStats.writeStateAsyncLocked();
15961                    }
15962                }
15963            });
15964        }
15965
15966        if (DEBUG_OOM_ADJ) {
15967            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15968        }
15969    }
15970
15971    final void trimApplications() {
15972        synchronized (this) {
15973            int i;
15974
15975            // First remove any unused application processes whose package
15976            // has been removed.
15977            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15978                final ProcessRecord app = mRemovedProcesses.get(i);
15979                if (app.activities.size() == 0
15980                        && app.curReceiver == null && app.services.size() == 0) {
15981                    Slog.i(
15982                        TAG, "Exiting empty application process "
15983                        + app.processName + " ("
15984                        + (app.thread != null ? app.thread.asBinder() : null)
15985                        + ")\n");
15986                    if (app.pid > 0 && app.pid != MY_PID) {
15987                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15988                                app.processName, app.setAdj, "empty");
15989                        app.killedByAm = true;
15990                        Process.killProcessQuiet(app.pid);
15991                    } else {
15992                        try {
15993                            app.thread.scheduleExit();
15994                        } catch (Exception e) {
15995                            // Ignore exceptions.
15996                        }
15997                    }
15998                    cleanUpApplicationRecordLocked(app, false, true, -1);
15999                    mRemovedProcesses.remove(i);
16000
16001                    if (app.persistent) {
16002                        if (app.persistent) {
16003                            addAppLocked(app.info, false);
16004                        }
16005                    }
16006                }
16007            }
16008
16009            // Now update the oom adj for all processes.
16010            updateOomAdjLocked();
16011        }
16012    }
16013
16014    /** This method sends the specified signal to each of the persistent apps */
16015    public void signalPersistentProcesses(int sig) throws RemoteException {
16016        if (sig != Process.SIGNAL_USR1) {
16017            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16018        }
16019
16020        synchronized (this) {
16021            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16022                    != PackageManager.PERMISSION_GRANTED) {
16023                throw new SecurityException("Requires permission "
16024                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16025            }
16026
16027            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16028                ProcessRecord r = mLruProcesses.get(i);
16029                if (r.thread != null && r.persistent) {
16030                    Process.sendSignal(r.pid, sig);
16031                }
16032            }
16033        }
16034    }
16035
16036    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16037        if (proc == null || proc == mProfileProc) {
16038            proc = mProfileProc;
16039            path = mProfileFile;
16040            profileType = mProfileType;
16041            clearProfilerLocked();
16042        }
16043        if (proc == null) {
16044            return;
16045        }
16046        try {
16047            proc.thread.profilerControl(false, path, null, profileType);
16048        } catch (RemoteException e) {
16049            throw new IllegalStateException("Process disappeared");
16050        }
16051    }
16052
16053    private void clearProfilerLocked() {
16054        if (mProfileFd != null) {
16055            try {
16056                mProfileFd.close();
16057            } catch (IOException e) {
16058            }
16059        }
16060        mProfileApp = null;
16061        mProfileProc = null;
16062        mProfileFile = null;
16063        mProfileType = 0;
16064        mAutoStopProfiler = false;
16065    }
16066
16067    public boolean profileControl(String process, int userId, boolean start,
16068            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16069
16070        try {
16071            synchronized (this) {
16072                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16073                // its own permission.
16074                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16075                        != PackageManager.PERMISSION_GRANTED) {
16076                    throw new SecurityException("Requires permission "
16077                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16078                }
16079
16080                if (start && fd == null) {
16081                    throw new IllegalArgumentException("null fd");
16082                }
16083
16084                ProcessRecord proc = null;
16085                if (process != null) {
16086                    proc = findProcessLocked(process, userId, "profileControl");
16087                }
16088
16089                if (start && (proc == null || proc.thread == null)) {
16090                    throw new IllegalArgumentException("Unknown process: " + process);
16091                }
16092
16093                if (start) {
16094                    stopProfilerLocked(null, null, 0);
16095                    setProfileApp(proc.info, proc.processName, path, fd, false);
16096                    mProfileProc = proc;
16097                    mProfileType = profileType;
16098                    try {
16099                        fd = fd.dup();
16100                    } catch (IOException e) {
16101                        fd = null;
16102                    }
16103                    proc.thread.profilerControl(start, path, fd, profileType);
16104                    fd = null;
16105                    mProfileFd = null;
16106                } else {
16107                    stopProfilerLocked(proc, path, profileType);
16108                    if (fd != null) {
16109                        try {
16110                            fd.close();
16111                        } catch (IOException e) {
16112                        }
16113                    }
16114                }
16115
16116                return true;
16117            }
16118        } catch (RemoteException e) {
16119            throw new IllegalStateException("Process disappeared");
16120        } finally {
16121            if (fd != null) {
16122                try {
16123                    fd.close();
16124                } catch (IOException e) {
16125                }
16126            }
16127        }
16128    }
16129
16130    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16131        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16132                userId, true, true, callName, null);
16133        ProcessRecord proc = null;
16134        try {
16135            int pid = Integer.parseInt(process);
16136            synchronized (mPidsSelfLocked) {
16137                proc = mPidsSelfLocked.get(pid);
16138            }
16139        } catch (NumberFormatException e) {
16140        }
16141
16142        if (proc == null) {
16143            ArrayMap<String, SparseArray<ProcessRecord>> all
16144                    = mProcessNames.getMap();
16145            SparseArray<ProcessRecord> procs = all.get(process);
16146            if (procs != null && procs.size() > 0) {
16147                proc = procs.valueAt(0);
16148                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16149                    for (int i=1; i<procs.size(); i++) {
16150                        ProcessRecord thisProc = procs.valueAt(i);
16151                        if (thisProc.userId == userId) {
16152                            proc = thisProc;
16153                            break;
16154                        }
16155                    }
16156                }
16157            }
16158        }
16159
16160        return proc;
16161    }
16162
16163    public boolean dumpHeap(String process, int userId, boolean managed,
16164            String path, ParcelFileDescriptor fd) throws RemoteException {
16165
16166        try {
16167            synchronized (this) {
16168                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16169                // its own permission (same as profileControl).
16170                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16171                        != PackageManager.PERMISSION_GRANTED) {
16172                    throw new SecurityException("Requires permission "
16173                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16174                }
16175
16176                if (fd == null) {
16177                    throw new IllegalArgumentException("null fd");
16178                }
16179
16180                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16181                if (proc == null || proc.thread == null) {
16182                    throw new IllegalArgumentException("Unknown process: " + process);
16183                }
16184
16185                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16186                if (!isDebuggable) {
16187                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16188                        throw new SecurityException("Process not debuggable: " + proc);
16189                    }
16190                }
16191
16192                proc.thread.dumpHeap(managed, path, fd);
16193                fd = null;
16194                return true;
16195            }
16196        } catch (RemoteException e) {
16197            throw new IllegalStateException("Process disappeared");
16198        } finally {
16199            if (fd != null) {
16200                try {
16201                    fd.close();
16202                } catch (IOException e) {
16203                }
16204            }
16205        }
16206    }
16207
16208    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16209    public void monitor() {
16210        synchronized (this) { }
16211    }
16212
16213    void onCoreSettingsChange(Bundle settings) {
16214        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16215            ProcessRecord processRecord = mLruProcesses.get(i);
16216            try {
16217                if (processRecord.thread != null) {
16218                    processRecord.thread.setCoreSettings(settings);
16219                }
16220            } catch (RemoteException re) {
16221                /* ignore */
16222            }
16223        }
16224    }
16225
16226    // Multi-user methods
16227
16228    /**
16229     * Start user, if its not already running, but don't bring it to foreground.
16230     */
16231    @Override
16232    public boolean startUserInBackground(final int userId) {
16233        return startUser(userId, /* foreground */ false);
16234    }
16235
16236    /**
16237     * Refreshes the list of users related to the current user when either a
16238     * user switch happens or when a new related user is started in the
16239     * background.
16240     */
16241    private void updateRelatedUserIdsLocked() {
16242        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16243        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16244        for (int i = 0; i < relatedUserIds.length; i++) {
16245            relatedUserIds[i] = relatedUsers.get(i).id;
16246        }
16247        mRelatedUserIds = relatedUserIds;
16248    }
16249
16250    @Override
16251    public boolean switchUser(final int userId) {
16252        return startUser(userId, /* foregound */ true);
16253    }
16254
16255    private boolean startUser(final int userId, boolean foreground) {
16256        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16257                != PackageManager.PERMISSION_GRANTED) {
16258            String msg = "Permission Denial: switchUser() from pid="
16259                    + Binder.getCallingPid()
16260                    + ", uid=" + Binder.getCallingUid()
16261                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16262            Slog.w(TAG, msg);
16263            throw new SecurityException(msg);
16264        }
16265
16266        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16267
16268        final long ident = Binder.clearCallingIdentity();
16269        try {
16270            synchronized (this) {
16271                final int oldUserId = mCurrentUserId;
16272                if (oldUserId == userId) {
16273                    return true;
16274                }
16275
16276                mStackSupervisor.setLockTaskModeLocked(null);
16277
16278                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16279                if (userInfo == null) {
16280                    Slog.w(TAG, "No user info for user #" + userId);
16281                    return false;
16282                }
16283
16284                if (foreground) {
16285                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16286                            R.anim.screen_user_enter);
16287                }
16288
16289                boolean needStart = false;
16290
16291                // If the user we are switching to is not currently started, then
16292                // we need to start it now.
16293                if (mStartedUsers.get(userId) == null) {
16294                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16295                    updateStartedUserArrayLocked();
16296                    needStart = true;
16297                }
16298
16299                final Integer userIdInt = Integer.valueOf(userId);
16300                mUserLru.remove(userIdInt);
16301                mUserLru.add(userIdInt);
16302
16303                if (foreground) {
16304                    mCurrentUserId = userId;
16305                    updateRelatedUserIdsLocked();
16306                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16307                    // Once the internal notion of the active user has switched, we lock the device
16308                    // with the option to show the user switcher on the keyguard.
16309                    mWindowManager.lockNow(null);
16310                } else {
16311                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16312                    updateRelatedUserIdsLocked();
16313                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16314                    mUserLru.remove(currentUserIdInt);
16315                    mUserLru.add(currentUserIdInt);
16316                }
16317
16318                final UserStartedState uss = mStartedUsers.get(userId);
16319
16320                // Make sure user is in the started state.  If it is currently
16321                // stopping, we need to knock that off.
16322                if (uss.mState == UserStartedState.STATE_STOPPING) {
16323                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16324                    // so we can just fairly silently bring the user back from
16325                    // the almost-dead.
16326                    uss.mState = UserStartedState.STATE_RUNNING;
16327                    updateStartedUserArrayLocked();
16328                    needStart = true;
16329                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16330                    // This means ACTION_SHUTDOWN has been sent, so we will
16331                    // need to treat this as a new boot of the user.
16332                    uss.mState = UserStartedState.STATE_BOOTING;
16333                    updateStartedUserArrayLocked();
16334                    needStart = true;
16335                }
16336
16337                if (foreground) {
16338                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16339                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16340                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16341                            oldUserId, userId, uss));
16342                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16343                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16344                }
16345
16346                if (needStart) {
16347                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16348                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16349                            | Intent.FLAG_RECEIVER_FOREGROUND);
16350                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16351                    broadcastIntentLocked(null, null, intent,
16352                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16353                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16354                }
16355
16356                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16357                    if (userId != 0) {
16358                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16359                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16360                        broadcastIntentLocked(null, null, intent, null,
16361                                new IIntentReceiver.Stub() {
16362                                    public void performReceive(Intent intent, int resultCode,
16363                                            String data, Bundle extras, boolean ordered,
16364                                            boolean sticky, int sendingUser) {
16365                                        userInitialized(uss, userId);
16366                                    }
16367                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16368                                true, false, MY_PID, Process.SYSTEM_UID,
16369                                userId);
16370                        uss.initializing = true;
16371                    } else {
16372                        getUserManagerLocked().makeInitialized(userInfo.id);
16373                    }
16374                }
16375
16376                if (foreground) {
16377                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16378                    if (homeInFront) {
16379                        startHomeActivityLocked(userId);
16380                    } else {
16381                        mStackSupervisor.resumeTopActivitiesLocked();
16382                    }
16383                    EventLogTags.writeAmSwitchUser(userId);
16384                    getUserManagerLocked().userForeground(userId);
16385                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16386                }
16387
16388                if (needStart) {
16389                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16390                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16391                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16392                    broadcastIntentLocked(null, null, intent,
16393                            null, new IIntentReceiver.Stub() {
16394                                @Override
16395                                public void performReceive(Intent intent, int resultCode, String data,
16396                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16397                                        throws RemoteException {
16398                                }
16399                            }, 0, null, null,
16400                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16401                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16402                }
16403            }
16404        } finally {
16405            Binder.restoreCallingIdentity(ident);
16406        }
16407
16408        return true;
16409    }
16410
16411    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16412        long ident = Binder.clearCallingIdentity();
16413        try {
16414            Intent intent;
16415            if (oldUserId >= 0) {
16416                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16417                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16418                        | Intent.FLAG_RECEIVER_FOREGROUND);
16419                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16420                broadcastIntentLocked(null, null, intent,
16421                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16422                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16423            }
16424            if (newUserId >= 0) {
16425                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16426                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16427                        | Intent.FLAG_RECEIVER_FOREGROUND);
16428                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16429                broadcastIntentLocked(null, null, intent,
16430                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16431                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16432                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16433                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16434                        | Intent.FLAG_RECEIVER_FOREGROUND);
16435                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16436                broadcastIntentLocked(null, null, intent,
16437                        null, null, 0, null, null,
16438                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16439                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16440            }
16441        } finally {
16442            Binder.restoreCallingIdentity(ident);
16443        }
16444    }
16445
16446    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16447            final int newUserId) {
16448        final int N = mUserSwitchObservers.beginBroadcast();
16449        if (N > 0) {
16450            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16451                int mCount = 0;
16452                @Override
16453                public void sendResult(Bundle data) throws RemoteException {
16454                    synchronized (ActivityManagerService.this) {
16455                        if (mCurUserSwitchCallback == this) {
16456                            mCount++;
16457                            if (mCount == N) {
16458                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16459                            }
16460                        }
16461                    }
16462                }
16463            };
16464            synchronized (this) {
16465                uss.switching = true;
16466                mCurUserSwitchCallback = callback;
16467            }
16468            for (int i=0; i<N; i++) {
16469                try {
16470                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16471                            newUserId, callback);
16472                } catch (RemoteException e) {
16473                }
16474            }
16475        } else {
16476            synchronized (this) {
16477                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16478            }
16479        }
16480        mUserSwitchObservers.finishBroadcast();
16481    }
16482
16483    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16484        synchronized (this) {
16485            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16486            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16487        }
16488    }
16489
16490    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16491        mCurUserSwitchCallback = null;
16492        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16493        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16494                oldUserId, newUserId, uss));
16495    }
16496
16497    void userInitialized(UserStartedState uss, int newUserId) {
16498        completeSwitchAndInitalize(uss, newUserId, true, false);
16499    }
16500
16501    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16502        completeSwitchAndInitalize(uss, newUserId, false, true);
16503    }
16504
16505    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16506            boolean clearInitializing, boolean clearSwitching) {
16507        boolean unfrozen = false;
16508        synchronized (this) {
16509            if (clearInitializing) {
16510                uss.initializing = false;
16511                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16512            }
16513            if (clearSwitching) {
16514                uss.switching = false;
16515            }
16516            if (!uss.switching && !uss.initializing) {
16517                mWindowManager.stopFreezingScreen();
16518                unfrozen = true;
16519            }
16520        }
16521        if (unfrozen) {
16522            final int N = mUserSwitchObservers.beginBroadcast();
16523            for (int i=0; i<N; i++) {
16524                try {
16525                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16526                } catch (RemoteException e) {
16527                }
16528            }
16529            mUserSwitchObservers.finishBroadcast();
16530        }
16531    }
16532
16533    void scheduleStartRelatedUsersLocked() {
16534        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16535            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16536                    DateUtils.SECOND_IN_MILLIS);
16537        }
16538    }
16539
16540    void startRelatedUsersLocked() {
16541        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16542        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16543        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16544        for (UserInfo relatedUser : relatedUsers) {
16545            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16546                toStart.add(relatedUser);
16547            }
16548        }
16549        final int n = toStart.size();
16550        int i = 0;
16551        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16552            startUserInBackground(toStart.get(i).id);
16553        }
16554        if (i < n) {
16555            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16556        }
16557    }
16558
16559    void finishUserSwitch(UserStartedState uss) {
16560        synchronized (this) {
16561            if (uss.mState == UserStartedState.STATE_BOOTING
16562                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16563                uss.mState = UserStartedState.STATE_RUNNING;
16564                final int userId = uss.mHandle.getIdentifier();
16565                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16566                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16567                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16568                broadcastIntentLocked(null, null, intent,
16569                        null, null, 0, null, null,
16570                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16571                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16572            }
16573
16574            startRelatedUsersLocked();
16575
16576            int num = mUserLru.size();
16577            int i = 0;
16578            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16579                Integer oldUserId = mUserLru.get(i);
16580                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16581                if (oldUss == null) {
16582                    // Shouldn't happen, but be sane if it does.
16583                    mUserLru.remove(i);
16584                    num--;
16585                    continue;
16586                }
16587                if (oldUss.mState == UserStartedState.STATE_STOPPING
16588                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16589                    // This user is already stopping, doesn't count.
16590                    num--;
16591                    i++;
16592                    continue;
16593                }
16594                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16595                    // Owner and current can't be stopped, but count as running.
16596                    i++;
16597                    continue;
16598                }
16599                // This is a user to be stopped.
16600                stopUserLocked(oldUserId, null);
16601                num--;
16602                i++;
16603            }
16604        }
16605    }
16606
16607    @Override
16608    public int stopUser(final int userId, final IStopUserCallback callback) {
16609        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16610                != PackageManager.PERMISSION_GRANTED) {
16611            String msg = "Permission Denial: switchUser() from pid="
16612                    + Binder.getCallingPid()
16613                    + ", uid=" + Binder.getCallingUid()
16614                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16615            Slog.w(TAG, msg);
16616            throw new SecurityException(msg);
16617        }
16618        if (userId <= 0) {
16619            throw new IllegalArgumentException("Can't stop primary user " + userId);
16620        }
16621        synchronized (this) {
16622            return stopUserLocked(userId, callback);
16623        }
16624    }
16625
16626    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16627        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16628        if (mCurrentUserId == userId) {
16629            return ActivityManager.USER_OP_IS_CURRENT;
16630        }
16631
16632        final UserStartedState uss = mStartedUsers.get(userId);
16633        if (uss == null) {
16634            // User is not started, nothing to do...  but we do need to
16635            // callback if requested.
16636            if (callback != null) {
16637                mHandler.post(new Runnable() {
16638                    @Override
16639                    public void run() {
16640                        try {
16641                            callback.userStopped(userId);
16642                        } catch (RemoteException e) {
16643                        }
16644                    }
16645                });
16646            }
16647            return ActivityManager.USER_OP_SUCCESS;
16648        }
16649
16650        if (callback != null) {
16651            uss.mStopCallbacks.add(callback);
16652        }
16653
16654        if (uss.mState != UserStartedState.STATE_STOPPING
16655                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16656            uss.mState = UserStartedState.STATE_STOPPING;
16657            updateStartedUserArrayLocked();
16658
16659            long ident = Binder.clearCallingIdentity();
16660            try {
16661                // We are going to broadcast ACTION_USER_STOPPING and then
16662                // once that is done send a final ACTION_SHUTDOWN and then
16663                // stop the user.
16664                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16665                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16666                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16667                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16668                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16669                // This is the result receiver for the final shutdown broadcast.
16670                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16671                    @Override
16672                    public void performReceive(Intent intent, int resultCode, String data,
16673                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16674                        finishUserStop(uss);
16675                    }
16676                };
16677                // This is the result receiver for the initial stopping broadcast.
16678                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16679                    @Override
16680                    public void performReceive(Intent intent, int resultCode, String data,
16681                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16682                        // On to the next.
16683                        synchronized (ActivityManagerService.this) {
16684                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16685                                // Whoops, we are being started back up.  Abort, abort!
16686                                return;
16687                            }
16688                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16689                        }
16690                        broadcastIntentLocked(null, null, shutdownIntent,
16691                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16692                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16693                    }
16694                };
16695                // Kick things off.
16696                broadcastIntentLocked(null, null, stoppingIntent,
16697                        null, stoppingReceiver, 0, null, null,
16698                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16699                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16700            } finally {
16701                Binder.restoreCallingIdentity(ident);
16702            }
16703        }
16704
16705        return ActivityManager.USER_OP_SUCCESS;
16706    }
16707
16708    void finishUserStop(UserStartedState uss) {
16709        final int userId = uss.mHandle.getIdentifier();
16710        boolean stopped;
16711        ArrayList<IStopUserCallback> callbacks;
16712        synchronized (this) {
16713            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16714            if (mStartedUsers.get(userId) != uss) {
16715                stopped = false;
16716            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16717                stopped = false;
16718            } else {
16719                stopped = true;
16720                // User can no longer run.
16721                mStartedUsers.remove(userId);
16722                mUserLru.remove(Integer.valueOf(userId));
16723                updateStartedUserArrayLocked();
16724
16725                // Clean up all state and processes associated with the user.
16726                // Kill all the processes for the user.
16727                forceStopUserLocked(userId, "finish user");
16728            }
16729        }
16730
16731        for (int i=0; i<callbacks.size(); i++) {
16732            try {
16733                if (stopped) callbacks.get(i).userStopped(userId);
16734                else callbacks.get(i).userStopAborted(userId);
16735            } catch (RemoteException e) {
16736            }
16737        }
16738
16739        mStackSupervisor.removeUserLocked(userId);
16740    }
16741
16742    @Override
16743    public UserInfo getCurrentUser() {
16744        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16745                != PackageManager.PERMISSION_GRANTED) && (
16746                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16747                != PackageManager.PERMISSION_GRANTED)) {
16748            String msg = "Permission Denial: getCurrentUser() from pid="
16749                    + Binder.getCallingPid()
16750                    + ", uid=" + Binder.getCallingUid()
16751                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16752            Slog.w(TAG, msg);
16753            throw new SecurityException(msg);
16754        }
16755        synchronized (this) {
16756            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16757        }
16758    }
16759
16760    int getCurrentUserIdLocked() {
16761        return mCurrentUserId;
16762    }
16763
16764    @Override
16765    public boolean isUserRunning(int userId, boolean orStopped) {
16766        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16767                != PackageManager.PERMISSION_GRANTED) {
16768            String msg = "Permission Denial: isUserRunning() from pid="
16769                    + Binder.getCallingPid()
16770                    + ", uid=" + Binder.getCallingUid()
16771                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16772            Slog.w(TAG, msg);
16773            throw new SecurityException(msg);
16774        }
16775        synchronized (this) {
16776            return isUserRunningLocked(userId, orStopped);
16777        }
16778    }
16779
16780    boolean isUserRunningLocked(int userId, boolean orStopped) {
16781        UserStartedState state = mStartedUsers.get(userId);
16782        if (state == null) {
16783            return false;
16784        }
16785        if (orStopped) {
16786            return true;
16787        }
16788        return state.mState != UserStartedState.STATE_STOPPING
16789                && state.mState != UserStartedState.STATE_SHUTDOWN;
16790    }
16791
16792    @Override
16793    public int[] getRunningUserIds() {
16794        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16795                != PackageManager.PERMISSION_GRANTED) {
16796            String msg = "Permission Denial: isUserRunning() from pid="
16797                    + Binder.getCallingPid()
16798                    + ", uid=" + Binder.getCallingUid()
16799                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16800            Slog.w(TAG, msg);
16801            throw new SecurityException(msg);
16802        }
16803        synchronized (this) {
16804            return mStartedUserArray;
16805        }
16806    }
16807
16808    private void updateStartedUserArrayLocked() {
16809        int num = 0;
16810        for (int i=0; i<mStartedUsers.size();  i++) {
16811            UserStartedState uss = mStartedUsers.valueAt(i);
16812            // This list does not include stopping users.
16813            if (uss.mState != UserStartedState.STATE_STOPPING
16814                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16815                num++;
16816            }
16817        }
16818        mStartedUserArray = new int[num];
16819        num = 0;
16820        for (int i=0; i<mStartedUsers.size();  i++) {
16821            UserStartedState uss = mStartedUsers.valueAt(i);
16822            if (uss.mState != UserStartedState.STATE_STOPPING
16823                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16824                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16825                num++;
16826            }
16827        }
16828    }
16829
16830    @Override
16831    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16832        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16833                != PackageManager.PERMISSION_GRANTED) {
16834            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16835                    + Binder.getCallingPid()
16836                    + ", uid=" + Binder.getCallingUid()
16837                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16838            Slog.w(TAG, msg);
16839            throw new SecurityException(msg);
16840        }
16841
16842        mUserSwitchObservers.register(observer);
16843    }
16844
16845    @Override
16846    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16847        mUserSwitchObservers.unregister(observer);
16848    }
16849
16850    private boolean userExists(int userId) {
16851        if (userId == 0) {
16852            return true;
16853        }
16854        UserManagerService ums = getUserManagerLocked();
16855        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16856    }
16857
16858    int[] getUsersLocked() {
16859        UserManagerService ums = getUserManagerLocked();
16860        return ums != null ? ums.getUserIds() : new int[] { 0 };
16861    }
16862
16863    UserManagerService getUserManagerLocked() {
16864        if (mUserManager == null) {
16865            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16866            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16867        }
16868        return mUserManager;
16869    }
16870
16871    private int applyUserId(int uid, int userId) {
16872        return UserHandle.getUid(userId, uid);
16873    }
16874
16875    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16876        if (info == null) return null;
16877        ApplicationInfo newInfo = new ApplicationInfo(info);
16878        newInfo.uid = applyUserId(info.uid, userId);
16879        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16880                + info.packageName;
16881        return newInfo;
16882    }
16883
16884    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16885        if (aInfo == null
16886                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16887            return aInfo;
16888        }
16889
16890        ActivityInfo info = new ActivityInfo(aInfo);
16891        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16892        return info;
16893    }
16894}
16895