ActivityManagerService.java revision f4824a06884e096beef921646cba4be29d7f36fc
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.os.Zygote;
47import com.android.internal.util.FastPrintWriter;
48import com.android.internal.util.FastXmlSerializer;
49import com.android.internal.util.MemInfoReader;
50import com.android.internal.util.Preconditions;
51import com.android.server.AppOpsService;
52import com.android.server.AttributeCache;
53import com.android.server.IntentResolver;
54import com.android.server.ServiceThread;
55import com.android.server.SystemService;
56import com.android.server.Watchdog;
57import com.android.server.am.ActivityStack.ActivityState;
58import com.android.server.firewall.IntentFirewall;
59import com.android.server.pm.UserManagerService;
60import com.android.server.wm.AppTransition;
61import com.android.server.wm.WindowManagerService;
62import com.google.android.collect.Lists;
63import com.google.android.collect.Maps;
64
65import libcore.io.IoUtils;
66
67import org.xmlpull.v1.XmlPullParser;
68import org.xmlpull.v1.XmlPullParserException;
69import org.xmlpull.v1.XmlSerializer;
70
71import android.app.Activity;
72import android.app.ActivityManager;
73import android.app.ActivityManager.RunningTaskInfo;
74import android.app.ActivityManager.StackInfo;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.ApplicationErrorReport;
81import android.app.Dialog;
82import android.app.IActivityController;
83import android.app.IApplicationThread;
84import android.app.IInstrumentationWatcher;
85import android.app.INotificationManager;
86import android.app.IProcessObserver;
87import android.app.IServiceConnection;
88import android.app.IStopUserCallback;
89import android.app.IThumbnailReceiver;
90import android.app.IUiAutomationConnection;
91import android.app.IUserSwitchObserver;
92import android.app.Instrumentation;
93import android.app.Notification;
94import android.app.NotificationManager;
95import android.app.PendingIntent;
96import android.app.backup.IBackupManager;
97import android.content.ActivityNotFoundException;
98import android.content.BroadcastReceiver;
99import android.content.ClipData;
100import android.content.ComponentCallbacks2;
101import android.content.ComponentName;
102import android.content.ContentProvider;
103import android.content.ContentResolver;
104import android.content.Context;
105import android.content.DialogInterface;
106import android.content.IContentProvider;
107import android.content.IIntentReceiver;
108import android.content.IIntentSender;
109import android.content.Intent;
110import android.content.IntentFilter;
111import android.content.IntentSender;
112import android.content.pm.ActivityInfo;
113import android.content.pm.ApplicationInfo;
114import android.content.pm.ConfigurationInfo;
115import android.content.pm.IPackageDataObserver;
116import android.content.pm.IPackageManager;
117import android.content.pm.InstrumentationInfo;
118import android.content.pm.PackageInfo;
119import android.content.pm.PackageManager;
120import android.content.pm.ParceledListSlice;
121import android.content.pm.UserInfo;
122import android.content.pm.PackageManager.NameNotFoundException;
123import android.content.pm.PathPermission;
124import android.content.pm.ProviderInfo;
125import android.content.pm.ResolveInfo;
126import android.content.pm.ServiceInfo;
127import android.content.res.CompatibilityInfo;
128import android.content.res.Configuration;
129import android.graphics.Bitmap;
130import android.net.Proxy;
131import android.net.ProxyProperties;
132import android.net.Uri;
133import android.os.Binder;
134import android.os.Build;
135import android.os.Bundle;
136import android.os.Debug;
137import android.os.DropBoxManager;
138import android.os.Environment;
139import android.os.FactoryTest;
140import android.os.FileObserver;
141import android.os.FileUtils;
142import android.os.Handler;
143import android.os.IBinder;
144import android.os.IPermissionController;
145import android.os.IRemoteCallback;
146import android.os.IUserManager;
147import android.os.Looper;
148import android.os.Message;
149import android.os.Parcel;
150import android.os.ParcelFileDescriptor;
151import android.os.Process;
152import android.os.RemoteCallbackList;
153import android.os.RemoteException;
154import android.os.SELinux;
155import android.os.ServiceManager;
156import android.os.StrictMode;
157import android.os.SystemClock;
158import android.os.SystemProperties;
159import android.os.UpdateLock;
160import android.os.UserHandle;
161import android.provider.Settings;
162import android.text.format.DateUtils;
163import android.text.format.Time;
164import android.util.AtomicFile;
165import android.util.EventLog;
166import android.util.Log;
167import android.util.Pair;
168import android.util.PrintWriterPrinter;
169import android.util.Slog;
170import android.util.SparseArray;
171import android.util.TimeUtils;
172import android.util.Xml;
173import android.view.Gravity;
174import android.view.LayoutInflater;
175import android.view.View;
176import android.view.WindowManager;
177
178import java.io.BufferedInputStream;
179import java.io.BufferedOutputStream;
180import java.io.DataInputStream;
181import java.io.DataOutputStream;
182import java.io.File;
183import java.io.FileDescriptor;
184import java.io.FileInputStream;
185import java.io.FileNotFoundException;
186import java.io.FileOutputStream;
187import java.io.IOException;
188import java.io.InputStreamReader;
189import java.io.PrintWriter;
190import java.io.StringWriter;
191import java.lang.ref.WeakReference;
192import java.util.ArrayList;
193import java.util.Arrays;
194import java.util.Collections;
195import java.util.Comparator;
196import java.util.HashMap;
197import java.util.HashSet;
198import java.util.Iterator;
199import java.util.List;
200import java.util.Locale;
201import java.util.Map;
202import java.util.Set;
203import java.util.concurrent.atomic.AtomicBoolean;
204import java.util.concurrent.atomic.AtomicLong;
205
206public final class ActivityManagerService extends ActivityManagerNative
207        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
208    private static final String USER_DATA_DIR = "/data/user/";
209    static final String TAG = "ActivityManager";
210    static final String TAG_MU = "ActivityManagerServiceMU";
211    static final boolean DEBUG = false;
212    static final boolean localLOGV = DEBUG;
213    static final boolean DEBUG_BACKUP = localLOGV || false;
214    static final boolean DEBUG_BROADCAST = localLOGV || false;
215    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
216    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_CLEANUP = localLOGV || false;
218    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
219    static final boolean DEBUG_FOCUS = false;
220    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
221    static final boolean DEBUG_MU = localLOGV || false;
222    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
223    static final boolean DEBUG_LRU = localLOGV || false;
224    static final boolean DEBUG_PAUSE = localLOGV || false;
225    static final boolean DEBUG_POWER = localLOGV || false;
226    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
227    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
228    static final boolean DEBUG_PROCESSES = localLOGV || false;
229    static final boolean DEBUG_PROVIDER = localLOGV || false;
230    static final boolean DEBUG_RESULTS = localLOGV || false;
231    static final boolean DEBUG_SERVICE = localLOGV || false;
232    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
233    static final boolean DEBUG_STACK = localLOGV || false;
234    static final boolean DEBUG_SWITCH = localLOGV || false;
235    static final boolean DEBUG_TASKS = localLOGV || false;
236    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
237    static final boolean DEBUG_TRANSITION = localLOGV || false;
238    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
239    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
240    static final boolean DEBUG_VISBILITY = localLOGV || false;
241    static final boolean DEBUG_PSS = localLOGV || false;
242    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
243    static final boolean VALIDATE_TOKENS = false;
244    static final boolean SHOW_ACTIVITY_START_TIME = true;
245
246    // Control over CPU and battery monitoring.
247    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
248    static final boolean MONITOR_CPU_USAGE = true;
249    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
250    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
251    static final boolean MONITOR_THREAD_CPU_USAGE = false;
252
253    // The flags that are set for all calls we make to the package manager.
254    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
255
256    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
257
258    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
259
260    // Maximum number of recent tasks that we can remember.
261    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
262
263    // Amount of time after a call to stopAppSwitches() during which we will
264    // prevent further untrusted switches from happening.
265    static final long APP_SWITCH_DELAY_TIME = 5*1000;
266
267    // How long we wait for a launched process to attach to the activity manager
268    // before we decide it's never going to come up for real.
269    static final int PROC_START_TIMEOUT = 10*1000;
270
271    // How long we wait for a launched process to attach to the activity manager
272    // before we decide it's never going to come up for real, when the process was
273    // started with a wrapper for instrumentation (such as Valgrind) because it
274    // could take much longer than usual.
275    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
276
277    // How long to wait after going idle before forcing apps to GC.
278    static final int GC_TIMEOUT = 5*1000;
279
280    // The minimum amount of time between successive GC requests for a process.
281    static final int GC_MIN_INTERVAL = 60*1000;
282
283    // The minimum amount of time between successive PSS requests for a process.
284    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
285
286    // The minimum amount of time between successive PSS requests for a process
287    // when the request is due to the memory state being lowered.
288    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
289
290    // The rate at which we check for apps using excessive power -- 15 mins.
291    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
292
293    // The minimum sample duration we will allow before deciding we have
294    // enough data on wake locks to start killing things.
295    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
296
297    // The minimum sample duration we will allow before deciding we have
298    // enough data on CPU usage to start killing things.
299    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
300
301    // How long we allow a receiver to run before giving up on it.
302    static final int BROADCAST_FG_TIMEOUT = 10*1000;
303    static final int BROADCAST_BG_TIMEOUT = 60*1000;
304
305    // How long we wait until we timeout on key dispatching.
306    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
307
308    // How long we wait until we timeout on key dispatching during instrumentation.
309    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
310
311    // Amount of time we wait for observers to handle a user switch before
312    // giving up on them and unfreezing the screen.
313    static final int USER_SWITCH_TIMEOUT = 2*1000;
314
315    // Maximum number of users we allow to be running at a time.
316    static final int MAX_RUNNING_USERS = 3;
317
318    // How long to wait in getAssistContextExtras for the activity and foreground services
319    // to respond with the result.
320    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
321
322    // Maximum number of persisted Uri grants a package is allowed
323    static final int MAX_PERSISTED_URI_GRANTS = 128;
324
325    static final int MY_PID = Process.myPid();
326
327    static final String[] EMPTY_STRING_ARRAY = new String[0];
328
329    // How many bytes to write into the dropbox log before truncating
330    static final int DROPBOX_MAX_SIZE = 256 * 1024;
331
332    /** Run all ActivityStacks through this */
333    ActivityStackSupervisor mStackSupervisor;
334
335    public IntentFirewall mIntentFirewall;
336
337    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
338    // default actuion automatically.  Important for devices without direct input
339    // devices.
340    private boolean mShowDialogs = true;
341
342    /**
343     * Description of a request to start a new activity, which has been held
344     * due to app switches being disabled.
345     */
346    static class PendingActivityLaunch {
347        final ActivityRecord r;
348        final ActivityRecord sourceRecord;
349        final int startFlags;
350        final ActivityStack stack;
351
352        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
353                int _startFlags, ActivityStack _stack) {
354            r = _r;
355            sourceRecord = _sourceRecord;
356            startFlags = _startFlags;
357            stack = _stack;
358        }
359    }
360
361    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
362            = new ArrayList<PendingActivityLaunch>();
363
364    BroadcastQueue mFgBroadcastQueue;
365    BroadcastQueue mBgBroadcastQueue;
366    // Convenient for easy iteration over the queues. Foreground is first
367    // so that dispatch of foreground broadcasts gets precedence.
368    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
369
370    BroadcastQueue broadcastQueueForIntent(Intent intent) {
371        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
372        if (DEBUG_BACKGROUND_BROADCAST) {
373            Slog.i(TAG, "Broadcast intent " + intent + " on "
374                    + (isFg ? "foreground" : "background")
375                    + " queue");
376        }
377        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
378    }
379
380    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
381        for (BroadcastQueue queue : mBroadcastQueues) {
382            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
383            if (r != null) {
384                return r;
385            }
386        }
387        return null;
388    }
389
390    /**
391     * Activity we have told the window manager to have key focus.
392     */
393    ActivityRecord mFocusedActivity = null;
394
395    /**
396     * List of intents that were used to start the most recent tasks.
397     */
398    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
399
400    public class PendingAssistExtras extends Binder implements Runnable {
401        public final ActivityRecord activity;
402        public boolean haveResult = false;
403        public Bundle result = null;
404        public PendingAssistExtras(ActivityRecord _activity) {
405            activity = _activity;
406        }
407        @Override
408        public void run() {
409            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
410            synchronized (this) {
411                haveResult = true;
412                notifyAll();
413            }
414        }
415    }
416
417    final ArrayList<PendingAssistExtras> mPendingAssistExtras
418            = new ArrayList<PendingAssistExtras>();
419
420    /**
421     * Process management.
422     */
423    final ProcessList mProcessList = new ProcessList();
424
425    /**
426     * All of the applications we currently have running organized by name.
427     * The keys are strings of the application package name (as
428     * returned by the package manager), and the keys are ApplicationRecord
429     * objects.
430     */
431    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
432
433    /**
434     * Tracking long-term execution of processes to look for abuse and other
435     * bad app behavior.
436     */
437    final ProcessStatsService mProcessStats;
438
439    /**
440     * The currently running isolated processes.
441     */
442    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
443
444    /**
445     * Counter for assigning isolated process uids, to avoid frequently reusing the
446     * same ones.
447     */
448    int mNextIsolatedProcessUid = 0;
449
450    /**
451     * The currently running heavy-weight process, if any.
452     */
453    ProcessRecord mHeavyWeightProcess = null;
454
455    /**
456     * The last time that various processes have crashed.
457     */
458    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
459
460    /**
461     * Information about a process that is currently marked as bad.
462     */
463    static final class BadProcessInfo {
464        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
465            this.time = time;
466            this.shortMsg = shortMsg;
467            this.longMsg = longMsg;
468            this.stack = stack;
469        }
470
471        final long time;
472        final String shortMsg;
473        final String longMsg;
474        final String stack;
475    }
476
477    /**
478     * Set of applications that we consider to be bad, and will reject
479     * incoming broadcasts from (which the user has no control over).
480     * Processes are added to this set when they have crashed twice within
481     * a minimum amount of time; they are removed from it when they are
482     * later restarted (hopefully due to some user action).  The value is the
483     * time it was added to the list.
484     */
485    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
486
487    /**
488     * All of the processes we currently have running organized by pid.
489     * The keys are the pid running the application.
490     *
491     * <p>NOTE: This object is protected by its own lock, NOT the global
492     * activity manager lock!
493     */
494    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
495
496    /**
497     * All of the processes that have been forced to be foreground.  The key
498     * is the pid of the caller who requested it (we hold a death
499     * link on it).
500     */
501    abstract class ForegroundToken implements IBinder.DeathRecipient {
502        int pid;
503        IBinder token;
504    }
505    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
506
507    /**
508     * List of records for processes that someone had tried to start before the
509     * system was ready.  We don't start them at that point, but ensure they
510     * are started by the time booting is complete.
511     */
512    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
513
514    /**
515     * List of persistent applications that are in the process
516     * of being started.
517     */
518    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
519
520    /**
521     * Processes that are being forcibly torn down.
522     */
523    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
524
525    /**
526     * List of running applications, sorted by recent usage.
527     * The first entry in the list is the least recently used.
528     */
529    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
530
531    /**
532     * Where in mLruProcesses that the processes hosting activities start.
533     */
534    int mLruProcessActivityStart = 0;
535
536    /**
537     * Where in mLruProcesses that the processes hosting services start.
538     * This is after (lower index) than mLruProcessesActivityStart.
539     */
540    int mLruProcessServiceStart = 0;
541
542    /**
543     * List of processes that should gc as soon as things are idle.
544     */
545    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
546
547    /**
548     * Processes we want to collect PSS data from.
549     */
550    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
551
552    /**
553     * Last time we requested PSS data of all processes.
554     */
555    long mLastFullPssTime = SystemClock.uptimeMillis();
556
557    /**
558     * This is the process holding what we currently consider to be
559     * the "home" activity.
560     */
561    ProcessRecord mHomeProcess;
562
563    /**
564     * This is the process holding the activity the user last visited that
565     * is in a different process from the one they are currently in.
566     */
567    ProcessRecord mPreviousProcess;
568
569    /**
570     * The time at which the previous process was last visible.
571     */
572    long mPreviousProcessVisibleTime;
573
574    /**
575     * Which uses have been started, so are allowed to run code.
576     */
577    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
578
579    /**
580     * LRU list of history of current users.  Most recently current is at the end.
581     */
582    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
583
584    /**
585     * Constant array of the users that are currently started.
586     */
587    int[] mStartedUserArray = new int[] { 0 };
588
589    /**
590     * Registered observers of the user switching mechanics.
591     */
592    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
593            = new RemoteCallbackList<IUserSwitchObserver>();
594
595    /**
596     * Currently active user switch.
597     */
598    Object mCurUserSwitchCallback;
599
600    /**
601     * Packages that the user has asked to have run in screen size
602     * compatibility mode instead of filling the screen.
603     */
604    final CompatModePackages mCompatModePackages;
605
606    /**
607     * Set of IntentSenderRecord objects that are currently active.
608     */
609    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
610            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
611
612    /**
613     * Fingerprints (hashCode()) of stack traces that we've
614     * already logged DropBox entries for.  Guarded by itself.  If
615     * something (rogue user app) forces this over
616     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
617     */
618    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
619    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
620
621    /**
622     * Strict Mode background batched logging state.
623     *
624     * The string buffer is guarded by itself, and its lock is also
625     * used to determine if another batched write is already
626     * in-flight.
627     */
628    private final StringBuilder mStrictModeBuffer = new StringBuilder();
629
630    /**
631     * Keeps track of all IIntentReceivers that have been registered for
632     * broadcasts.  Hash keys are the receiver IBinder, hash value is
633     * a ReceiverList.
634     */
635    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
636            new HashMap<IBinder, ReceiverList>();
637
638    /**
639     * Resolver for broadcast intents to registered receivers.
640     * Holds BroadcastFilter (subclass of IntentFilter).
641     */
642    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
643            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
644        @Override
645        protected boolean allowFilterResult(
646                BroadcastFilter filter, List<BroadcastFilter> dest) {
647            IBinder target = filter.receiverList.receiver.asBinder();
648            for (int i=dest.size()-1; i>=0; i--) {
649                if (dest.get(i).receiverList.receiver.asBinder() == target) {
650                    return false;
651                }
652            }
653            return true;
654        }
655
656        @Override
657        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
658            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
659                    || userId == filter.owningUserId) {
660                return super.newResult(filter, match, userId);
661            }
662            return null;
663        }
664
665        @Override
666        protected BroadcastFilter[] newArray(int size) {
667            return new BroadcastFilter[size];
668        }
669
670        @Override
671        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
672            return packageName.equals(filter.packageName);
673        }
674    };
675
676    /**
677     * State of all active sticky broadcasts per user.  Keys are the action of the
678     * sticky Intent, values are an ArrayList of all broadcasted intents with
679     * that action (which should usually be one).  The SparseArray is keyed
680     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
681     * for stickies that are sent to all users.
682     */
683    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
684            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
685
686    final ActiveServices mServices;
687
688    /**
689     * Backup/restore process management
690     */
691    String mBackupAppName = null;
692    BackupRecord mBackupTarget = null;
693
694    /**
695     * List of PendingThumbnailsRecord objects of clients who are still
696     * waiting to receive all of the thumbnails for a task.
697     */
698    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
699            new ArrayList<PendingThumbnailsRecord>();
700
701    final ProviderMap mProviderMap;
702
703    /**
704     * List of content providers who have clients waiting for them.  The
705     * application is currently being launched and the provider will be
706     * removed from this list once it is published.
707     */
708    final ArrayList<ContentProviderRecord> mLaunchingProviders
709            = new ArrayList<ContentProviderRecord>();
710
711    /**
712     * File storing persisted {@link #mGrantedUriPermissions}.
713     */
714    private final AtomicFile mGrantFile;
715
716    /** XML constants used in {@link #mGrantFile} */
717    private static final String TAG_URI_GRANTS = "uri-grants";
718    private static final String TAG_URI_GRANT = "uri-grant";
719    private static final String ATTR_USER_HANDLE = "userHandle";
720    private static final String ATTR_SOURCE_PKG = "sourcePkg";
721    private static final String ATTR_TARGET_PKG = "targetPkg";
722    private static final String ATTR_URI = "uri";
723    private static final String ATTR_MODE_FLAGS = "modeFlags";
724    private static final String ATTR_CREATED_TIME = "createdTime";
725
726    /**
727     * Global set of specific {@link Uri} permissions that have been granted.
728     * This optimized lookup structure maps from {@link UriPermission#targetUid}
729     * to {@link UriPermission#uri} to {@link UriPermission}.
730     */
731    @GuardedBy("this")
732    private final SparseArray<ArrayMap<Uri, UriPermission>>
733            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
734
735    CoreSettingsObserver mCoreSettingsObserver;
736
737    /**
738     * Thread-local storage used to carry caller permissions over through
739     * indirect content-provider access.
740     */
741    private class Identity {
742        public int pid;
743        public int uid;
744
745        Identity(int _pid, int _uid) {
746            pid = _pid;
747            uid = _uid;
748        }
749    }
750
751    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
752
753    /**
754     * All information we have collected about the runtime performance of
755     * any user id that can impact battery performance.
756     */
757    final BatteryStatsService mBatteryStatsService;
758
759    /**
760     * Information about component usage
761     */
762    final UsageStatsService mUsageStatsService;
763
764    /**
765     * Information about and control over application operations
766     */
767    final AppOpsService mAppOpsService;
768
769    /**
770     * Current configuration information.  HistoryRecord objects are given
771     * a reference to this object to indicate which configuration they are
772     * currently running in, so this object must be kept immutable.
773     */
774    Configuration mConfiguration = new Configuration();
775
776    /**
777     * Current sequencing integer of the configuration, for skipping old
778     * configurations.
779     */
780    int mConfigurationSeq = 0;
781
782    /**
783     * Hardware-reported OpenGLES version.
784     */
785    final int GL_ES_VERSION;
786
787    /**
788     * List of initialization arguments to pass to all processes when binding applications to them.
789     * For example, references to the commonly used services.
790     */
791    HashMap<String, IBinder> mAppBindArgs;
792
793    /**
794     * Temporary to avoid allocations.  Protected by main lock.
795     */
796    final StringBuilder mStringBuilder = new StringBuilder(256);
797
798    /**
799     * Used to control how we initialize the service.
800     */
801    boolean mStartRunning = false;
802    ComponentName mTopComponent;
803    String mTopAction;
804    String mTopData;
805    boolean mProcessesReady = false;
806    boolean mSystemReady = false;
807    boolean mBooting = false;
808    boolean mWaitingUpdate = false;
809    boolean mDidUpdate = false;
810    boolean mOnBattery = false;
811    boolean mLaunchWarningShown = false;
812
813    Context mContext;
814
815    int mFactoryTest;
816
817    boolean mCheckedForSetup;
818
819    /**
820     * The time at which we will allow normal application switches again,
821     * after a call to {@link #stopAppSwitches()}.
822     */
823    long mAppSwitchesAllowedTime;
824
825    /**
826     * This is set to true after the first switch after mAppSwitchesAllowedTime
827     * is set; any switches after that will clear the time.
828     */
829    boolean mDidAppSwitch;
830
831    /**
832     * Last time (in realtime) at which we checked for power usage.
833     */
834    long mLastPowerCheckRealtime;
835
836    /**
837     * Last time (in uptime) at which we checked for power usage.
838     */
839    long mLastPowerCheckUptime;
840
841    /**
842     * Set while we are wanting to sleep, to prevent any
843     * activities from being started/resumed.
844     */
845    boolean mSleeping = false;
846
847    /**
848     * State of external calls telling us if the device is asleep.
849     */
850    boolean mWentToSleep = false;
851
852    /**
853     * State of external call telling us if the lock screen is shown.
854     */
855    boolean mLockScreenShown = false;
856
857    /**
858     * Set if we are shutting down the system, similar to sleeping.
859     */
860    boolean mShuttingDown = false;
861
862    /**
863     * Current sequence id for oom_adj computation traversal.
864     */
865    int mAdjSeq = 0;
866
867    /**
868     * Current sequence id for process LRU updating.
869     */
870    int mLruSeq = 0;
871
872    /**
873     * Keep track of the non-cached/empty process we last found, to help
874     * determine how to distribute cached/empty processes next time.
875     */
876    int mNumNonCachedProcs = 0;
877
878    /**
879     * Keep track of the number of cached hidden procs, to balance oom adj
880     * distribution between those and empty procs.
881     */
882    int mNumCachedHiddenProcs = 0;
883
884    /**
885     * Keep track of the number of service processes we last found, to
886     * determine on the next iteration which should be B services.
887     */
888    int mNumServiceProcs = 0;
889    int mNewNumAServiceProcs = 0;
890    int mNewNumServiceProcs = 0;
891
892    /**
893     * Allow the current computed overall memory level of the system to go down?
894     * This is set to false when we are killing processes for reasons other than
895     * memory management, so that the now smaller process list will not be taken as
896     * an indication that memory is tighter.
897     */
898    boolean mAllowLowerMemLevel = false;
899
900    /**
901     * The last computed memory level, for holding when we are in a state that
902     * processes are going away for other reasons.
903     */
904    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
905
906    /**
907     * The last total number of process we have, to determine if changes actually look
908     * like a shrinking number of process due to lower RAM.
909     */
910    int mLastNumProcesses;
911
912    /**
913     * The uptime of the last time we performed idle maintenance.
914     */
915    long mLastIdleTime = SystemClock.uptimeMillis();
916
917    /**
918     * Total time spent with RAM that has been added in the past since the last idle time.
919     */
920    long mLowRamTimeSinceLastIdle = 0;
921
922    /**
923     * If RAM is currently low, when that horrible situation started.
924     */
925    long mLowRamStartTime = 0;
926
927    /**
928     * For reporting to battery stats the current top application.
929     */
930    private String mCurResumedPackage = null;
931    private int mCurResumedUid = -1;
932
933    /**
934     * For reporting to battery stats the apps currently running foreground
935     * service.  The ProcessMap is package/uid tuples; each of these contain
936     * an array of the currently foreground processes.
937     */
938    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
939            = new ProcessMap<ArrayList<ProcessRecord>>();
940
941    /**
942     * This is set if we had to do a delayed dexopt of an app before launching
943     * it, to increasing the ANR timeouts in that case.
944     */
945    boolean mDidDexOpt;
946
947    /**
948     * Set if the systemServer made a call to enterSafeMode.
949     */
950    boolean mSafeMode;
951
952    String mDebugApp = null;
953    boolean mWaitForDebugger = false;
954    boolean mDebugTransient = false;
955    String mOrigDebugApp = null;
956    boolean mOrigWaitForDebugger = false;
957    boolean mAlwaysFinishActivities = false;
958    IActivityController mController = null;
959    String mProfileApp = null;
960    ProcessRecord mProfileProc = null;
961    String mProfileFile;
962    ParcelFileDescriptor mProfileFd;
963    int mProfileType = 0;
964    boolean mAutoStopProfiler = false;
965    String mOpenGlTraceApp = null;
966
967    static class ProcessChangeItem {
968        static final int CHANGE_ACTIVITIES = 1<<0;
969        static final int CHANGE_IMPORTANCE= 1<<1;
970        int changes;
971        int uid;
972        int pid;
973        int importance;
974        boolean foregroundActivities;
975    }
976
977    final RemoteCallbackList<IProcessObserver> mProcessObservers
978            = new RemoteCallbackList<IProcessObserver>();
979    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
980
981    final ArrayList<ProcessChangeItem> mPendingProcessChanges
982            = new ArrayList<ProcessChangeItem>();
983    final ArrayList<ProcessChangeItem> mAvailProcessChanges
984            = new ArrayList<ProcessChangeItem>();
985
986    /**
987     * Runtime CPU use collection thread.  This object's lock is used to
988     * protect all related state.
989     */
990    final Thread mProcessCpuThread;
991
992    /**
993     * Used to collect process stats when showing not responding dialog.
994     * Protected by mProcessCpuThread.
995     */
996    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
997            MONITOR_THREAD_CPU_USAGE);
998    final AtomicLong mLastCpuTime = new AtomicLong(0);
999    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1000
1001    long mLastWriteTime = 0;
1002
1003    /**
1004     * Used to retain an update lock when the foreground activity is in
1005     * immersive mode.
1006     */
1007    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1008
1009    /**
1010     * Set to true after the system has finished booting.
1011     */
1012    boolean mBooted = false;
1013
1014    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1015    int mProcessLimitOverride = -1;
1016
1017    WindowManagerService mWindowManager;
1018
1019    final ActivityThread mSystemThread;
1020
1021    int mCurrentUserId = 0;
1022    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1023    private UserManagerService mUserManager;
1024
1025    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1026        final ProcessRecord mApp;
1027        final int mPid;
1028        final IApplicationThread mAppThread;
1029
1030        AppDeathRecipient(ProcessRecord app, int pid,
1031                IApplicationThread thread) {
1032            if (localLOGV) Slog.v(
1033                TAG, "New death recipient " + this
1034                + " for thread " + thread.asBinder());
1035            mApp = app;
1036            mPid = pid;
1037            mAppThread = thread;
1038        }
1039
1040        @Override
1041        public void binderDied() {
1042            if (localLOGV) Slog.v(
1043                TAG, "Death received in " + this
1044                + " for thread " + mAppThread.asBinder());
1045            synchronized(ActivityManagerService.this) {
1046                appDiedLocked(mApp, mPid, mAppThread);
1047            }
1048        }
1049    }
1050
1051    static final int SHOW_ERROR_MSG = 1;
1052    static final int SHOW_NOT_RESPONDING_MSG = 2;
1053    static final int SHOW_FACTORY_ERROR_MSG = 3;
1054    static final int UPDATE_CONFIGURATION_MSG = 4;
1055    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1056    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1057    static final int SERVICE_TIMEOUT_MSG = 12;
1058    static final int UPDATE_TIME_ZONE = 13;
1059    static final int SHOW_UID_ERROR_MSG = 14;
1060    static final int IM_FEELING_LUCKY_MSG = 15;
1061    static final int PROC_START_TIMEOUT_MSG = 20;
1062    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1063    static final int KILL_APPLICATION_MSG = 22;
1064    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1065    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1066    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1067    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1068    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1069    static final int CLEAR_DNS_CACHE_MSG = 28;
1070    static final int UPDATE_HTTP_PROXY_MSG = 29;
1071    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1072    static final int DISPATCH_PROCESSES_CHANGED = 31;
1073    static final int DISPATCH_PROCESS_DIED = 32;
1074    static final int REPORT_MEM_USAGE_MSG = 33;
1075    static final int REPORT_USER_SWITCH_MSG = 34;
1076    static final int CONTINUE_USER_SWITCH_MSG = 35;
1077    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1078    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1079    static final int PERSIST_URI_GRANTS_MSG = 38;
1080    static final int REQUEST_ALL_PSS_MSG = 39;
1081    static final int START_PROFILES_MSG = 40;
1082    static final int UPDATE_TIME = 41;
1083
1084    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1085    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1086    static final int FIRST_COMPAT_MODE_MSG = 300;
1087    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1088
1089    AlertDialog mUidAlert;
1090    CompatModeDialog mCompatModeDialog;
1091    long mLastMemUsageReportTime = 0;
1092
1093    /**
1094     * Flag whether the current user is a "monkey", i.e. whether
1095     * the UI is driven by a UI automation tool.
1096     */
1097    private boolean mUserIsMonkey;
1098
1099    final ServiceThread mHandlerThread;
1100    final MainHandler mHandler;
1101
1102    final class MainHandler extends Handler {
1103        public MainHandler(Looper looper) {
1104            super(looper, null, true);
1105        }
1106
1107        @Override
1108        public void handleMessage(Message msg) {
1109            switch (msg.what) {
1110            case SHOW_ERROR_MSG: {
1111                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1112                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1113                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1114                synchronized (ActivityManagerService.this) {
1115                    ProcessRecord proc = (ProcessRecord)data.get("app");
1116                    AppErrorResult res = (AppErrorResult) data.get("result");
1117                    if (proc != null && proc.crashDialog != null) {
1118                        Slog.e(TAG, "App already has crash dialog: " + proc);
1119                        if (res != null) {
1120                            res.set(0);
1121                        }
1122                        return;
1123                    }
1124                    if (!showBackground && UserHandle.getAppId(proc.uid)
1125                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1126                            && proc.pid != MY_PID) {
1127                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1128                        if (res != null) {
1129                            res.set(0);
1130                        }
1131                        return;
1132                    }
1133                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1134                        Dialog d = new AppErrorDialog(mContext,
1135                                ActivityManagerService.this, res, proc);
1136                        d.show();
1137                        proc.crashDialog = d;
1138                    } else {
1139                        // The device is asleep, so just pretend that the user
1140                        // saw a crash dialog and hit "force quit".
1141                        if (res != null) {
1142                            res.set(0);
1143                        }
1144                    }
1145                }
1146
1147                ensureBootCompleted();
1148            } break;
1149            case SHOW_NOT_RESPONDING_MSG: {
1150                synchronized (ActivityManagerService.this) {
1151                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1152                    ProcessRecord proc = (ProcessRecord)data.get("app");
1153                    if (proc != null && proc.anrDialog != null) {
1154                        Slog.e(TAG, "App already has anr dialog: " + proc);
1155                        return;
1156                    }
1157
1158                    Intent intent = new Intent("android.intent.action.ANR");
1159                    if (!mProcessesReady) {
1160                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1161                                | Intent.FLAG_RECEIVER_FOREGROUND);
1162                    }
1163                    broadcastIntentLocked(null, null, intent,
1164                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1165                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1166
1167                    if (mShowDialogs) {
1168                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1169                                mContext, proc, (ActivityRecord)data.get("activity"),
1170                                msg.arg1 != 0);
1171                        d.show();
1172                        proc.anrDialog = d;
1173                    } else {
1174                        // Just kill the app if there is no dialog to be shown.
1175                        killAppAtUsersRequest(proc, null);
1176                    }
1177                }
1178
1179                ensureBootCompleted();
1180            } break;
1181            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1182                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1183                synchronized (ActivityManagerService.this) {
1184                    ProcessRecord proc = (ProcessRecord) data.get("app");
1185                    if (proc == null) {
1186                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1187                        break;
1188                    }
1189                    if (proc.crashDialog != null) {
1190                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1191                        return;
1192                    }
1193                    AppErrorResult res = (AppErrorResult) data.get("result");
1194                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1195                        Dialog d = new StrictModeViolationDialog(mContext,
1196                                ActivityManagerService.this, res, proc);
1197                        d.show();
1198                        proc.crashDialog = d;
1199                    } else {
1200                        // The device is asleep, so just pretend that the user
1201                        // saw a crash dialog and hit "force quit".
1202                        res.set(0);
1203                    }
1204                }
1205                ensureBootCompleted();
1206            } break;
1207            case SHOW_FACTORY_ERROR_MSG: {
1208                Dialog d = new FactoryErrorDialog(
1209                    mContext, msg.getData().getCharSequence("msg"));
1210                d.show();
1211                ensureBootCompleted();
1212            } break;
1213            case UPDATE_CONFIGURATION_MSG: {
1214                final ContentResolver resolver = mContext.getContentResolver();
1215                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1216            } break;
1217            case GC_BACKGROUND_PROCESSES_MSG: {
1218                synchronized (ActivityManagerService.this) {
1219                    performAppGcsIfAppropriateLocked();
1220                }
1221            } break;
1222            case WAIT_FOR_DEBUGGER_MSG: {
1223                synchronized (ActivityManagerService.this) {
1224                    ProcessRecord app = (ProcessRecord)msg.obj;
1225                    if (msg.arg1 != 0) {
1226                        if (!app.waitedForDebugger) {
1227                            Dialog d = new AppWaitingForDebuggerDialog(
1228                                    ActivityManagerService.this,
1229                                    mContext, app);
1230                            app.waitDialog = d;
1231                            app.waitedForDebugger = true;
1232                            d.show();
1233                        }
1234                    } else {
1235                        if (app.waitDialog != null) {
1236                            app.waitDialog.dismiss();
1237                            app.waitDialog = null;
1238                        }
1239                    }
1240                }
1241            } break;
1242            case SERVICE_TIMEOUT_MSG: {
1243                if (mDidDexOpt) {
1244                    mDidDexOpt = false;
1245                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1246                    nmsg.obj = msg.obj;
1247                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1248                    return;
1249                }
1250                mServices.serviceTimeout((ProcessRecord)msg.obj);
1251            } break;
1252            case UPDATE_TIME_ZONE: {
1253                synchronized (ActivityManagerService.this) {
1254                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1255                        ProcessRecord r = mLruProcesses.get(i);
1256                        if (r.thread != null) {
1257                            try {
1258                                r.thread.updateTimeZone();
1259                            } catch (RemoteException ex) {
1260                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1261                            }
1262                        }
1263                    }
1264                }
1265            } break;
1266            case CLEAR_DNS_CACHE_MSG: {
1267                synchronized (ActivityManagerService.this) {
1268                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1269                        ProcessRecord r = mLruProcesses.get(i);
1270                        if (r.thread != null) {
1271                            try {
1272                                r.thread.clearDnsCache();
1273                            } catch (RemoteException ex) {
1274                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1275                            }
1276                        }
1277                    }
1278                }
1279            } break;
1280            case UPDATE_HTTP_PROXY_MSG: {
1281                ProxyProperties proxy = (ProxyProperties)msg.obj;
1282                String host = "";
1283                String port = "";
1284                String exclList = "";
1285                String pacFileUrl = null;
1286                if (proxy != null) {
1287                    host = proxy.getHost();
1288                    port = Integer.toString(proxy.getPort());
1289                    exclList = proxy.getExclusionList();
1290                    pacFileUrl = proxy.getPacFileUrl();
1291                }
1292                synchronized (ActivityManagerService.this) {
1293                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1294                        ProcessRecord r = mLruProcesses.get(i);
1295                        if (r.thread != null) {
1296                            try {
1297                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1298                            } catch (RemoteException ex) {
1299                                Slog.w(TAG, "Failed to update http proxy for: " +
1300                                        r.info.processName);
1301                            }
1302                        }
1303                    }
1304                }
1305            } break;
1306            case SHOW_UID_ERROR_MSG: {
1307                String title = "System UIDs Inconsistent";
1308                String text = "UIDs on the system are inconsistent, you need to wipe your"
1309                        + " data partition or your device will be unstable.";
1310                Log.e(TAG, title + ": " + text);
1311                if (mShowDialogs) {
1312                    // XXX This is a temporary dialog, no need to localize.
1313                    AlertDialog d = new BaseErrorDialog(mContext);
1314                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1315                    d.setCancelable(false);
1316                    d.setTitle(title);
1317                    d.setMessage(text);
1318                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1319                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1320                    mUidAlert = d;
1321                    d.show();
1322                }
1323            } break;
1324            case IM_FEELING_LUCKY_MSG: {
1325                if (mUidAlert != null) {
1326                    mUidAlert.dismiss();
1327                    mUidAlert = null;
1328                }
1329            } break;
1330            case PROC_START_TIMEOUT_MSG: {
1331                if (mDidDexOpt) {
1332                    mDidDexOpt = false;
1333                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1334                    nmsg.obj = msg.obj;
1335                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1336                    return;
1337                }
1338                ProcessRecord app = (ProcessRecord)msg.obj;
1339                synchronized (ActivityManagerService.this) {
1340                    processStartTimedOutLocked(app);
1341                }
1342            } break;
1343            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1344                synchronized (ActivityManagerService.this) {
1345                    doPendingActivityLaunchesLocked(true);
1346                }
1347            } break;
1348            case KILL_APPLICATION_MSG: {
1349                synchronized (ActivityManagerService.this) {
1350                    int appid = msg.arg1;
1351                    boolean restart = (msg.arg2 == 1);
1352                    Bundle bundle = (Bundle)msg.obj;
1353                    String pkg = bundle.getString("pkg");
1354                    String reason = bundle.getString("reason");
1355                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1356                            false, UserHandle.USER_ALL, reason);
1357                }
1358            } break;
1359            case FINALIZE_PENDING_INTENT_MSG: {
1360                ((PendingIntentRecord)msg.obj).completeFinalize();
1361            } break;
1362            case POST_HEAVY_NOTIFICATION_MSG: {
1363                INotificationManager inm = NotificationManager.getService();
1364                if (inm == null) {
1365                    return;
1366                }
1367
1368                ActivityRecord root = (ActivityRecord)msg.obj;
1369                ProcessRecord process = root.app;
1370                if (process == null) {
1371                    return;
1372                }
1373
1374                try {
1375                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1376                    String text = mContext.getString(R.string.heavy_weight_notification,
1377                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1378                    Notification notification = new Notification();
1379                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1380                    notification.when = 0;
1381                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1382                    notification.tickerText = text;
1383                    notification.defaults = 0; // please be quiet
1384                    notification.sound = null;
1385                    notification.vibrate = null;
1386                    notification.setLatestEventInfo(context, text,
1387                            mContext.getText(R.string.heavy_weight_notification_detail),
1388                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1389                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1390                                    new UserHandle(root.userId)));
1391
1392                    try {
1393                        int[] outId = new int[1];
1394                        inm.enqueueNotificationWithTag("android", "android", null,
1395                                R.string.heavy_weight_notification,
1396                                notification, outId, root.userId);
1397                    } catch (RuntimeException e) {
1398                        Slog.w(ActivityManagerService.TAG,
1399                                "Error showing notification for heavy-weight app", e);
1400                    } catch (RemoteException e) {
1401                    }
1402                } catch (NameNotFoundException e) {
1403                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1404                }
1405            } break;
1406            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1407                INotificationManager inm = NotificationManager.getService();
1408                if (inm == null) {
1409                    return;
1410                }
1411                try {
1412                    inm.cancelNotificationWithTag("android", null,
1413                            R.string.heavy_weight_notification,  msg.arg1);
1414                } catch (RuntimeException e) {
1415                    Slog.w(ActivityManagerService.TAG,
1416                            "Error canceling notification for service", e);
1417                } catch (RemoteException e) {
1418                }
1419            } break;
1420            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1421                synchronized (ActivityManagerService.this) {
1422                    checkExcessivePowerUsageLocked(true);
1423                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1424                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1425                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1426                }
1427            } break;
1428            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1429                synchronized (ActivityManagerService.this) {
1430                    ActivityRecord ar = (ActivityRecord)msg.obj;
1431                    if (mCompatModeDialog != null) {
1432                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1433                                ar.info.applicationInfo.packageName)) {
1434                            return;
1435                        }
1436                        mCompatModeDialog.dismiss();
1437                        mCompatModeDialog = null;
1438                    }
1439                    if (ar != null && false) {
1440                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1441                                ar.packageName)) {
1442                            int mode = mCompatModePackages.computeCompatModeLocked(
1443                                    ar.info.applicationInfo);
1444                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1445                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1446                                mCompatModeDialog = new CompatModeDialog(
1447                                        ActivityManagerService.this, mContext,
1448                                        ar.info.applicationInfo);
1449                                mCompatModeDialog.show();
1450                            }
1451                        }
1452                    }
1453                }
1454                break;
1455            }
1456            case DISPATCH_PROCESSES_CHANGED: {
1457                dispatchProcessesChanged();
1458                break;
1459            }
1460            case DISPATCH_PROCESS_DIED: {
1461                final int pid = msg.arg1;
1462                final int uid = msg.arg2;
1463                dispatchProcessDied(pid, uid);
1464                break;
1465            }
1466            case REPORT_MEM_USAGE_MSG: {
1467                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1468                Thread thread = new Thread() {
1469                    @Override public void run() {
1470                        final SparseArray<ProcessMemInfo> infoMap
1471                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1472                        for (int i=0, N=memInfos.size(); i<N; i++) {
1473                            ProcessMemInfo mi = memInfos.get(i);
1474                            infoMap.put(mi.pid, mi);
1475                        }
1476                        updateCpuStatsNow();
1477                        synchronized (mProcessCpuThread) {
1478                            final int N = mProcessCpuTracker.countStats();
1479                            for (int i=0; i<N; i++) {
1480                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1481                                if (st.vsize > 0) {
1482                                    long pss = Debug.getPss(st.pid, null);
1483                                    if (pss > 0) {
1484                                        if (infoMap.indexOfKey(st.pid) < 0) {
1485                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1486                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1487                                            mi.pss = pss;
1488                                            memInfos.add(mi);
1489                                        }
1490                                    }
1491                                }
1492                            }
1493                        }
1494
1495                        long totalPss = 0;
1496                        for (int i=0, N=memInfos.size(); i<N; i++) {
1497                            ProcessMemInfo mi = memInfos.get(i);
1498                            if (mi.pss == 0) {
1499                                mi.pss = Debug.getPss(mi.pid, null);
1500                            }
1501                            totalPss += mi.pss;
1502                        }
1503                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1504                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1505                                if (lhs.oomAdj != rhs.oomAdj) {
1506                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1507                                }
1508                                if (lhs.pss != rhs.pss) {
1509                                    return lhs.pss < rhs.pss ? 1 : -1;
1510                                }
1511                                return 0;
1512                            }
1513                        });
1514
1515                        StringBuilder tag = new StringBuilder(128);
1516                        StringBuilder stack = new StringBuilder(128);
1517                        tag.append("Low on memory -- ");
1518                        appendMemBucket(tag, totalPss, "total", false);
1519                        appendMemBucket(stack, totalPss, "total", true);
1520
1521                        StringBuilder logBuilder = new StringBuilder(1024);
1522                        logBuilder.append("Low on memory:\n");
1523
1524                        boolean firstLine = true;
1525                        int lastOomAdj = Integer.MIN_VALUE;
1526                        for (int i=0, N=memInfos.size(); i<N; i++) {
1527                            ProcessMemInfo mi = memInfos.get(i);
1528
1529                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1530                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1531                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1532                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1533                                if (lastOomAdj != mi.oomAdj) {
1534                                    lastOomAdj = mi.oomAdj;
1535                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1536                                        tag.append(" / ");
1537                                    }
1538                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1539                                        if (firstLine) {
1540                                            stack.append(":");
1541                                            firstLine = false;
1542                                        }
1543                                        stack.append("\n\t at ");
1544                                    } else {
1545                                        stack.append("$");
1546                                    }
1547                                } else {
1548                                    tag.append(" ");
1549                                    stack.append("$");
1550                                }
1551                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1552                                    appendMemBucket(tag, mi.pss, mi.name, false);
1553                                }
1554                                appendMemBucket(stack, mi.pss, mi.name, true);
1555                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1556                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1557                                    stack.append("(");
1558                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1559                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1560                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1561                                            stack.append(":");
1562                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1563                                        }
1564                                    }
1565                                    stack.append(")");
1566                                }
1567                            }
1568
1569                            logBuilder.append("  ");
1570                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1571                            logBuilder.append(' ');
1572                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1573                            logBuilder.append(' ');
1574                            ProcessList.appendRamKb(logBuilder, mi.pss);
1575                            logBuilder.append(" kB: ");
1576                            logBuilder.append(mi.name);
1577                            logBuilder.append(" (");
1578                            logBuilder.append(mi.pid);
1579                            logBuilder.append(") ");
1580                            logBuilder.append(mi.adjType);
1581                            logBuilder.append('\n');
1582                            if (mi.adjReason != null) {
1583                                logBuilder.append("                      ");
1584                                logBuilder.append(mi.adjReason);
1585                                logBuilder.append('\n');
1586                            }
1587                        }
1588
1589                        logBuilder.append("           ");
1590                        ProcessList.appendRamKb(logBuilder, totalPss);
1591                        logBuilder.append(" kB: TOTAL\n");
1592
1593                        long[] infos = new long[Debug.MEMINFO_COUNT];
1594                        Debug.getMemInfo(infos);
1595                        logBuilder.append("  MemInfo: ");
1596                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1597                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1598                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1599                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1600                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1601                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1602                            logBuilder.append("  ZRAM: ");
1603                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1604                            logBuilder.append(" kB RAM, ");
1605                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1606                            logBuilder.append(" kB swap total, ");
1607                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1608                            logBuilder.append(" kB swap free\n");
1609                        }
1610                        Slog.i(TAG, logBuilder.toString());
1611
1612                        StringBuilder dropBuilder = new StringBuilder(1024);
1613                        /*
1614                        StringWriter oomSw = new StringWriter();
1615                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1616                        StringWriter catSw = new StringWriter();
1617                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1618                        String[] emptyArgs = new String[] { };
1619                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1620                        oomPw.flush();
1621                        String oomString = oomSw.toString();
1622                        */
1623                        dropBuilder.append(stack);
1624                        dropBuilder.append('\n');
1625                        dropBuilder.append('\n');
1626                        dropBuilder.append(logBuilder);
1627                        dropBuilder.append('\n');
1628                        /*
1629                        dropBuilder.append(oomString);
1630                        dropBuilder.append('\n');
1631                        */
1632                        StringWriter catSw = new StringWriter();
1633                        synchronized (ActivityManagerService.this) {
1634                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1635                            String[] emptyArgs = new String[] { };
1636                            catPw.println();
1637                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1638                            catPw.println();
1639                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1640                                    false, false, null);
1641                            catPw.println();
1642                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1643                            catPw.flush();
1644                        }
1645                        dropBuilder.append(catSw.toString());
1646                        addErrorToDropBox("lowmem", null, "system_server", null,
1647                                null, tag.toString(), dropBuilder.toString(), null, null);
1648                        //Slog.i(TAG, "Sent to dropbox:");
1649                        //Slog.i(TAG, dropBuilder.toString());
1650                        synchronized (ActivityManagerService.this) {
1651                            long now = SystemClock.uptimeMillis();
1652                            if (mLastMemUsageReportTime < now) {
1653                                mLastMemUsageReportTime = now;
1654                            }
1655                        }
1656                    }
1657                };
1658                thread.start();
1659                break;
1660            }
1661            case REPORT_USER_SWITCH_MSG: {
1662                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1663                break;
1664            }
1665            case CONTINUE_USER_SWITCH_MSG: {
1666                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1667                break;
1668            }
1669            case USER_SWITCH_TIMEOUT_MSG: {
1670                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1671                break;
1672            }
1673            case IMMERSIVE_MODE_LOCK_MSG: {
1674                final boolean nextState = (msg.arg1 != 0);
1675                if (mUpdateLock.isHeld() != nextState) {
1676                    if (DEBUG_IMMERSIVE) {
1677                        final ActivityRecord r = (ActivityRecord) msg.obj;
1678                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1679                    }
1680                    if (nextState) {
1681                        mUpdateLock.acquire();
1682                    } else {
1683                        mUpdateLock.release();
1684                    }
1685                }
1686                break;
1687            }
1688            case PERSIST_URI_GRANTS_MSG: {
1689                writeGrantedUriPermissions();
1690                break;
1691            }
1692            case REQUEST_ALL_PSS_MSG: {
1693                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1694                break;
1695            }
1696            case START_PROFILES_MSG: {
1697                synchronized (ActivityManagerService.this) {
1698                    startProfilesLocked();
1699                }
1700                break;
1701            }
1702            case UPDATE_TIME: {
1703                synchronized (ActivityManagerService.this) {
1704                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1705                        ProcessRecord r = mLruProcesses.get(i);
1706                        if (r.thread != null) {
1707                            try {
1708                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1709                            } catch (RemoteException ex) {
1710                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1711                            }
1712                        }
1713                    }
1714                }
1715                break;
1716            }
1717            }
1718        }
1719    };
1720
1721    static final int COLLECT_PSS_BG_MSG = 1;
1722
1723    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1724        @Override
1725        public void handleMessage(Message msg) {
1726            switch (msg.what) {
1727            case COLLECT_PSS_BG_MSG: {
1728                int i=0, num=0;
1729                long start = SystemClock.uptimeMillis();
1730                long[] tmp = new long[1];
1731                do {
1732                    ProcessRecord proc;
1733                    int procState;
1734                    int pid;
1735                    synchronized (ActivityManagerService.this) {
1736                        if (i >= mPendingPssProcesses.size()) {
1737                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1738                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1739                            mPendingPssProcesses.clear();
1740                            return;
1741                        }
1742                        proc = mPendingPssProcesses.get(i);
1743                        procState = proc.pssProcState;
1744                        if (proc.thread != null && procState == proc.setProcState) {
1745                            pid = proc.pid;
1746                        } else {
1747                            proc = null;
1748                            pid = 0;
1749                        }
1750                        i++;
1751                    }
1752                    if (proc != null) {
1753                        long pss = Debug.getPss(pid, tmp);
1754                        synchronized (ActivityManagerService.this) {
1755                            if (proc.thread != null && proc.setProcState == procState
1756                                    && proc.pid == pid) {
1757                                num++;
1758                                proc.lastPssTime = SystemClock.uptimeMillis();
1759                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1760                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1761                                        + ": " + pss + " lastPss=" + proc.lastPss
1762                                        + " state=" + ProcessList.makeProcStateString(procState));
1763                                if (proc.initialIdlePss == 0) {
1764                                    proc.initialIdlePss = pss;
1765                                }
1766                                proc.lastPss = pss;
1767                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1768                                    proc.lastCachedPss = pss;
1769                                }
1770                            }
1771                        }
1772                    }
1773                } while (true);
1774            }
1775            }
1776        }
1777    };
1778
1779    public void setSystemProcess() {
1780        try {
1781            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1782            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1783            ServiceManager.addService("meminfo", new MemBinder(this));
1784            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1785            ServiceManager.addService("dbinfo", new DbBinder(this));
1786            if (MONITOR_CPU_USAGE) {
1787                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1788            }
1789            ServiceManager.addService("permission", new PermissionController(this));
1790
1791            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1792                    "android", STOCK_PM_FLAGS);
1793            mSystemThread.installSystemApplicationInfo(info);
1794
1795            synchronized (this) {
1796                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1797                app.persistent = true;
1798                app.pid = MY_PID;
1799                app.maxAdj = ProcessList.SYSTEM_ADJ;
1800                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1801                mProcessNames.put(app.processName, app.uid, app);
1802                synchronized (mPidsSelfLocked) {
1803                    mPidsSelfLocked.put(app.pid, app);
1804                }
1805                updateLruProcessLocked(app, false, null);
1806                updateOomAdjLocked();
1807            }
1808        } catch (PackageManager.NameNotFoundException e) {
1809            throw new RuntimeException(
1810                    "Unable to find android system package", e);
1811        }
1812    }
1813
1814    public void setWindowManager(WindowManagerService wm) {
1815        mWindowManager = wm;
1816        mStackSupervisor.setWindowManager(wm);
1817    }
1818
1819    public void startObservingNativeCrashes() {
1820        final NativeCrashListener ncl = new NativeCrashListener(this);
1821        ncl.start();
1822    }
1823
1824    public IAppOpsService getAppOpsService() {
1825        return mAppOpsService;
1826    }
1827
1828    static class MemBinder extends Binder {
1829        ActivityManagerService mActivityManagerService;
1830        MemBinder(ActivityManagerService activityManagerService) {
1831            mActivityManagerService = activityManagerService;
1832        }
1833
1834        @Override
1835        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1836            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1837                    != PackageManager.PERMISSION_GRANTED) {
1838                pw.println("Permission Denial: can't dump meminfo from from pid="
1839                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1840                        + " without permission " + android.Manifest.permission.DUMP);
1841                return;
1842            }
1843
1844            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1845        }
1846    }
1847
1848    static class GraphicsBinder extends Binder {
1849        ActivityManagerService mActivityManagerService;
1850        GraphicsBinder(ActivityManagerService activityManagerService) {
1851            mActivityManagerService = activityManagerService;
1852        }
1853
1854        @Override
1855        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1856            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1857                    != PackageManager.PERMISSION_GRANTED) {
1858                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1859                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1860                        + " without permission " + android.Manifest.permission.DUMP);
1861                return;
1862            }
1863
1864            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1865        }
1866    }
1867
1868    static class DbBinder extends Binder {
1869        ActivityManagerService mActivityManagerService;
1870        DbBinder(ActivityManagerService activityManagerService) {
1871            mActivityManagerService = activityManagerService;
1872        }
1873
1874        @Override
1875        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1876            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1877                    != PackageManager.PERMISSION_GRANTED) {
1878                pw.println("Permission Denial: can't dump dbinfo from from pid="
1879                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1880                        + " without permission " + android.Manifest.permission.DUMP);
1881                return;
1882            }
1883
1884            mActivityManagerService.dumpDbInfo(fd, pw, args);
1885        }
1886    }
1887
1888    static class CpuBinder extends Binder {
1889        ActivityManagerService mActivityManagerService;
1890        CpuBinder(ActivityManagerService activityManagerService) {
1891            mActivityManagerService = activityManagerService;
1892        }
1893
1894        @Override
1895        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1896            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1897                    != PackageManager.PERMISSION_GRANTED) {
1898                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1899                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1900                        + " without permission " + android.Manifest.permission.DUMP);
1901                return;
1902            }
1903
1904            synchronized (mActivityManagerService.mProcessCpuThread) {
1905                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1906                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1907                        SystemClock.uptimeMillis()));
1908            }
1909        }
1910    }
1911
1912    public static final class Lifecycle extends SystemService {
1913        private final ActivityManagerService mService;
1914
1915        public Lifecycle(Context context) {
1916            super(context);
1917            mService = new ActivityManagerService(context);
1918        }
1919
1920        @Override
1921        public void onStart() {
1922            mService.start();
1923        }
1924
1925        public ActivityManagerService getService() {
1926            return mService;
1927        }
1928    }
1929
1930    // Note: This method is invoked on the main thread but may need to attach various
1931    // handlers to other threads.  So take care to be explicit about the looper.
1932    public ActivityManagerService(Context systemContext) {
1933        mContext = systemContext;
1934        mFactoryTest = FactoryTest.getMode();
1935        mSystemThread = ActivityThread.currentActivityThread();
1936
1937        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1938
1939        mHandlerThread = new ServiceThread(TAG,
1940                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1941        mHandlerThread.start();
1942        mHandler = new MainHandler(mHandlerThread.getLooper());
1943
1944        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1945                "foreground", BROADCAST_FG_TIMEOUT, false);
1946        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1947                "background", BROADCAST_BG_TIMEOUT, true);
1948        mBroadcastQueues[0] = mFgBroadcastQueue;
1949        mBroadcastQueues[1] = mBgBroadcastQueue;
1950
1951        mServices = new ActiveServices(this);
1952        mProviderMap = new ProviderMap(this);
1953
1954        // TODO: Move creation of battery stats service outside of activity manager service.
1955        File dataDir = Environment.getDataDirectory();
1956        File systemDir = new File(dataDir, "system");
1957        systemDir.mkdirs();
1958        mBatteryStatsService = new BatteryStatsService(new File(
1959                systemDir, "batterystats.bin").toString(), mHandler);
1960        mBatteryStatsService.getActiveStatistics().readLocked();
1961        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1962        mOnBattery = DEBUG_POWER ? true
1963                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1964        mBatteryStatsService.getActiveStatistics().setCallback(this);
1965
1966        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1967
1968        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1969        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1970
1971        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1972
1973        // User 0 is the first and only user that runs at boot.
1974        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1975        mUserLru.add(Integer.valueOf(0));
1976        updateStartedUserArrayLocked();
1977
1978        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1979            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1980
1981        mConfiguration.setToDefaults();
1982        mConfiguration.setLocale(Locale.getDefault());
1983
1984        mConfigurationSeq = mConfiguration.seq = 1;
1985        mProcessCpuTracker.init();
1986
1987        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1988        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1989        mStackSupervisor = new ActivityStackSupervisor(this);
1990
1991        mProcessCpuThread = new Thread("CpuTracker") {
1992            @Override
1993            public void run() {
1994                while (true) {
1995                    try {
1996                        try {
1997                            synchronized(this) {
1998                                final long now = SystemClock.uptimeMillis();
1999                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2000                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2001                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2002                                //        + ", write delay=" + nextWriteDelay);
2003                                if (nextWriteDelay < nextCpuDelay) {
2004                                    nextCpuDelay = nextWriteDelay;
2005                                }
2006                                if (nextCpuDelay > 0) {
2007                                    mProcessCpuMutexFree.set(true);
2008                                    this.wait(nextCpuDelay);
2009                                }
2010                            }
2011                        } catch (InterruptedException e) {
2012                        }
2013                        updateCpuStatsNow();
2014                    } catch (Exception e) {
2015                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2016                    }
2017                }
2018            }
2019        };
2020
2021        Watchdog.getInstance().addMonitor(this);
2022        Watchdog.getInstance().addThread(mHandler);
2023    }
2024
2025    private void start() {
2026        mProcessCpuThread.start();
2027
2028        mBatteryStatsService.publish(mContext);
2029        mUsageStatsService.publish(mContext);
2030        mAppOpsService.publish(mContext);
2031        startRunning(null, null, null, null);
2032    }
2033
2034    @Override
2035    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2036            throws RemoteException {
2037        if (code == SYSPROPS_TRANSACTION) {
2038            // We need to tell all apps about the system property change.
2039            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2040            synchronized(this) {
2041                final int NP = mProcessNames.getMap().size();
2042                for (int ip=0; ip<NP; ip++) {
2043                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2044                    final int NA = apps.size();
2045                    for (int ia=0; ia<NA; ia++) {
2046                        ProcessRecord app = apps.valueAt(ia);
2047                        if (app.thread != null) {
2048                            procs.add(app.thread.asBinder());
2049                        }
2050                    }
2051                }
2052            }
2053
2054            int N = procs.size();
2055            for (int i=0; i<N; i++) {
2056                Parcel data2 = Parcel.obtain();
2057                try {
2058                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2059                } catch (RemoteException e) {
2060                }
2061                data2.recycle();
2062            }
2063        }
2064        try {
2065            return super.onTransact(code, data, reply, flags);
2066        } catch (RuntimeException e) {
2067            // The activity manager only throws security exceptions, so let's
2068            // log all others.
2069            if (!(e instanceof SecurityException)) {
2070                Slog.wtf(TAG, "Activity Manager Crash", e);
2071            }
2072            throw e;
2073        }
2074    }
2075
2076    void updateCpuStats() {
2077        final long now = SystemClock.uptimeMillis();
2078        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2079            return;
2080        }
2081        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2082            synchronized (mProcessCpuThread) {
2083                mProcessCpuThread.notify();
2084            }
2085        }
2086    }
2087
2088    void updateCpuStatsNow() {
2089        synchronized (mProcessCpuThread) {
2090            mProcessCpuMutexFree.set(false);
2091            final long now = SystemClock.uptimeMillis();
2092            boolean haveNewCpuStats = false;
2093
2094            if (MONITOR_CPU_USAGE &&
2095                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2096                mLastCpuTime.set(now);
2097                haveNewCpuStats = true;
2098                mProcessCpuTracker.update();
2099                //Slog.i(TAG, mProcessCpu.printCurrentState());
2100                //Slog.i(TAG, "Total CPU usage: "
2101                //        + mProcessCpu.getTotalCpuPercent() + "%");
2102
2103                // Slog the cpu usage if the property is set.
2104                if ("true".equals(SystemProperties.get("events.cpu"))) {
2105                    int user = mProcessCpuTracker.getLastUserTime();
2106                    int system = mProcessCpuTracker.getLastSystemTime();
2107                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2108                    int irq = mProcessCpuTracker.getLastIrqTime();
2109                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2110                    int idle = mProcessCpuTracker.getLastIdleTime();
2111
2112                    int total = user + system + iowait + irq + softIrq + idle;
2113                    if (total == 0) total = 1;
2114
2115                    EventLog.writeEvent(EventLogTags.CPU,
2116                            ((user+system+iowait+irq+softIrq) * 100) / total,
2117                            (user * 100) / total,
2118                            (system * 100) / total,
2119                            (iowait * 100) / total,
2120                            (irq * 100) / total,
2121                            (softIrq * 100) / total);
2122                }
2123            }
2124
2125            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2126            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2127            synchronized(bstats) {
2128                synchronized(mPidsSelfLocked) {
2129                    if (haveNewCpuStats) {
2130                        if (mOnBattery) {
2131                            int perc = bstats.startAddingCpuLocked();
2132                            int totalUTime = 0;
2133                            int totalSTime = 0;
2134                            final int N = mProcessCpuTracker.countStats();
2135                            for (int i=0; i<N; i++) {
2136                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2137                                if (!st.working) {
2138                                    continue;
2139                                }
2140                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2141                                int otherUTime = (st.rel_utime*perc)/100;
2142                                int otherSTime = (st.rel_stime*perc)/100;
2143                                totalUTime += otherUTime;
2144                                totalSTime += otherSTime;
2145                                if (pr != null) {
2146                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2147                                    if (ps == null || !ps.isActive()) {
2148                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2149                                                pr.info.uid, pr.processName);
2150                                    }
2151                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2152                                            st.rel_stime-otherSTime);
2153                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2154                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2155                                } else {
2156                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2157                                    if (ps == null || !ps.isActive()) {
2158                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2159                                                bstats.mapUid(st.uid), st.name);
2160                                    }
2161                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2162                                            st.rel_stime-otherSTime);
2163                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2164                                }
2165                            }
2166                            bstats.finishAddingCpuLocked(perc, totalUTime,
2167                                    totalSTime, cpuSpeedTimes);
2168                        }
2169                    }
2170                }
2171
2172                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2173                    mLastWriteTime = now;
2174                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2175                }
2176            }
2177        }
2178    }
2179
2180    @Override
2181    public void batteryNeedsCpuUpdate() {
2182        updateCpuStatsNow();
2183    }
2184
2185    @Override
2186    public void batteryPowerChanged(boolean onBattery) {
2187        // When plugging in, update the CPU stats first before changing
2188        // the plug state.
2189        updateCpuStatsNow();
2190        synchronized (this) {
2191            synchronized(mPidsSelfLocked) {
2192                mOnBattery = DEBUG_POWER ? true : onBattery;
2193            }
2194        }
2195    }
2196
2197    /**
2198     * Initialize the application bind args. These are passed to each
2199     * process when the bindApplication() IPC is sent to the process. They're
2200     * lazily setup to make sure the services are running when they're asked for.
2201     */
2202    private HashMap<String, IBinder> getCommonServicesLocked() {
2203        if (mAppBindArgs == null) {
2204            mAppBindArgs = new HashMap<String, IBinder>();
2205
2206            // Setup the application init args
2207            mAppBindArgs.put("package", ServiceManager.getService("package"));
2208            mAppBindArgs.put("window", ServiceManager.getService("window"));
2209            mAppBindArgs.put(Context.ALARM_SERVICE,
2210                    ServiceManager.getService(Context.ALARM_SERVICE));
2211        }
2212        return mAppBindArgs;
2213    }
2214
2215    final void setFocusedActivityLocked(ActivityRecord r) {
2216        if (mFocusedActivity != r) {
2217            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2218            mFocusedActivity = r;
2219            mStackSupervisor.setFocusedStack(r);
2220            if (r != null) {
2221                mWindowManager.setFocusedApp(r.appToken, true);
2222            }
2223            applyUpdateLockStateLocked(r);
2224        }
2225    }
2226
2227    @Override
2228    public void setFocusedStack(int stackId) {
2229        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2230        synchronized (ActivityManagerService.this) {
2231            ActivityStack stack = mStackSupervisor.getStack(stackId);
2232            if (stack != null) {
2233                ActivityRecord r = stack.topRunningActivityLocked(null);
2234                if (r != null) {
2235                    setFocusedActivityLocked(r);
2236                }
2237            }
2238        }
2239    }
2240
2241    @Override
2242    public void notifyActivityDrawn(IBinder token) {
2243        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2244        synchronized (this) {
2245            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2246            if (r != null) {
2247                r.task.stack.notifyActivityDrawnLocked(r);
2248            }
2249        }
2250    }
2251
2252    final void applyUpdateLockStateLocked(ActivityRecord r) {
2253        // Modifications to the UpdateLock state are done on our handler, outside
2254        // the activity manager's locks.  The new state is determined based on the
2255        // state *now* of the relevant activity record.  The object is passed to
2256        // the handler solely for logging detail, not to be consulted/modified.
2257        final boolean nextState = r != null && r.immersive;
2258        mHandler.sendMessage(
2259                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2260    }
2261
2262    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2263        Message msg = Message.obtain();
2264        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2265        msg.obj = r.task.askedCompatMode ? null : r;
2266        mHandler.sendMessage(msg);
2267    }
2268
2269    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2270            String what, Object obj, ProcessRecord srcApp) {
2271        app.lastActivityTime = now;
2272
2273        if (app.activities.size() > 0) {
2274            // Don't want to touch dependent processes that are hosting activities.
2275            return index;
2276        }
2277
2278        int lrui = mLruProcesses.lastIndexOf(app);
2279        if (lrui < 0) {
2280            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2281                    + what + " " + obj + " from " + srcApp);
2282            return index;
2283        }
2284
2285        if (lrui >= index) {
2286            // Don't want to cause this to move dependent processes *back* in the
2287            // list as if they were less frequently used.
2288            return index;
2289        }
2290
2291        if (lrui >= mLruProcessActivityStart) {
2292            // Don't want to touch dependent processes that are hosting activities.
2293            return index;
2294        }
2295
2296        mLruProcesses.remove(lrui);
2297        if (index > 0) {
2298            index--;
2299        }
2300        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2301                + " in LRU list: " + app);
2302        mLruProcesses.add(index, app);
2303        return index;
2304    }
2305
2306    final void removeLruProcessLocked(ProcessRecord app) {
2307        int lrui = mLruProcesses.lastIndexOf(app);
2308        if (lrui >= 0) {
2309            if (lrui <= mLruProcessActivityStart) {
2310                mLruProcessActivityStart--;
2311            }
2312            if (lrui <= mLruProcessServiceStart) {
2313                mLruProcessServiceStart--;
2314            }
2315            mLruProcesses.remove(lrui);
2316        }
2317    }
2318
2319    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2320            ProcessRecord client) {
2321        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2322                || app.treatLikeActivity;
2323        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2324        if (!activityChange && hasActivity) {
2325            // The process has activities, so we are only allowing activity-based adjustments
2326            // to move it.  It should be kept in the front of the list with other
2327            // processes that have activities, and we don't want those to change their
2328            // order except due to activity operations.
2329            return;
2330        }
2331
2332        mLruSeq++;
2333        final long now = SystemClock.uptimeMillis();
2334        app.lastActivityTime = now;
2335
2336        // First a quick reject: if the app is already at the position we will
2337        // put it, then there is nothing to do.
2338        if (hasActivity) {
2339            final int N = mLruProcesses.size();
2340            if (N > 0 && mLruProcesses.get(N-1) == app) {
2341                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2342                return;
2343            }
2344        } else {
2345            if (mLruProcessServiceStart > 0
2346                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2347                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2348                return;
2349            }
2350        }
2351
2352        int lrui = mLruProcesses.lastIndexOf(app);
2353
2354        if (app.persistent && lrui >= 0) {
2355            // We don't care about the position of persistent processes, as long as
2356            // they are in the list.
2357            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2358            return;
2359        }
2360
2361        /* In progress: compute new position first, so we can avoid doing work
2362           if the process is not actually going to move.  Not yet working.
2363        int addIndex;
2364        int nextIndex;
2365        boolean inActivity = false, inService = false;
2366        if (hasActivity) {
2367            // Process has activities, put it at the very tipsy-top.
2368            addIndex = mLruProcesses.size();
2369            nextIndex = mLruProcessServiceStart;
2370            inActivity = true;
2371        } else if (hasService) {
2372            // Process has services, put it at the top of the service list.
2373            addIndex = mLruProcessActivityStart;
2374            nextIndex = mLruProcessServiceStart;
2375            inActivity = true;
2376            inService = true;
2377        } else  {
2378            // Process not otherwise of interest, it goes to the top of the non-service area.
2379            addIndex = mLruProcessServiceStart;
2380            if (client != null) {
2381                int clientIndex = mLruProcesses.lastIndexOf(client);
2382                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2383                        + app);
2384                if (clientIndex >= 0 && addIndex > clientIndex) {
2385                    addIndex = clientIndex;
2386                }
2387            }
2388            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2389        }
2390
2391        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2392                + mLruProcessActivityStart + "): " + app);
2393        */
2394
2395        if (lrui >= 0) {
2396            if (lrui < mLruProcessActivityStart) {
2397                mLruProcessActivityStart--;
2398            }
2399            if (lrui < mLruProcessServiceStart) {
2400                mLruProcessServiceStart--;
2401            }
2402            /*
2403            if (addIndex > lrui) {
2404                addIndex--;
2405            }
2406            if (nextIndex > lrui) {
2407                nextIndex--;
2408            }
2409            */
2410            mLruProcesses.remove(lrui);
2411        }
2412
2413        /*
2414        mLruProcesses.add(addIndex, app);
2415        if (inActivity) {
2416            mLruProcessActivityStart++;
2417        }
2418        if (inService) {
2419            mLruProcessActivityStart++;
2420        }
2421        */
2422
2423        int nextIndex;
2424        if (hasActivity) {
2425            final int N = mLruProcesses.size();
2426            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2427                // Process doesn't have activities, but has clients with
2428                // activities...  move it up, but one below the top (the top
2429                // should always have a real activity).
2430                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2431                mLruProcesses.add(N-1, app);
2432                // To keep it from spamming the LRU list (by making a bunch of clients),
2433                // we will push down any other entries owned by the app.
2434                final int uid = app.info.uid;
2435                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2436                    ProcessRecord subProc = mLruProcesses.get(i);
2437                    if (subProc.info.uid == uid) {
2438                        // We want to push this one down the list.  If the process after
2439                        // it is for the same uid, however, don't do so, because we don't
2440                        // want them internally to be re-ordered.
2441                        if (mLruProcesses.get(i-1).info.uid != uid) {
2442                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2443                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2444                            ProcessRecord tmp = mLruProcesses.get(i);
2445                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2446                            mLruProcesses.set(i-1, tmp);
2447                            i--;
2448                        }
2449                    } else {
2450                        // A gap, we can stop here.
2451                        break;
2452                    }
2453                }
2454            } else {
2455                // Process has activities, put it at the very tipsy-top.
2456                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2457                mLruProcesses.add(app);
2458            }
2459            nextIndex = mLruProcessServiceStart;
2460        } else if (hasService) {
2461            // Process has services, put it at the top of the service list.
2462            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2463            mLruProcesses.add(mLruProcessActivityStart, app);
2464            nextIndex = mLruProcessServiceStart;
2465            mLruProcessActivityStart++;
2466        } else  {
2467            // Process not otherwise of interest, it goes to the top of the non-service area.
2468            int index = mLruProcessServiceStart;
2469            if (client != null) {
2470                // If there is a client, don't allow the process to be moved up higher
2471                // in the list than that client.
2472                int clientIndex = mLruProcesses.lastIndexOf(client);
2473                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2474                        + " when updating " + app);
2475                if (clientIndex <= lrui) {
2476                    // Don't allow the client index restriction to push it down farther in the
2477                    // list than it already is.
2478                    clientIndex = lrui;
2479                }
2480                if (clientIndex >= 0 && index > clientIndex) {
2481                    index = clientIndex;
2482                }
2483            }
2484            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2485            mLruProcesses.add(index, app);
2486            nextIndex = index-1;
2487            mLruProcessActivityStart++;
2488            mLruProcessServiceStart++;
2489        }
2490
2491        // If the app is currently using a content provider or service,
2492        // bump those processes as well.
2493        for (int j=app.connections.size()-1; j>=0; j--) {
2494            ConnectionRecord cr = app.connections.valueAt(j);
2495            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2496                    && cr.binding.service.app != null
2497                    && cr.binding.service.app.lruSeq != mLruSeq
2498                    && !cr.binding.service.app.persistent) {
2499                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2500                        "service connection", cr, app);
2501            }
2502        }
2503        for (int j=app.conProviders.size()-1; j>=0; j--) {
2504            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2505            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2506                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2507                        "provider reference", cpr, app);
2508            }
2509        }
2510    }
2511
2512    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2513        if (uid == Process.SYSTEM_UID) {
2514            // The system gets to run in any process.  If there are multiple
2515            // processes with the same uid, just pick the first (this
2516            // should never happen).
2517            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2518            if (procs == null) return null;
2519            final int N = procs.size();
2520            for (int i = 0; i < N; i++) {
2521                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2522            }
2523        }
2524        ProcessRecord proc = mProcessNames.get(processName, uid);
2525        if (false && proc != null && !keepIfLarge
2526                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2527                && proc.lastCachedPss >= 4000) {
2528            // Turn this condition on to cause killing to happen regularly, for testing.
2529            if (proc.baseProcessTracker != null) {
2530                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2531            }
2532            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2533                    + "k from cached");
2534        } else if (proc != null && !keepIfLarge
2535                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2536                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2537            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2538            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2539                if (proc.baseProcessTracker != null) {
2540                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2541                }
2542                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2543                        + "k from cached");
2544            }
2545        }
2546        return proc;
2547    }
2548
2549    void ensurePackageDexOpt(String packageName) {
2550        IPackageManager pm = AppGlobals.getPackageManager();
2551        try {
2552            if (pm.performDexOpt(packageName)) {
2553                mDidDexOpt = true;
2554            }
2555        } catch (RemoteException e) {
2556        }
2557    }
2558
2559    boolean isNextTransitionForward() {
2560        int transit = mWindowManager.getPendingAppTransition();
2561        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2562                || transit == AppTransition.TRANSIT_TASK_OPEN
2563                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2564    }
2565
2566    final ProcessRecord startProcessLocked(String processName,
2567            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2568            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2569            boolean isolated, boolean keepIfLarge) {
2570        ProcessRecord app;
2571        if (!isolated) {
2572            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2573        } else {
2574            // If this is an isolated process, it can't re-use an existing process.
2575            app = null;
2576        }
2577        // We don't have to do anything more if:
2578        // (1) There is an existing application record; and
2579        // (2) The caller doesn't think it is dead, OR there is no thread
2580        //     object attached to it so we know it couldn't have crashed; and
2581        // (3) There is a pid assigned to it, so it is either starting or
2582        //     already running.
2583        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2584                + " app=" + app + " knownToBeDead=" + knownToBeDead
2585                + " thread=" + (app != null ? app.thread : null)
2586                + " pid=" + (app != null ? app.pid : -1));
2587        if (app != null && app.pid > 0) {
2588            if (!knownToBeDead || app.thread == null) {
2589                // We already have the app running, or are waiting for it to
2590                // come up (we have a pid but not yet its thread), so keep it.
2591                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2592                // If this is a new package in the process, add the package to the list
2593                app.addPackage(info.packageName, mProcessStats);
2594                return app;
2595            }
2596
2597            // An application record is attached to a previous process,
2598            // clean it up now.
2599            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2600            handleAppDiedLocked(app, true, true);
2601        }
2602
2603        String hostingNameStr = hostingName != null
2604                ? hostingName.flattenToShortString() : null;
2605
2606        if (!isolated) {
2607            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2608                // If we are in the background, then check to see if this process
2609                // is bad.  If so, we will just silently fail.
2610                if (mBadProcesses.get(info.processName, info.uid) != null) {
2611                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2612                            + "/" + info.processName);
2613                    return null;
2614                }
2615            } else {
2616                // When the user is explicitly starting a process, then clear its
2617                // crash count so that we won't make it bad until they see at
2618                // least one crash dialog again, and make the process good again
2619                // if it had been bad.
2620                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2621                        + "/" + info.processName);
2622                mProcessCrashTimes.remove(info.processName, info.uid);
2623                if (mBadProcesses.get(info.processName, info.uid) != null) {
2624                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2625                            UserHandle.getUserId(info.uid), info.uid,
2626                            info.processName);
2627                    mBadProcesses.remove(info.processName, info.uid);
2628                    if (app != null) {
2629                        app.bad = false;
2630                    }
2631                }
2632            }
2633        }
2634
2635        if (app == null) {
2636            app = newProcessRecordLocked(info, processName, isolated);
2637            if (app == null) {
2638                Slog.w(TAG, "Failed making new process record for "
2639                        + processName + "/" + info.uid + " isolated=" + isolated);
2640                return null;
2641            }
2642            mProcessNames.put(processName, app.uid, app);
2643            if (isolated) {
2644                mIsolatedProcesses.put(app.uid, app);
2645            }
2646        } else {
2647            // If this is a new package in the process, add the package to the list
2648            app.addPackage(info.packageName, mProcessStats);
2649        }
2650
2651        // If the system is not ready yet, then hold off on starting this
2652        // process until it is.
2653        if (!mProcessesReady
2654                && !isAllowedWhileBooting(info)
2655                && !allowWhileBooting) {
2656            if (!mProcessesOnHold.contains(app)) {
2657                mProcessesOnHold.add(app);
2658            }
2659            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2660            return app;
2661        }
2662
2663        startProcessLocked(app, hostingType, hostingNameStr);
2664        return (app.pid != 0) ? app : null;
2665    }
2666
2667    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2668        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2669    }
2670
2671    private final void startProcessLocked(ProcessRecord app,
2672            String hostingType, String hostingNameStr) {
2673        if (app.pid > 0 && app.pid != MY_PID) {
2674            synchronized (mPidsSelfLocked) {
2675                mPidsSelfLocked.remove(app.pid);
2676                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2677            }
2678            app.setPid(0);
2679        }
2680
2681        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2682                "startProcessLocked removing on hold: " + app);
2683        mProcessesOnHold.remove(app);
2684
2685        updateCpuStats();
2686
2687        try {
2688            int uid = app.uid;
2689
2690            int[] gids = null;
2691            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2692            if (!app.isolated) {
2693                int[] permGids = null;
2694                try {
2695                    final PackageManager pm = mContext.getPackageManager();
2696                    permGids = pm.getPackageGids(app.info.packageName);
2697
2698                    if (Environment.isExternalStorageEmulated()) {
2699                        if (pm.checkPermission(
2700                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2701                                app.info.packageName) == PERMISSION_GRANTED) {
2702                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2703                        } else {
2704                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2705                        }
2706                    }
2707                } catch (PackageManager.NameNotFoundException e) {
2708                    Slog.w(TAG, "Unable to retrieve gids", e);
2709                }
2710
2711                /*
2712                 * Add shared application GID so applications can share some
2713                 * resources like shared libraries
2714                 */
2715                if (permGids == null) {
2716                    gids = new int[1];
2717                } else {
2718                    gids = new int[permGids.length + 1];
2719                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2720                }
2721                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2722            }
2723            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2724                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2725                        && mTopComponent != null
2726                        && app.processName.equals(mTopComponent.getPackageName())) {
2727                    uid = 0;
2728                }
2729                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2730                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2731                    uid = 0;
2732                }
2733            }
2734            int debugFlags = 0;
2735            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2736                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2737                // Also turn on CheckJNI for debuggable apps. It's quite
2738                // awkward to turn on otherwise.
2739                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2740            }
2741            // Run the app in safe mode if its manifest requests so or the
2742            // system is booted in safe mode.
2743            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2744                mSafeMode == true) {
2745                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2746            }
2747            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2748                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2749            }
2750            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2751                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2752            }
2753            if ("1".equals(SystemProperties.get("debug.assert"))) {
2754                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2755            }
2756
2757            // Start the process.  It will either succeed and return a result containing
2758            // the PID of the new process, or else throw a RuntimeException.
2759            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2760                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2761                    app.info.targetSdkVersion, app.info.seinfo, null);
2762
2763            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2764            synchronized (bs) {
2765                if (bs.isOnBattery()) {
2766                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2767                }
2768            }
2769
2770            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2771                    UserHandle.getUserId(uid), startResult.pid, uid,
2772                    app.processName, hostingType,
2773                    hostingNameStr != null ? hostingNameStr : "");
2774
2775            if (app.persistent) {
2776                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2777            }
2778
2779            StringBuilder buf = mStringBuilder;
2780            buf.setLength(0);
2781            buf.append("Start proc ");
2782            buf.append(app.processName);
2783            buf.append(" for ");
2784            buf.append(hostingType);
2785            if (hostingNameStr != null) {
2786                buf.append(" ");
2787                buf.append(hostingNameStr);
2788            }
2789            buf.append(": pid=");
2790            buf.append(startResult.pid);
2791            buf.append(" uid=");
2792            buf.append(uid);
2793            buf.append(" gids={");
2794            if (gids != null) {
2795                for (int gi=0; gi<gids.length; gi++) {
2796                    if (gi != 0) buf.append(", ");
2797                    buf.append(gids[gi]);
2798
2799                }
2800            }
2801            buf.append("}");
2802            Slog.i(TAG, buf.toString());
2803            app.setPid(startResult.pid);
2804            app.usingWrapper = startResult.usingWrapper;
2805            app.removed = false;
2806            synchronized (mPidsSelfLocked) {
2807                this.mPidsSelfLocked.put(startResult.pid, app);
2808                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2809                msg.obj = app;
2810                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2811                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2812            }
2813            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2814                    app.processName, app.info.uid);
2815            if (app.isolated) {
2816                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2817            }
2818        } catch (RuntimeException e) {
2819            // XXX do better error recovery.
2820            app.setPid(0);
2821            Slog.e(TAG, "Failure starting process " + app.processName, e);
2822        }
2823    }
2824
2825    void updateUsageStats(ActivityRecord component, boolean resumed) {
2826        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2827        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2828        if (resumed) {
2829            mUsageStatsService.noteResumeComponent(component.realActivity);
2830            synchronized (stats) {
2831                stats.noteActivityResumedLocked(component.app.uid);
2832            }
2833        } else {
2834            mUsageStatsService.notePauseComponent(component.realActivity);
2835            synchronized (stats) {
2836                stats.noteActivityPausedLocked(component.app.uid);
2837            }
2838        }
2839    }
2840
2841    Intent getHomeIntent() {
2842        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2843        intent.setComponent(mTopComponent);
2844        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2845            intent.addCategory(Intent.CATEGORY_HOME);
2846        }
2847        return intent;
2848    }
2849
2850    boolean startHomeActivityLocked(int userId) {
2851        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2852                && mTopAction == null) {
2853            // We are running in factory test mode, but unable to find
2854            // the factory test app, so just sit around displaying the
2855            // error message and don't try to start anything.
2856            return false;
2857        }
2858        Intent intent = getHomeIntent();
2859        ActivityInfo aInfo =
2860            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2861        if (aInfo != null) {
2862            intent.setComponent(new ComponentName(
2863                    aInfo.applicationInfo.packageName, aInfo.name));
2864            // Don't do this if the home app is currently being
2865            // instrumented.
2866            aInfo = new ActivityInfo(aInfo);
2867            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2868            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2869                    aInfo.applicationInfo.uid, true);
2870            if (app == null || app.instrumentationClass == null) {
2871                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2872                mStackSupervisor.startHomeActivity(intent, aInfo);
2873            }
2874        }
2875
2876        return true;
2877    }
2878
2879    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2880        ActivityInfo ai = null;
2881        ComponentName comp = intent.getComponent();
2882        try {
2883            if (comp != null) {
2884                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2885            } else {
2886                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2887                        intent,
2888                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2889                            flags, userId);
2890
2891                if (info != null) {
2892                    ai = info.activityInfo;
2893                }
2894            }
2895        } catch (RemoteException e) {
2896            // ignore
2897        }
2898
2899        return ai;
2900    }
2901
2902    /**
2903     * Starts the "new version setup screen" if appropriate.
2904     */
2905    void startSetupActivityLocked() {
2906        // Only do this once per boot.
2907        if (mCheckedForSetup) {
2908            return;
2909        }
2910
2911        // We will show this screen if the current one is a different
2912        // version than the last one shown, and we are not running in
2913        // low-level factory test mode.
2914        final ContentResolver resolver = mContext.getContentResolver();
2915        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2916                Settings.Global.getInt(resolver,
2917                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2918            mCheckedForSetup = true;
2919
2920            // See if we should be showing the platform update setup UI.
2921            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2922            List<ResolveInfo> ris = mContext.getPackageManager()
2923                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2924
2925            // We don't allow third party apps to replace this.
2926            ResolveInfo ri = null;
2927            for (int i=0; ris != null && i<ris.size(); i++) {
2928                if ((ris.get(i).activityInfo.applicationInfo.flags
2929                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2930                    ri = ris.get(i);
2931                    break;
2932                }
2933            }
2934
2935            if (ri != null) {
2936                String vers = ri.activityInfo.metaData != null
2937                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2938                        : null;
2939                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2940                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2941                            Intent.METADATA_SETUP_VERSION);
2942                }
2943                String lastVers = Settings.Secure.getString(
2944                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2945                if (vers != null && !vers.equals(lastVers)) {
2946                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2947                    intent.setComponent(new ComponentName(
2948                            ri.activityInfo.packageName, ri.activityInfo.name));
2949                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2950                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2951                }
2952            }
2953        }
2954    }
2955
2956    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2957        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2958    }
2959
2960    void enforceNotIsolatedCaller(String caller) {
2961        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2962            throw new SecurityException("Isolated process not allowed to call " + caller);
2963        }
2964    }
2965
2966    @Override
2967    public int getFrontActivityScreenCompatMode() {
2968        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2969        synchronized (this) {
2970            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2971        }
2972    }
2973
2974    @Override
2975    public void setFrontActivityScreenCompatMode(int mode) {
2976        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2977                "setFrontActivityScreenCompatMode");
2978        synchronized (this) {
2979            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2980        }
2981    }
2982
2983    @Override
2984    public int getPackageScreenCompatMode(String packageName) {
2985        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2986        synchronized (this) {
2987            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2988        }
2989    }
2990
2991    @Override
2992    public void setPackageScreenCompatMode(String packageName, int mode) {
2993        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2994                "setPackageScreenCompatMode");
2995        synchronized (this) {
2996            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2997        }
2998    }
2999
3000    @Override
3001    public boolean getPackageAskScreenCompat(String packageName) {
3002        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3003        synchronized (this) {
3004            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3005        }
3006    }
3007
3008    @Override
3009    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3010        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3011                "setPackageAskScreenCompat");
3012        synchronized (this) {
3013            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3014        }
3015    }
3016
3017    private void dispatchProcessesChanged() {
3018        int N;
3019        synchronized (this) {
3020            N = mPendingProcessChanges.size();
3021            if (mActiveProcessChanges.length < N) {
3022                mActiveProcessChanges = new ProcessChangeItem[N];
3023            }
3024            mPendingProcessChanges.toArray(mActiveProcessChanges);
3025            mAvailProcessChanges.addAll(mPendingProcessChanges);
3026            mPendingProcessChanges.clear();
3027            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3028        }
3029
3030        int i = mProcessObservers.beginBroadcast();
3031        while (i > 0) {
3032            i--;
3033            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3034            if (observer != null) {
3035                try {
3036                    for (int j=0; j<N; j++) {
3037                        ProcessChangeItem item = mActiveProcessChanges[j];
3038                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3039                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3040                                    + item.pid + " uid=" + item.uid + ": "
3041                                    + item.foregroundActivities);
3042                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3043                                    item.foregroundActivities);
3044                        }
3045                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3046                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3047                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3048                            observer.onImportanceChanged(item.pid, item.uid,
3049                                    item.importance);
3050                        }
3051                    }
3052                } catch (RemoteException e) {
3053                }
3054            }
3055        }
3056        mProcessObservers.finishBroadcast();
3057    }
3058
3059    private void dispatchProcessDied(int pid, int uid) {
3060        int i = mProcessObservers.beginBroadcast();
3061        while (i > 0) {
3062            i--;
3063            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3064            if (observer != null) {
3065                try {
3066                    observer.onProcessDied(pid, uid);
3067                } catch (RemoteException e) {
3068                }
3069            }
3070        }
3071        mProcessObservers.finishBroadcast();
3072    }
3073
3074    final void doPendingActivityLaunchesLocked(boolean doResume) {
3075        final int N = mPendingActivityLaunches.size();
3076        if (N <= 0) {
3077            return;
3078        }
3079        for (int i=0; i<N; i++) {
3080            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3081            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3082                    doResume && i == (N-1), null);
3083        }
3084        mPendingActivityLaunches.clear();
3085    }
3086
3087    @Override
3088    public final int startActivity(IApplicationThread caller, String callingPackage,
3089            Intent intent, String resolvedType, IBinder resultTo,
3090            String resultWho, int requestCode, int startFlags,
3091            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3092        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3093                resultWho, requestCode,
3094                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3095    }
3096
3097    @Override
3098    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3099            Intent intent, String resolvedType, IBinder resultTo,
3100            String resultWho, int requestCode, int startFlags,
3101            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3102        enforceNotIsolatedCaller("startActivity");
3103        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3104                false, true, "startActivity", null);
3105        // TODO: Switch to user app stacks here.
3106        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3107                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3108                null, null, options, userId, null);
3109    }
3110
3111    @Override
3112    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3113            Intent intent, String resolvedType, IBinder resultTo,
3114            String resultWho, int requestCode, int startFlags, String profileFile,
3115            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3116        enforceNotIsolatedCaller("startActivityAndWait");
3117        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3118                false, true, "startActivityAndWait", null);
3119        WaitResult res = new WaitResult();
3120        // TODO: Switch to user app stacks here.
3121        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3122                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3123                res, null, options, UserHandle.getCallingUserId(), null);
3124        return res;
3125    }
3126
3127    @Override
3128    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3129            Intent intent, String resolvedType, IBinder resultTo,
3130            String resultWho, int requestCode, int startFlags, Configuration config,
3131            Bundle options, int userId) {
3132        enforceNotIsolatedCaller("startActivityWithConfig");
3133        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3134                false, true, "startActivityWithConfig", null);
3135        // TODO: Switch to user app stacks here.
3136        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3137                resolvedType, resultTo, resultWho, requestCode, startFlags,
3138                null, null, null, config, options, userId, null);
3139        return ret;
3140    }
3141
3142    @Override
3143    public int startActivityIntentSender(IApplicationThread caller,
3144            IntentSender intent, Intent fillInIntent, String resolvedType,
3145            IBinder resultTo, String resultWho, int requestCode,
3146            int flagsMask, int flagsValues, Bundle options) {
3147        enforceNotIsolatedCaller("startActivityIntentSender");
3148        // Refuse possible leaked file descriptors
3149        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3150            throw new IllegalArgumentException("File descriptors passed in Intent");
3151        }
3152
3153        IIntentSender sender = intent.getTarget();
3154        if (!(sender instanceof PendingIntentRecord)) {
3155            throw new IllegalArgumentException("Bad PendingIntent object");
3156        }
3157
3158        PendingIntentRecord pir = (PendingIntentRecord)sender;
3159
3160        synchronized (this) {
3161            // If this is coming from the currently resumed activity, it is
3162            // effectively saying that app switches are allowed at this point.
3163            final ActivityStack stack = getFocusedStack();
3164            if (stack.mResumedActivity != null &&
3165                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3166                mAppSwitchesAllowedTime = 0;
3167            }
3168        }
3169        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3170                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3171        return ret;
3172    }
3173
3174    @Override
3175    public boolean startNextMatchingActivity(IBinder callingActivity,
3176            Intent intent, Bundle options) {
3177        // Refuse possible leaked file descriptors
3178        if (intent != null && intent.hasFileDescriptors() == true) {
3179            throw new IllegalArgumentException("File descriptors passed in Intent");
3180        }
3181
3182        synchronized (this) {
3183            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3184            if (r == null) {
3185                ActivityOptions.abort(options);
3186                return false;
3187            }
3188            if (r.app == null || r.app.thread == null) {
3189                // The caller is not running...  d'oh!
3190                ActivityOptions.abort(options);
3191                return false;
3192            }
3193            intent = new Intent(intent);
3194            // The caller is not allowed to change the data.
3195            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3196            // And we are resetting to find the next component...
3197            intent.setComponent(null);
3198
3199            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3200
3201            ActivityInfo aInfo = null;
3202            try {
3203                List<ResolveInfo> resolves =
3204                    AppGlobals.getPackageManager().queryIntentActivities(
3205                            intent, r.resolvedType,
3206                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3207                            UserHandle.getCallingUserId());
3208
3209                // Look for the original activity in the list...
3210                final int N = resolves != null ? resolves.size() : 0;
3211                for (int i=0; i<N; i++) {
3212                    ResolveInfo rInfo = resolves.get(i);
3213                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3214                            && rInfo.activityInfo.name.equals(r.info.name)) {
3215                        // We found the current one...  the next matching is
3216                        // after it.
3217                        i++;
3218                        if (i<N) {
3219                            aInfo = resolves.get(i).activityInfo;
3220                        }
3221                        if (debug) {
3222                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3223                                    + "/" + r.info.name);
3224                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3225                                    + "/" + aInfo.name);
3226                        }
3227                        break;
3228                    }
3229                }
3230            } catch (RemoteException e) {
3231            }
3232
3233            if (aInfo == null) {
3234                // Nobody who is next!
3235                ActivityOptions.abort(options);
3236                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3237                return false;
3238            }
3239
3240            intent.setComponent(new ComponentName(
3241                    aInfo.applicationInfo.packageName, aInfo.name));
3242            intent.setFlags(intent.getFlags()&~(
3243                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3244                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3245                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3246                    Intent.FLAG_ACTIVITY_NEW_TASK));
3247
3248            // Okay now we need to start the new activity, replacing the
3249            // currently running activity.  This is a little tricky because
3250            // we want to start the new one as if the current one is finished,
3251            // but not finish the current one first so that there is no flicker.
3252            // And thus...
3253            final boolean wasFinishing = r.finishing;
3254            r.finishing = true;
3255
3256            // Propagate reply information over to the new activity.
3257            final ActivityRecord resultTo = r.resultTo;
3258            final String resultWho = r.resultWho;
3259            final int requestCode = r.requestCode;
3260            r.resultTo = null;
3261            if (resultTo != null) {
3262                resultTo.removeResultsLocked(r, resultWho, requestCode);
3263            }
3264
3265            final long origId = Binder.clearCallingIdentity();
3266            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3267                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3268                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3269                    options, false, null, null);
3270            Binder.restoreCallingIdentity(origId);
3271
3272            r.finishing = wasFinishing;
3273            if (res != ActivityManager.START_SUCCESS) {
3274                return false;
3275            }
3276            return true;
3277        }
3278    }
3279
3280    final int startActivityInPackage(int uid, String callingPackage,
3281            Intent intent, String resolvedType, IBinder resultTo,
3282            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3283                    IActivityContainer container) {
3284
3285        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3286                false, true, "startActivityInPackage", null);
3287
3288        // TODO: Switch to user app stacks here.
3289        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3290                resultTo, resultWho, requestCode, startFlags,
3291                null, null, null, null, options, userId, container);
3292        return ret;
3293    }
3294
3295    @Override
3296    public final int startActivities(IApplicationThread caller, String callingPackage,
3297            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3298            int userId) {
3299        enforceNotIsolatedCaller("startActivities");
3300        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3301                false, true, "startActivity", null);
3302        // TODO: Switch to user app stacks here.
3303        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3304                resolvedTypes, resultTo, options, userId);
3305        return ret;
3306    }
3307
3308    final int startActivitiesInPackage(int uid, String callingPackage,
3309            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3310            Bundle options, int userId) {
3311
3312        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3313                false, true, "startActivityInPackage", null);
3314        // TODO: Switch to user app stacks here.
3315        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3316                resultTo, options, userId);
3317        return ret;
3318    }
3319
3320    final void addRecentTaskLocked(TaskRecord task) {
3321        int N = mRecentTasks.size();
3322        // Quick case: check if the top-most recent task is the same.
3323        if (N > 0 && mRecentTasks.get(0) == task) {
3324            return;
3325        }
3326        // Remove any existing entries that are the same kind of task.
3327        final Intent intent = task.intent;
3328        final boolean document = intent != null && intent.isDocument();
3329        for (int i=0; i<N; i++) {
3330            TaskRecord tr = mRecentTasks.get(i);
3331            if (task != tr) {
3332                if (task.userId != tr.userId) {
3333                    continue;
3334                }
3335                final Intent trIntent = tr.intent;
3336                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3337                    (intent == null || !intent.filterEquals(trIntent))) {
3338                    continue;
3339                }
3340                if (document || trIntent != null && trIntent.isDocument()) {
3341                    // Document tasks do not match other tasks.
3342                    continue;
3343                }
3344            }
3345
3346            // Either task and tr are the same or, their affinities match or their intents match
3347            // and neither of them is a document.
3348            tr.disposeThumbnail();
3349            mRecentTasks.remove(i);
3350            i--;
3351            N--;
3352            if (task.intent == null) {
3353                // If the new recent task we are adding is not fully
3354                // specified, then replace it with the existing recent task.
3355                task = tr;
3356            }
3357        }
3358        if (N >= MAX_RECENT_TASKS) {
3359            mRecentTasks.remove(N-1).disposeThumbnail();
3360        }
3361        mRecentTasks.add(0, task);
3362    }
3363
3364    @Override
3365    public void reportActivityFullyDrawn(IBinder token) {
3366        synchronized (this) {
3367            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3368            if (r == null) {
3369                return;
3370            }
3371            r.reportFullyDrawnLocked();
3372        }
3373    }
3374
3375    @Override
3376    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3377        synchronized (this) {
3378            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3379            if (r == null) {
3380                return;
3381            }
3382            final long origId = Binder.clearCallingIdentity();
3383            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3384            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3385                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3386            if (config != null) {
3387                r.frozenBeforeDestroy = true;
3388                if (!updateConfigurationLocked(config, r, false, false)) {
3389                    mStackSupervisor.resumeTopActivitiesLocked();
3390                }
3391            }
3392            Binder.restoreCallingIdentity(origId);
3393        }
3394    }
3395
3396    @Override
3397    public int getRequestedOrientation(IBinder token) {
3398        synchronized (this) {
3399            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3400            if (r == null) {
3401                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3402            }
3403            return mWindowManager.getAppOrientation(r.appToken);
3404        }
3405    }
3406
3407    /**
3408     * This is the internal entry point for handling Activity.finish().
3409     *
3410     * @param token The Binder token referencing the Activity we want to finish.
3411     * @param resultCode Result code, if any, from this Activity.
3412     * @param resultData Result data (Intent), if any, from this Activity.
3413     *
3414     * @return Returns true if the activity successfully finished, or false if it is still running.
3415     */
3416    @Override
3417    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3418        // Refuse possible leaked file descriptors
3419        if (resultData != null && resultData.hasFileDescriptors() == true) {
3420            throw new IllegalArgumentException("File descriptors passed in Intent");
3421        }
3422
3423        synchronized(this) {
3424            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3425            if (r == null) {
3426                return true;
3427            }
3428            if (mController != null) {
3429                // Find the first activity that is not finishing.
3430                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3431                if (next != null) {
3432                    // ask watcher if this is allowed
3433                    boolean resumeOK = true;
3434                    try {
3435                        resumeOK = mController.activityResuming(next.packageName);
3436                    } catch (RemoteException e) {
3437                        mController = null;
3438                        Watchdog.getInstance().setActivityController(null);
3439                    }
3440
3441                    if (!resumeOK) {
3442                        return false;
3443                    }
3444                }
3445            }
3446            final long origId = Binder.clearCallingIdentity();
3447            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3448                    resultData, "app-request", true);
3449            Binder.restoreCallingIdentity(origId);
3450            return res;
3451        }
3452    }
3453
3454    @Override
3455    public final void finishHeavyWeightApp() {
3456        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3457                != PackageManager.PERMISSION_GRANTED) {
3458            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3459                    + Binder.getCallingPid()
3460                    + ", uid=" + Binder.getCallingUid()
3461                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3462            Slog.w(TAG, msg);
3463            throw new SecurityException(msg);
3464        }
3465
3466        synchronized(this) {
3467            if (mHeavyWeightProcess == null) {
3468                return;
3469            }
3470
3471            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3472                    mHeavyWeightProcess.activities);
3473            for (int i=0; i<activities.size(); i++) {
3474                ActivityRecord r = activities.get(i);
3475                if (!r.finishing) {
3476                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3477                            null, "finish-heavy", true);
3478                }
3479            }
3480
3481            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3482                    mHeavyWeightProcess.userId, 0));
3483            mHeavyWeightProcess = null;
3484        }
3485    }
3486
3487    @Override
3488    public void crashApplication(int uid, int initialPid, String packageName,
3489            String message) {
3490        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3491                != PackageManager.PERMISSION_GRANTED) {
3492            String msg = "Permission Denial: crashApplication() from pid="
3493                    + Binder.getCallingPid()
3494                    + ", uid=" + Binder.getCallingUid()
3495                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3496            Slog.w(TAG, msg);
3497            throw new SecurityException(msg);
3498        }
3499
3500        synchronized(this) {
3501            ProcessRecord proc = null;
3502
3503            // Figure out which process to kill.  We don't trust that initialPid
3504            // still has any relation to current pids, so must scan through the
3505            // list.
3506            synchronized (mPidsSelfLocked) {
3507                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3508                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3509                    if (p.uid != uid) {
3510                        continue;
3511                    }
3512                    if (p.pid == initialPid) {
3513                        proc = p;
3514                        break;
3515                    }
3516                    if (p.pkgList.containsKey(packageName)) {
3517                        proc = p;
3518                    }
3519                }
3520            }
3521
3522            if (proc == null) {
3523                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3524                        + " initialPid=" + initialPid
3525                        + " packageName=" + packageName);
3526                return;
3527            }
3528
3529            if (proc.thread != null) {
3530                if (proc.pid == Process.myPid()) {
3531                    Log.w(TAG, "crashApplication: trying to crash self!");
3532                    return;
3533                }
3534                long ident = Binder.clearCallingIdentity();
3535                try {
3536                    proc.thread.scheduleCrash(message);
3537                } catch (RemoteException e) {
3538                }
3539                Binder.restoreCallingIdentity(ident);
3540            }
3541        }
3542    }
3543
3544    @Override
3545    public final void finishSubActivity(IBinder token, String resultWho,
3546            int requestCode) {
3547        synchronized(this) {
3548            final long origId = Binder.clearCallingIdentity();
3549            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3550            if (r != null) {
3551                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3552            }
3553            Binder.restoreCallingIdentity(origId);
3554        }
3555    }
3556
3557    @Override
3558    public boolean finishActivityAffinity(IBinder token) {
3559        synchronized(this) {
3560            final long origId = Binder.clearCallingIdentity();
3561            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3562            boolean res = false;
3563            if (r != null) {
3564                res = r.task.stack.finishActivityAffinityLocked(r);
3565            }
3566            Binder.restoreCallingIdentity(origId);
3567            return res;
3568        }
3569    }
3570
3571    @Override
3572    public boolean willActivityBeVisible(IBinder token) {
3573        synchronized(this) {
3574            ActivityStack stack = ActivityRecord.getStackLocked(token);
3575            if (stack != null) {
3576                return stack.willActivityBeVisibleLocked(token);
3577            }
3578            return false;
3579        }
3580    }
3581
3582    @Override
3583    public void overridePendingTransition(IBinder token, String packageName,
3584            int enterAnim, int exitAnim) {
3585        synchronized(this) {
3586            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3587            if (self == null) {
3588                return;
3589            }
3590
3591            final long origId = Binder.clearCallingIdentity();
3592
3593            if (self.state == ActivityState.RESUMED
3594                    || self.state == ActivityState.PAUSING) {
3595                mWindowManager.overridePendingAppTransition(packageName,
3596                        enterAnim, exitAnim, null);
3597            }
3598
3599            Binder.restoreCallingIdentity(origId);
3600        }
3601    }
3602
3603    /**
3604     * Main function for removing an existing process from the activity manager
3605     * as a result of that process going away.  Clears out all connections
3606     * to the process.
3607     */
3608    private final void handleAppDiedLocked(ProcessRecord app,
3609            boolean restarting, boolean allowRestart) {
3610        int pid = app.pid;
3611        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3612        if (!restarting) {
3613            removeLruProcessLocked(app);
3614            if (pid > 0) {
3615                ProcessList.remove(pid);
3616            }
3617        }
3618
3619        if (mProfileProc == app) {
3620            clearProfilerLocked();
3621        }
3622
3623        // Remove this application's activities from active lists.
3624        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3625
3626        app.activities.clear();
3627
3628        if (app.instrumentationClass != null) {
3629            Slog.w(TAG, "Crash of app " + app.processName
3630                  + " running instrumentation " + app.instrumentationClass);
3631            Bundle info = new Bundle();
3632            info.putString("shortMsg", "Process crashed.");
3633            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3634        }
3635
3636        if (!restarting) {
3637            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3638                // If there was nothing to resume, and we are not already
3639                // restarting this process, but there is a visible activity that
3640                // is hosted by the process...  then make sure all visible
3641                // activities are running, taking care of restarting this
3642                // process.
3643                if (hasVisibleActivities) {
3644                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3645                }
3646            }
3647        }
3648    }
3649
3650    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3651        IBinder threadBinder = thread.asBinder();
3652        // Find the application record.
3653        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3654            ProcessRecord rec = mLruProcesses.get(i);
3655            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3656                return i;
3657            }
3658        }
3659        return -1;
3660    }
3661
3662    final ProcessRecord getRecordForAppLocked(
3663            IApplicationThread thread) {
3664        if (thread == null) {
3665            return null;
3666        }
3667
3668        int appIndex = getLRURecordIndexForAppLocked(thread);
3669        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3670    }
3671
3672    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3673        // If there are no longer any background processes running,
3674        // and the app that died was not running instrumentation,
3675        // then tell everyone we are now low on memory.
3676        boolean haveBg = false;
3677        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3678            ProcessRecord rec = mLruProcesses.get(i);
3679            if (rec.thread != null
3680                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3681                haveBg = true;
3682                break;
3683            }
3684        }
3685
3686        if (!haveBg) {
3687            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3688            if (doReport) {
3689                long now = SystemClock.uptimeMillis();
3690                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3691                    doReport = false;
3692                } else {
3693                    mLastMemUsageReportTime = now;
3694                }
3695            }
3696            final ArrayList<ProcessMemInfo> memInfos
3697                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3698            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3699            long now = SystemClock.uptimeMillis();
3700            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3701                ProcessRecord rec = mLruProcesses.get(i);
3702                if (rec == dyingProc || rec.thread == null) {
3703                    continue;
3704                }
3705                if (doReport) {
3706                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3707                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3708                }
3709                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3710                    // The low memory report is overriding any current
3711                    // state for a GC request.  Make sure to do
3712                    // heavy/important/visible/foreground processes first.
3713                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3714                        rec.lastRequestedGc = 0;
3715                    } else {
3716                        rec.lastRequestedGc = rec.lastLowMemory;
3717                    }
3718                    rec.reportLowMemory = true;
3719                    rec.lastLowMemory = now;
3720                    mProcessesToGc.remove(rec);
3721                    addProcessToGcListLocked(rec);
3722                }
3723            }
3724            if (doReport) {
3725                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3726                mHandler.sendMessage(msg);
3727            }
3728            scheduleAppGcsLocked();
3729        }
3730    }
3731
3732    final void appDiedLocked(ProcessRecord app, int pid,
3733            IApplicationThread thread) {
3734
3735        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3736        synchronized (stats) {
3737            stats.noteProcessDiedLocked(app.info.uid, pid);
3738        }
3739
3740        // Clean up already done if the process has been re-started.
3741        if (app.pid == pid && app.thread != null &&
3742                app.thread.asBinder() == thread.asBinder()) {
3743            boolean doLowMem = app.instrumentationClass == null;
3744            boolean doOomAdj = doLowMem;
3745            if (!app.killedByAm) {
3746                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3747                        + ") has died.");
3748                mAllowLowerMemLevel = true;
3749            } else {
3750                // Note that we always want to do oom adj to update our state with the
3751                // new number of procs.
3752                mAllowLowerMemLevel = false;
3753                doLowMem = false;
3754            }
3755            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3756            if (DEBUG_CLEANUP) Slog.v(
3757                TAG, "Dying app: " + app + ", pid: " + pid
3758                + ", thread: " + thread.asBinder());
3759            handleAppDiedLocked(app, false, true);
3760
3761            if (doOomAdj) {
3762                updateOomAdjLocked();
3763            }
3764            if (doLowMem) {
3765                doLowMemReportIfNeededLocked(app);
3766            }
3767        } else if (app.pid != pid) {
3768            // A new process has already been started.
3769            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3770                    + ") has died and restarted (pid " + app.pid + ").");
3771            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3772        } else if (DEBUG_PROCESSES) {
3773            Slog.d(TAG, "Received spurious death notification for thread "
3774                    + thread.asBinder());
3775        }
3776    }
3777
3778    /**
3779     * If a stack trace dump file is configured, dump process stack traces.
3780     * @param clearTraces causes the dump file to be erased prior to the new
3781     *    traces being written, if true; when false, the new traces will be
3782     *    appended to any existing file content.
3783     * @param firstPids of dalvik VM processes to dump stack traces for first
3784     * @param lastPids of dalvik VM processes to dump stack traces for last
3785     * @param nativeProcs optional list of native process names to dump stack crawls
3786     * @return file containing stack traces, or null if no dump file is configured
3787     */
3788    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3789            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3790        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3791        if (tracesPath == null || tracesPath.length() == 0) {
3792            return null;
3793        }
3794
3795        File tracesFile = new File(tracesPath);
3796        try {
3797            File tracesDir = tracesFile.getParentFile();
3798            if (!tracesDir.exists()) {
3799                tracesFile.mkdirs();
3800                if (!SELinux.restorecon(tracesDir)) {
3801                    return null;
3802                }
3803            }
3804            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3805
3806            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3807            tracesFile.createNewFile();
3808            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3809        } catch (IOException e) {
3810            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3811            return null;
3812        }
3813
3814        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3815        return tracesFile;
3816    }
3817
3818    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3819            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3820        // Use a FileObserver to detect when traces finish writing.
3821        // The order of traces is considered important to maintain for legibility.
3822        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3823            @Override
3824            public synchronized void onEvent(int event, String path) { notify(); }
3825        };
3826
3827        try {
3828            observer.startWatching();
3829
3830            // First collect all of the stacks of the most important pids.
3831            if (firstPids != null) {
3832                try {
3833                    int num = firstPids.size();
3834                    for (int i = 0; i < num; i++) {
3835                        synchronized (observer) {
3836                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3837                            observer.wait(200);  // Wait for write-close, give up after 200msec
3838                        }
3839                    }
3840                } catch (InterruptedException e) {
3841                    Log.wtf(TAG, e);
3842                }
3843            }
3844
3845            // Next collect the stacks of the native pids
3846            if (nativeProcs != null) {
3847                int[] pids = Process.getPidsForCommands(nativeProcs);
3848                if (pids != null) {
3849                    for (int pid : pids) {
3850                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3851                    }
3852                }
3853            }
3854
3855            // Lastly, measure CPU usage.
3856            if (processCpuTracker != null) {
3857                processCpuTracker.init();
3858                System.gc();
3859                processCpuTracker.update();
3860                try {
3861                    synchronized (processCpuTracker) {
3862                        processCpuTracker.wait(500); // measure over 1/2 second.
3863                    }
3864                } catch (InterruptedException e) {
3865                }
3866                processCpuTracker.update();
3867
3868                // We'll take the stack crawls of just the top apps using CPU.
3869                final int N = processCpuTracker.countWorkingStats();
3870                int numProcs = 0;
3871                for (int i=0; i<N && numProcs<5; i++) {
3872                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3873                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3874                        numProcs++;
3875                        try {
3876                            synchronized (observer) {
3877                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3878                                observer.wait(200);  // Wait for write-close, give up after 200msec
3879                            }
3880                        } catch (InterruptedException e) {
3881                            Log.wtf(TAG, e);
3882                        }
3883
3884                    }
3885                }
3886            }
3887        } finally {
3888            observer.stopWatching();
3889        }
3890    }
3891
3892    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3893        if (true || IS_USER_BUILD) {
3894            return;
3895        }
3896        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3897        if (tracesPath == null || tracesPath.length() == 0) {
3898            return;
3899        }
3900
3901        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3902        StrictMode.allowThreadDiskWrites();
3903        try {
3904            final File tracesFile = new File(tracesPath);
3905            final File tracesDir = tracesFile.getParentFile();
3906            final File tracesTmp = new File(tracesDir, "__tmp__");
3907            try {
3908                if (!tracesDir.exists()) {
3909                    tracesFile.mkdirs();
3910                    if (!SELinux.restorecon(tracesDir.getPath())) {
3911                        return;
3912                    }
3913                }
3914                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3915
3916                if (tracesFile.exists()) {
3917                    tracesTmp.delete();
3918                    tracesFile.renameTo(tracesTmp);
3919                }
3920                StringBuilder sb = new StringBuilder();
3921                Time tobj = new Time();
3922                tobj.set(System.currentTimeMillis());
3923                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3924                sb.append(": ");
3925                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3926                sb.append(" since ");
3927                sb.append(msg);
3928                FileOutputStream fos = new FileOutputStream(tracesFile);
3929                fos.write(sb.toString().getBytes());
3930                if (app == null) {
3931                    fos.write("\n*** No application process!".getBytes());
3932                }
3933                fos.close();
3934                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3935            } catch (IOException e) {
3936                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3937                return;
3938            }
3939
3940            if (app != null) {
3941                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3942                firstPids.add(app.pid);
3943                dumpStackTraces(tracesPath, firstPids, null, null, null);
3944            }
3945
3946            File lastTracesFile = null;
3947            File curTracesFile = null;
3948            for (int i=9; i>=0; i--) {
3949                String name = String.format(Locale.US, "slow%02d.txt", i);
3950                curTracesFile = new File(tracesDir, name);
3951                if (curTracesFile.exists()) {
3952                    if (lastTracesFile != null) {
3953                        curTracesFile.renameTo(lastTracesFile);
3954                    } else {
3955                        curTracesFile.delete();
3956                    }
3957                }
3958                lastTracesFile = curTracesFile;
3959            }
3960            tracesFile.renameTo(curTracesFile);
3961            if (tracesTmp.exists()) {
3962                tracesTmp.renameTo(tracesFile);
3963            }
3964        } finally {
3965            StrictMode.setThreadPolicy(oldPolicy);
3966        }
3967    }
3968
3969    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3970            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3971        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3972        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3973
3974        if (mController != null) {
3975            try {
3976                // 0 == continue, -1 = kill process immediately
3977                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3978                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3979            } catch (RemoteException e) {
3980                mController = null;
3981                Watchdog.getInstance().setActivityController(null);
3982            }
3983        }
3984
3985        long anrTime = SystemClock.uptimeMillis();
3986        if (MONITOR_CPU_USAGE) {
3987            updateCpuStatsNow();
3988        }
3989
3990        synchronized (this) {
3991            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3992            if (mShuttingDown) {
3993                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3994                return;
3995            } else if (app.notResponding) {
3996                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3997                return;
3998            } else if (app.crashing) {
3999                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4000                return;
4001            }
4002
4003            // In case we come through here for the same app before completing
4004            // this one, mark as anring now so we will bail out.
4005            app.notResponding = true;
4006
4007            // Log the ANR to the event log.
4008            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4009                    app.processName, app.info.flags, annotation);
4010
4011            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4012            firstPids.add(app.pid);
4013
4014            int parentPid = app.pid;
4015            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4016            if (parentPid != app.pid) firstPids.add(parentPid);
4017
4018            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4019
4020            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4021                ProcessRecord r = mLruProcesses.get(i);
4022                if (r != null && r.thread != null) {
4023                    int pid = r.pid;
4024                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4025                        if (r.persistent) {
4026                            firstPids.add(pid);
4027                        } else {
4028                            lastPids.put(pid, Boolean.TRUE);
4029                        }
4030                    }
4031                }
4032            }
4033        }
4034
4035        // Log the ANR to the main log.
4036        StringBuilder info = new StringBuilder();
4037        info.setLength(0);
4038        info.append("ANR in ").append(app.processName);
4039        if (activity != null && activity.shortComponentName != null) {
4040            info.append(" (").append(activity.shortComponentName).append(")");
4041        }
4042        info.append("\n");
4043        info.append("PID: ").append(app.pid).append("\n");
4044        if (annotation != null) {
4045            info.append("Reason: ").append(annotation).append("\n");
4046        }
4047        if (parent != null && parent != activity) {
4048            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4049        }
4050
4051        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4052
4053        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4054                NATIVE_STACKS_OF_INTEREST);
4055
4056        String cpuInfo = null;
4057        if (MONITOR_CPU_USAGE) {
4058            updateCpuStatsNow();
4059            synchronized (mProcessCpuThread) {
4060                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4061            }
4062            info.append(processCpuTracker.printCurrentLoad());
4063            info.append(cpuInfo);
4064        }
4065
4066        info.append(processCpuTracker.printCurrentState(anrTime));
4067
4068        Slog.e(TAG, info.toString());
4069        if (tracesFile == null) {
4070            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4071            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4072        }
4073
4074        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4075                cpuInfo, tracesFile, null);
4076
4077        if (mController != null) {
4078            try {
4079                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4080                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4081                if (res != 0) {
4082                    if (res < 0 && app.pid != MY_PID) {
4083                        Process.killProcess(app.pid);
4084                    } else {
4085                        synchronized (this) {
4086                            mServices.scheduleServiceTimeoutLocked(app);
4087                        }
4088                    }
4089                    return;
4090                }
4091            } catch (RemoteException e) {
4092                mController = null;
4093                Watchdog.getInstance().setActivityController(null);
4094            }
4095        }
4096
4097        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4098        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4099                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4100
4101        synchronized (this) {
4102            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4103                killUnneededProcessLocked(app, "background ANR");
4104                return;
4105            }
4106
4107            // Set the app's notResponding state, and look up the errorReportReceiver
4108            makeAppNotRespondingLocked(app,
4109                    activity != null ? activity.shortComponentName : null,
4110                    annotation != null ? "ANR " + annotation : "ANR",
4111                    info.toString());
4112
4113            // Bring up the infamous App Not Responding dialog
4114            Message msg = Message.obtain();
4115            HashMap<String, Object> map = new HashMap<String, Object>();
4116            msg.what = SHOW_NOT_RESPONDING_MSG;
4117            msg.obj = map;
4118            msg.arg1 = aboveSystem ? 1 : 0;
4119            map.put("app", app);
4120            if (activity != null) {
4121                map.put("activity", activity);
4122            }
4123
4124            mHandler.sendMessage(msg);
4125        }
4126    }
4127
4128    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4129        if (!mLaunchWarningShown) {
4130            mLaunchWarningShown = true;
4131            mHandler.post(new Runnable() {
4132                @Override
4133                public void run() {
4134                    synchronized (ActivityManagerService.this) {
4135                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4136                        d.show();
4137                        mHandler.postDelayed(new Runnable() {
4138                            @Override
4139                            public void run() {
4140                                synchronized (ActivityManagerService.this) {
4141                                    d.dismiss();
4142                                    mLaunchWarningShown = false;
4143                                }
4144                            }
4145                        }, 4000);
4146                    }
4147                }
4148            });
4149        }
4150    }
4151
4152    @Override
4153    public boolean clearApplicationUserData(final String packageName,
4154            final IPackageDataObserver observer, int userId) {
4155        enforceNotIsolatedCaller("clearApplicationUserData");
4156        int uid = Binder.getCallingUid();
4157        int pid = Binder.getCallingPid();
4158        userId = handleIncomingUser(pid, uid,
4159                userId, false, true, "clearApplicationUserData", null);
4160        long callingId = Binder.clearCallingIdentity();
4161        try {
4162            IPackageManager pm = AppGlobals.getPackageManager();
4163            int pkgUid = -1;
4164            synchronized(this) {
4165                try {
4166                    pkgUid = pm.getPackageUid(packageName, userId);
4167                } catch (RemoteException e) {
4168                }
4169                if (pkgUid == -1) {
4170                    Slog.w(TAG, "Invalid packageName: " + packageName);
4171                    if (observer != null) {
4172                        try {
4173                            observer.onRemoveCompleted(packageName, false);
4174                        } catch (RemoteException e) {
4175                            Slog.i(TAG, "Observer no longer exists.");
4176                        }
4177                    }
4178                    return false;
4179                }
4180                if (uid == pkgUid || checkComponentPermission(
4181                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4182                        pid, uid, -1, true)
4183                        == PackageManager.PERMISSION_GRANTED) {
4184                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4185                } else {
4186                    throw new SecurityException("PID " + pid + " does not have permission "
4187                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4188                                    + " of package " + packageName);
4189                }
4190            }
4191
4192            try {
4193                // Clear application user data
4194                pm.clearApplicationUserData(packageName, observer, userId);
4195
4196                // Remove all permissions granted from/to this package
4197                removeUriPermissionsForPackageLocked(packageName, userId, true);
4198
4199                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4200                        Uri.fromParts("package", packageName, null));
4201                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4202                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4203                        null, null, 0, null, null, null, false, false, userId);
4204            } catch (RemoteException e) {
4205            }
4206        } finally {
4207            Binder.restoreCallingIdentity(callingId);
4208        }
4209        return true;
4210    }
4211
4212    @Override
4213    public void killBackgroundProcesses(final String packageName, int userId) {
4214        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4215                != PackageManager.PERMISSION_GRANTED &&
4216                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4217                        != PackageManager.PERMISSION_GRANTED) {
4218            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4219                    + Binder.getCallingPid()
4220                    + ", uid=" + Binder.getCallingUid()
4221                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4222            Slog.w(TAG, msg);
4223            throw new SecurityException(msg);
4224        }
4225
4226        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4227                userId, true, true, "killBackgroundProcesses", null);
4228        long callingId = Binder.clearCallingIdentity();
4229        try {
4230            IPackageManager pm = AppGlobals.getPackageManager();
4231            synchronized(this) {
4232                int appId = -1;
4233                try {
4234                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4235                } catch (RemoteException e) {
4236                }
4237                if (appId == -1) {
4238                    Slog.w(TAG, "Invalid packageName: " + packageName);
4239                    return;
4240                }
4241                killPackageProcessesLocked(packageName, appId, userId,
4242                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4243            }
4244        } finally {
4245            Binder.restoreCallingIdentity(callingId);
4246        }
4247    }
4248
4249    @Override
4250    public void killAllBackgroundProcesses() {
4251        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4252                != PackageManager.PERMISSION_GRANTED) {
4253            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4254                    + Binder.getCallingPid()
4255                    + ", uid=" + Binder.getCallingUid()
4256                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4257            Slog.w(TAG, msg);
4258            throw new SecurityException(msg);
4259        }
4260
4261        long callingId = Binder.clearCallingIdentity();
4262        try {
4263            synchronized(this) {
4264                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4265                final int NP = mProcessNames.getMap().size();
4266                for (int ip=0; ip<NP; ip++) {
4267                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4268                    final int NA = apps.size();
4269                    for (int ia=0; ia<NA; ia++) {
4270                        ProcessRecord app = apps.valueAt(ia);
4271                        if (app.persistent) {
4272                            // we don't kill persistent processes
4273                            continue;
4274                        }
4275                        if (app.removed) {
4276                            procs.add(app);
4277                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4278                            app.removed = true;
4279                            procs.add(app);
4280                        }
4281                    }
4282                }
4283
4284                int N = procs.size();
4285                for (int i=0; i<N; i++) {
4286                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4287                }
4288                mAllowLowerMemLevel = true;
4289                updateOomAdjLocked();
4290                doLowMemReportIfNeededLocked(null);
4291            }
4292        } finally {
4293            Binder.restoreCallingIdentity(callingId);
4294        }
4295    }
4296
4297    @Override
4298    public void forceStopPackage(final String packageName, int userId) {
4299        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4300                != PackageManager.PERMISSION_GRANTED) {
4301            String msg = "Permission Denial: forceStopPackage() from pid="
4302                    + Binder.getCallingPid()
4303                    + ", uid=" + Binder.getCallingUid()
4304                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4305            Slog.w(TAG, msg);
4306            throw new SecurityException(msg);
4307        }
4308        final int callingPid = Binder.getCallingPid();
4309        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4310                userId, true, true, "forceStopPackage", null);
4311        long callingId = Binder.clearCallingIdentity();
4312        try {
4313            IPackageManager pm = AppGlobals.getPackageManager();
4314            synchronized(this) {
4315                int[] users = userId == UserHandle.USER_ALL
4316                        ? getUsersLocked() : new int[] { userId };
4317                for (int user : users) {
4318                    int pkgUid = -1;
4319                    try {
4320                        pkgUid = pm.getPackageUid(packageName, user);
4321                    } catch (RemoteException e) {
4322                    }
4323                    if (pkgUid == -1) {
4324                        Slog.w(TAG, "Invalid packageName: " + packageName);
4325                        continue;
4326                    }
4327                    try {
4328                        pm.setPackageStoppedState(packageName, true, user);
4329                    } catch (RemoteException e) {
4330                    } catch (IllegalArgumentException e) {
4331                        Slog.w(TAG, "Failed trying to unstop package "
4332                                + packageName + ": " + e);
4333                    }
4334                    if (isUserRunningLocked(user, false)) {
4335                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4336                    }
4337                }
4338            }
4339        } finally {
4340            Binder.restoreCallingIdentity(callingId);
4341        }
4342    }
4343
4344    /*
4345     * The pkg name and app id have to be specified.
4346     */
4347    @Override
4348    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4349        if (pkg == null) {
4350            return;
4351        }
4352        // Make sure the uid is valid.
4353        if (appid < 0) {
4354            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4355            return;
4356        }
4357        int callerUid = Binder.getCallingUid();
4358        // Only the system server can kill an application
4359        if (callerUid == Process.SYSTEM_UID) {
4360            // Post an aysnc message to kill the application
4361            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4362            msg.arg1 = appid;
4363            msg.arg2 = 0;
4364            Bundle bundle = new Bundle();
4365            bundle.putString("pkg", pkg);
4366            bundle.putString("reason", reason);
4367            msg.obj = bundle;
4368            mHandler.sendMessage(msg);
4369        } else {
4370            throw new SecurityException(callerUid + " cannot kill pkg: " +
4371                    pkg);
4372        }
4373    }
4374
4375    @Override
4376    public void closeSystemDialogs(String reason) {
4377        enforceNotIsolatedCaller("closeSystemDialogs");
4378
4379        final int pid = Binder.getCallingPid();
4380        final int uid = Binder.getCallingUid();
4381        final long origId = Binder.clearCallingIdentity();
4382        try {
4383            synchronized (this) {
4384                // Only allow this from foreground processes, so that background
4385                // applications can't abuse it to prevent system UI from being shown.
4386                if (uid >= Process.FIRST_APPLICATION_UID) {
4387                    ProcessRecord proc;
4388                    synchronized (mPidsSelfLocked) {
4389                        proc = mPidsSelfLocked.get(pid);
4390                    }
4391                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4392                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4393                                + " from background process " + proc);
4394                        return;
4395                    }
4396                }
4397                closeSystemDialogsLocked(reason);
4398            }
4399        } finally {
4400            Binder.restoreCallingIdentity(origId);
4401        }
4402    }
4403
4404    void closeSystemDialogsLocked(String reason) {
4405        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4406        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4407                | Intent.FLAG_RECEIVER_FOREGROUND);
4408        if (reason != null) {
4409            intent.putExtra("reason", reason);
4410        }
4411        mWindowManager.closeSystemDialogs(reason);
4412
4413        mStackSupervisor.closeSystemDialogsLocked();
4414
4415        broadcastIntentLocked(null, null, intent, null,
4416                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4417                Process.SYSTEM_UID, UserHandle.USER_ALL);
4418    }
4419
4420    @Override
4421    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4422        enforceNotIsolatedCaller("getProcessMemoryInfo");
4423        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4424        for (int i=pids.length-1; i>=0; i--) {
4425            ProcessRecord proc;
4426            int oomAdj;
4427            synchronized (this) {
4428                synchronized (mPidsSelfLocked) {
4429                    proc = mPidsSelfLocked.get(pids[i]);
4430                    oomAdj = proc != null ? proc.setAdj : 0;
4431                }
4432            }
4433            infos[i] = new Debug.MemoryInfo();
4434            Debug.getMemoryInfo(pids[i], infos[i]);
4435            if (proc != null) {
4436                synchronized (this) {
4437                    if (proc.thread != null && proc.setAdj == oomAdj) {
4438                        // Record this for posterity if the process has been stable.
4439                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4440                                infos[i].getTotalUss(), false, proc.pkgList);
4441                    }
4442                }
4443            }
4444        }
4445        return infos;
4446    }
4447
4448    @Override
4449    public long[] getProcessPss(int[] pids) {
4450        enforceNotIsolatedCaller("getProcessPss");
4451        long[] pss = new long[pids.length];
4452        for (int i=pids.length-1; i>=0; i--) {
4453            ProcessRecord proc;
4454            int oomAdj;
4455            synchronized (this) {
4456                synchronized (mPidsSelfLocked) {
4457                    proc = mPidsSelfLocked.get(pids[i]);
4458                    oomAdj = proc != null ? proc.setAdj : 0;
4459                }
4460            }
4461            long[] tmpUss = new long[1];
4462            pss[i] = Debug.getPss(pids[i], tmpUss);
4463            if (proc != null) {
4464                synchronized (this) {
4465                    if (proc.thread != null && proc.setAdj == oomAdj) {
4466                        // Record this for posterity if the process has been stable.
4467                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4468                    }
4469                }
4470            }
4471        }
4472        return pss;
4473    }
4474
4475    @Override
4476    public void killApplicationProcess(String processName, int uid) {
4477        if (processName == null) {
4478            return;
4479        }
4480
4481        int callerUid = Binder.getCallingUid();
4482        // Only the system server can kill an application
4483        if (callerUid == Process.SYSTEM_UID) {
4484            synchronized (this) {
4485                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4486                if (app != null && app.thread != null) {
4487                    try {
4488                        app.thread.scheduleSuicide();
4489                    } catch (RemoteException e) {
4490                        // If the other end already died, then our work here is done.
4491                    }
4492                } else {
4493                    Slog.w(TAG, "Process/uid not found attempting kill of "
4494                            + processName + " / " + uid);
4495                }
4496            }
4497        } else {
4498            throw new SecurityException(callerUid + " cannot kill app process: " +
4499                    processName);
4500        }
4501    }
4502
4503    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4504        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4505                false, true, false, false, UserHandle.getUserId(uid), reason);
4506        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4507                Uri.fromParts("package", packageName, null));
4508        if (!mProcessesReady) {
4509            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4510                    | Intent.FLAG_RECEIVER_FOREGROUND);
4511        }
4512        intent.putExtra(Intent.EXTRA_UID, uid);
4513        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4514        broadcastIntentLocked(null, null, intent,
4515                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4516                false, false,
4517                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4518    }
4519
4520    private void forceStopUserLocked(int userId, String reason) {
4521        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4522        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4523        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4524                | Intent.FLAG_RECEIVER_FOREGROUND);
4525        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4526        broadcastIntentLocked(null, null, intent,
4527                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4528                false, false,
4529                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4530    }
4531
4532    private final boolean killPackageProcessesLocked(String packageName, int appId,
4533            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4534            boolean doit, boolean evenPersistent, String reason) {
4535        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4536
4537        // Remove all processes this package may have touched: all with the
4538        // same UID (except for the system or root user), and all whose name
4539        // matches the package name.
4540        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4541        final int NP = mProcessNames.getMap().size();
4542        for (int ip=0; ip<NP; ip++) {
4543            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4544            final int NA = apps.size();
4545            for (int ia=0; ia<NA; ia++) {
4546                ProcessRecord app = apps.valueAt(ia);
4547                if (app.persistent && !evenPersistent) {
4548                    // we don't kill persistent processes
4549                    continue;
4550                }
4551                if (app.removed) {
4552                    if (doit) {
4553                        procs.add(app);
4554                    }
4555                    continue;
4556                }
4557
4558                // Skip process if it doesn't meet our oom adj requirement.
4559                if (app.setAdj < minOomAdj) {
4560                    continue;
4561                }
4562
4563                // If no package is specified, we call all processes under the
4564                // give user id.
4565                if (packageName == null) {
4566                    if (app.userId != userId) {
4567                        continue;
4568                    }
4569                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4570                        continue;
4571                    }
4572                // Package has been specified, we want to hit all processes
4573                // that match it.  We need to qualify this by the processes
4574                // that are running under the specified app and user ID.
4575                } else {
4576                    if (UserHandle.getAppId(app.uid) != appId) {
4577                        continue;
4578                    }
4579                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4580                        continue;
4581                    }
4582                    if (!app.pkgList.containsKey(packageName)) {
4583                        continue;
4584                    }
4585                }
4586
4587                // Process has passed all conditions, kill it!
4588                if (!doit) {
4589                    return true;
4590                }
4591                app.removed = true;
4592                procs.add(app);
4593            }
4594        }
4595
4596        int N = procs.size();
4597        for (int i=0; i<N; i++) {
4598            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4599        }
4600        updateOomAdjLocked();
4601        return N > 0;
4602    }
4603
4604    private final boolean forceStopPackageLocked(String name, int appId,
4605            boolean callerWillRestart, boolean purgeCache, boolean doit,
4606            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4607        int i;
4608        int N;
4609
4610        if (userId == UserHandle.USER_ALL && name == null) {
4611            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4612        }
4613
4614        if (appId < 0 && name != null) {
4615            try {
4616                appId = UserHandle.getAppId(
4617                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4618            } catch (RemoteException e) {
4619            }
4620        }
4621
4622        if (doit) {
4623            if (name != null) {
4624                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4625                        + " user=" + userId + ": " + reason);
4626            } else {
4627                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4628            }
4629
4630            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4631            for (int ip=pmap.size()-1; ip>=0; ip--) {
4632                SparseArray<Long> ba = pmap.valueAt(ip);
4633                for (i=ba.size()-1; i>=0; i--) {
4634                    boolean remove = false;
4635                    final int entUid = ba.keyAt(i);
4636                    if (name != null) {
4637                        if (userId == UserHandle.USER_ALL) {
4638                            if (UserHandle.getAppId(entUid) == appId) {
4639                                remove = true;
4640                            }
4641                        } else {
4642                            if (entUid == UserHandle.getUid(userId, appId)) {
4643                                remove = true;
4644                            }
4645                        }
4646                    } else if (UserHandle.getUserId(entUid) == userId) {
4647                        remove = true;
4648                    }
4649                    if (remove) {
4650                        ba.removeAt(i);
4651                    }
4652                }
4653                if (ba.size() == 0) {
4654                    pmap.removeAt(ip);
4655                }
4656            }
4657        }
4658
4659        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4660                -100, callerWillRestart, true, doit, evenPersistent,
4661                name == null ? ("stop user " + userId) : ("stop " + name));
4662
4663        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4664            if (!doit) {
4665                return true;
4666            }
4667            didSomething = true;
4668        }
4669
4670        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4671            if (!doit) {
4672                return true;
4673            }
4674            didSomething = true;
4675        }
4676
4677        if (name == null) {
4678            // Remove all sticky broadcasts from this user.
4679            mStickyBroadcasts.remove(userId);
4680        }
4681
4682        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4683        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4684                userId, providers)) {
4685            if (!doit) {
4686                return true;
4687            }
4688            didSomething = true;
4689        }
4690        N = providers.size();
4691        for (i=0; i<N; i++) {
4692            removeDyingProviderLocked(null, providers.get(i), true);
4693        }
4694
4695        // Remove transient permissions granted from/to this package/user
4696        removeUriPermissionsForPackageLocked(name, userId, false);
4697
4698        if (name == null || uninstalling) {
4699            // Remove pending intents.  For now we only do this when force
4700            // stopping users, because we have some problems when doing this
4701            // for packages -- app widgets are not currently cleaned up for
4702            // such packages, so they can be left with bad pending intents.
4703            if (mIntentSenderRecords.size() > 0) {
4704                Iterator<WeakReference<PendingIntentRecord>> it
4705                        = mIntentSenderRecords.values().iterator();
4706                while (it.hasNext()) {
4707                    WeakReference<PendingIntentRecord> wpir = it.next();
4708                    if (wpir == null) {
4709                        it.remove();
4710                        continue;
4711                    }
4712                    PendingIntentRecord pir = wpir.get();
4713                    if (pir == null) {
4714                        it.remove();
4715                        continue;
4716                    }
4717                    if (name == null) {
4718                        // Stopping user, remove all objects for the user.
4719                        if (pir.key.userId != userId) {
4720                            // Not the same user, skip it.
4721                            continue;
4722                        }
4723                    } else {
4724                        if (UserHandle.getAppId(pir.uid) != appId) {
4725                            // Different app id, skip it.
4726                            continue;
4727                        }
4728                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4729                            // Different user, skip it.
4730                            continue;
4731                        }
4732                        if (!pir.key.packageName.equals(name)) {
4733                            // Different package, skip it.
4734                            continue;
4735                        }
4736                    }
4737                    if (!doit) {
4738                        return true;
4739                    }
4740                    didSomething = true;
4741                    it.remove();
4742                    pir.canceled = true;
4743                    if (pir.key.activity != null) {
4744                        pir.key.activity.pendingResults.remove(pir.ref);
4745                    }
4746                }
4747            }
4748        }
4749
4750        if (doit) {
4751            if (purgeCache && name != null) {
4752                AttributeCache ac = AttributeCache.instance();
4753                if (ac != null) {
4754                    ac.removePackage(name);
4755                }
4756            }
4757            if (mBooted) {
4758                mStackSupervisor.resumeTopActivitiesLocked();
4759                mStackSupervisor.scheduleIdleLocked();
4760            }
4761        }
4762
4763        return didSomething;
4764    }
4765
4766    private final boolean removeProcessLocked(ProcessRecord app,
4767            boolean callerWillRestart, boolean allowRestart, String reason) {
4768        final String name = app.processName;
4769        final int uid = app.uid;
4770        if (DEBUG_PROCESSES) Slog.d(
4771            TAG, "Force removing proc " + app.toShortString() + " (" + name
4772            + "/" + uid + ")");
4773
4774        mProcessNames.remove(name, uid);
4775        mIsolatedProcesses.remove(app.uid);
4776        if (mHeavyWeightProcess == app) {
4777            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4778                    mHeavyWeightProcess.userId, 0));
4779            mHeavyWeightProcess = null;
4780        }
4781        boolean needRestart = false;
4782        if (app.pid > 0 && app.pid != MY_PID) {
4783            int pid = app.pid;
4784            synchronized (mPidsSelfLocked) {
4785                mPidsSelfLocked.remove(pid);
4786                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4787            }
4788            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4789                    app.processName, app.info.uid);
4790            if (app.isolated) {
4791                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4792            }
4793            killUnneededProcessLocked(app, reason);
4794            handleAppDiedLocked(app, true, allowRestart);
4795            removeLruProcessLocked(app);
4796
4797            if (app.persistent && !app.isolated) {
4798                if (!callerWillRestart) {
4799                    addAppLocked(app.info, false);
4800                } else {
4801                    needRestart = true;
4802                }
4803            }
4804        } else {
4805            mRemovedProcesses.add(app);
4806        }
4807
4808        return needRestart;
4809    }
4810
4811    private final void processStartTimedOutLocked(ProcessRecord app) {
4812        final int pid = app.pid;
4813        boolean gone = false;
4814        synchronized (mPidsSelfLocked) {
4815            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4816            if (knownApp != null && knownApp.thread == null) {
4817                mPidsSelfLocked.remove(pid);
4818                gone = true;
4819            }
4820        }
4821
4822        if (gone) {
4823            Slog.w(TAG, "Process " + app + " failed to attach");
4824            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4825                    pid, app.uid, app.processName);
4826            mProcessNames.remove(app.processName, app.uid);
4827            mIsolatedProcesses.remove(app.uid);
4828            if (mHeavyWeightProcess == app) {
4829                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4830                        mHeavyWeightProcess.userId, 0));
4831                mHeavyWeightProcess = null;
4832            }
4833            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4834                    app.processName, app.info.uid);
4835            if (app.isolated) {
4836                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4837            }
4838            // Take care of any launching providers waiting for this process.
4839            checkAppInLaunchingProvidersLocked(app, true);
4840            // Take care of any services that are waiting for the process.
4841            mServices.processStartTimedOutLocked(app);
4842            killUnneededProcessLocked(app, "start timeout");
4843            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4844                Slog.w(TAG, "Unattached app died before backup, skipping");
4845                try {
4846                    IBackupManager bm = IBackupManager.Stub.asInterface(
4847                            ServiceManager.getService(Context.BACKUP_SERVICE));
4848                    bm.agentDisconnected(app.info.packageName);
4849                } catch (RemoteException e) {
4850                    // Can't happen; the backup manager is local
4851                }
4852            }
4853            if (isPendingBroadcastProcessLocked(pid)) {
4854                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4855                skipPendingBroadcastLocked(pid);
4856            }
4857        } else {
4858            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4859        }
4860    }
4861
4862    private final boolean attachApplicationLocked(IApplicationThread thread,
4863            int pid) {
4864
4865        // Find the application record that is being attached...  either via
4866        // the pid if we are running in multiple processes, or just pull the
4867        // next app record if we are emulating process with anonymous threads.
4868        ProcessRecord app;
4869        if (pid != MY_PID && pid >= 0) {
4870            synchronized (mPidsSelfLocked) {
4871                app = mPidsSelfLocked.get(pid);
4872            }
4873        } else {
4874            app = null;
4875        }
4876
4877        if (app == null) {
4878            Slog.w(TAG, "No pending application record for pid " + pid
4879                    + " (IApplicationThread " + thread + "); dropping process");
4880            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4881            if (pid > 0 && pid != MY_PID) {
4882                Process.killProcessQuiet(pid);
4883            } else {
4884                try {
4885                    thread.scheduleExit();
4886                } catch (Exception e) {
4887                    // Ignore exceptions.
4888                }
4889            }
4890            return false;
4891        }
4892
4893        // If this application record is still attached to a previous
4894        // process, clean it up now.
4895        if (app.thread != null) {
4896            handleAppDiedLocked(app, true, true);
4897        }
4898
4899        // Tell the process all about itself.
4900
4901        if (localLOGV) Slog.v(
4902                TAG, "Binding process pid " + pid + " to record " + app);
4903
4904        final String processName = app.processName;
4905        try {
4906            AppDeathRecipient adr = new AppDeathRecipient(
4907                    app, pid, thread);
4908            thread.asBinder().linkToDeath(adr, 0);
4909            app.deathRecipient = adr;
4910        } catch (RemoteException e) {
4911            app.resetPackageList(mProcessStats);
4912            startProcessLocked(app, "link fail", processName);
4913            return false;
4914        }
4915
4916        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4917
4918        app.makeActive(thread, mProcessStats);
4919        app.curAdj = app.setAdj = -100;
4920        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4921        app.forcingToForeground = null;
4922        updateProcessForegroundLocked(app, false, false);
4923        app.hasShownUi = false;
4924        app.debugging = false;
4925        app.cached = false;
4926
4927        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4928
4929        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4930        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4931
4932        if (!normalMode) {
4933            Slog.i(TAG, "Launching preboot mode app: " + app);
4934        }
4935
4936        if (localLOGV) Slog.v(
4937            TAG, "New app record " + app
4938            + " thread=" + thread.asBinder() + " pid=" + pid);
4939        try {
4940            int testMode = IApplicationThread.DEBUG_OFF;
4941            if (mDebugApp != null && mDebugApp.equals(processName)) {
4942                testMode = mWaitForDebugger
4943                    ? IApplicationThread.DEBUG_WAIT
4944                    : IApplicationThread.DEBUG_ON;
4945                app.debugging = true;
4946                if (mDebugTransient) {
4947                    mDebugApp = mOrigDebugApp;
4948                    mWaitForDebugger = mOrigWaitForDebugger;
4949                }
4950            }
4951            String profileFile = app.instrumentationProfileFile;
4952            ParcelFileDescriptor profileFd = null;
4953            boolean profileAutoStop = false;
4954            if (mProfileApp != null && mProfileApp.equals(processName)) {
4955                mProfileProc = app;
4956                profileFile = mProfileFile;
4957                profileFd = mProfileFd;
4958                profileAutoStop = mAutoStopProfiler;
4959            }
4960            boolean enableOpenGlTrace = false;
4961            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4962                enableOpenGlTrace = true;
4963                mOpenGlTraceApp = null;
4964            }
4965
4966            // If the app is being launched for restore or full backup, set it up specially
4967            boolean isRestrictedBackupMode = false;
4968            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4969                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4970                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4971                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4972            }
4973
4974            ensurePackageDexOpt(app.instrumentationInfo != null
4975                    ? app.instrumentationInfo.packageName
4976                    : app.info.packageName);
4977            if (app.instrumentationClass != null) {
4978                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4979            }
4980            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4981                    + processName + " with config " + mConfiguration);
4982            ApplicationInfo appInfo = app.instrumentationInfo != null
4983                    ? app.instrumentationInfo : app.info;
4984            app.compat = compatibilityInfoForPackageLocked(appInfo);
4985            if (profileFd != null) {
4986                profileFd = profileFd.dup();
4987            }
4988            thread.bindApplication(processName, appInfo, providers,
4989                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4990                    app.instrumentationArguments, app.instrumentationWatcher,
4991                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4992                    isRestrictedBackupMode || !normalMode, app.persistent,
4993                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4994                    mCoreSettingsObserver.getCoreSettingsLocked());
4995            updateLruProcessLocked(app, false, null);
4996            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4997        } catch (Exception e) {
4998            // todo: Yikes!  What should we do?  For now we will try to
4999            // start another process, but that could easily get us in
5000            // an infinite loop of restarting processes...
5001            Slog.w(TAG, "Exception thrown during bind!", e);
5002
5003            app.resetPackageList(mProcessStats);
5004            app.unlinkDeathRecipient();
5005            startProcessLocked(app, "bind fail", processName);
5006            return false;
5007        }
5008
5009        // Remove this record from the list of starting applications.
5010        mPersistentStartingProcesses.remove(app);
5011        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5012                "Attach application locked removing on hold: " + app);
5013        mProcessesOnHold.remove(app);
5014
5015        boolean badApp = false;
5016        boolean didSomething = false;
5017
5018        // See if the top visible activity is waiting to run in this process...
5019        if (normalMode) {
5020            try {
5021                if (mStackSupervisor.attachApplicationLocked(app)) {
5022                    didSomething = true;
5023                }
5024            } catch (Exception e) {
5025                badApp = true;
5026            }
5027        }
5028
5029        // Find any services that should be running in this process...
5030        if (!badApp) {
5031            try {
5032                didSomething |= mServices.attachApplicationLocked(app, processName);
5033            } catch (Exception e) {
5034                badApp = true;
5035            }
5036        }
5037
5038        // Check if a next-broadcast receiver is in this process...
5039        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5040            try {
5041                didSomething |= sendPendingBroadcastsLocked(app);
5042            } catch (Exception e) {
5043                // If the app died trying to launch the receiver we declare it 'bad'
5044                badApp = true;
5045            }
5046        }
5047
5048        // Check whether the next backup agent is in this process...
5049        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5050            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5051            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5052            try {
5053                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5054                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5055                        mBackupTarget.backupMode);
5056            } catch (Exception e) {
5057                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5058                e.printStackTrace();
5059            }
5060        }
5061
5062        if (badApp) {
5063            // todo: Also need to kill application to deal with all
5064            // kinds of exceptions.
5065            handleAppDiedLocked(app, false, true);
5066            return false;
5067        }
5068
5069        if (!didSomething) {
5070            updateOomAdjLocked();
5071        }
5072
5073        return true;
5074    }
5075
5076    @Override
5077    public final void attachApplication(IApplicationThread thread) {
5078        synchronized (this) {
5079            int callingPid = Binder.getCallingPid();
5080            final long origId = Binder.clearCallingIdentity();
5081            attachApplicationLocked(thread, callingPid);
5082            Binder.restoreCallingIdentity(origId);
5083        }
5084    }
5085
5086    @Override
5087    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5088        final long origId = Binder.clearCallingIdentity();
5089        synchronized (this) {
5090            ActivityStack stack = ActivityRecord.getStackLocked(token);
5091            if (stack != null) {
5092                ActivityRecord r =
5093                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5094                if (stopProfiling) {
5095                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5096                        try {
5097                            mProfileFd.close();
5098                        } catch (IOException e) {
5099                        }
5100                        clearProfilerLocked();
5101                    }
5102                }
5103            }
5104        }
5105        Binder.restoreCallingIdentity(origId);
5106    }
5107
5108    void enableScreenAfterBoot() {
5109        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5110                SystemClock.uptimeMillis());
5111        mWindowManager.enableScreenAfterBoot();
5112
5113        synchronized (this) {
5114            updateEventDispatchingLocked();
5115        }
5116    }
5117
5118    @Override
5119    public void showBootMessage(final CharSequence msg, final boolean always) {
5120        enforceNotIsolatedCaller("showBootMessage");
5121        mWindowManager.showBootMessage(msg, always);
5122    }
5123
5124    @Override
5125    public void dismissKeyguardOnNextActivity() {
5126        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5127        final long token = Binder.clearCallingIdentity();
5128        try {
5129            synchronized (this) {
5130                if (DEBUG_LOCKSCREEN) logLockScreen("");
5131                if (mLockScreenShown) {
5132                    mLockScreenShown = false;
5133                    comeOutOfSleepIfNeededLocked();
5134                }
5135                mStackSupervisor.setDismissKeyguard(true);
5136            }
5137        } finally {
5138            Binder.restoreCallingIdentity(token);
5139        }
5140    }
5141
5142    final void finishBooting() {
5143        IntentFilter pkgFilter = new IntentFilter();
5144        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5145        pkgFilter.addDataScheme("package");
5146        mContext.registerReceiver(new BroadcastReceiver() {
5147            @Override
5148            public void onReceive(Context context, Intent intent) {
5149                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5150                if (pkgs != null) {
5151                    for (String pkg : pkgs) {
5152                        synchronized (ActivityManagerService.this) {
5153                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5154                                    "finished booting")) {
5155                                setResultCode(Activity.RESULT_OK);
5156                                return;
5157                            }
5158                        }
5159                    }
5160                }
5161            }
5162        }, pkgFilter);
5163
5164        synchronized (this) {
5165            // Ensure that any processes we had put on hold are now started
5166            // up.
5167            final int NP = mProcessesOnHold.size();
5168            if (NP > 0) {
5169                ArrayList<ProcessRecord> procs =
5170                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5171                for (int ip=0; ip<NP; ip++) {
5172                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5173                            + procs.get(ip));
5174                    startProcessLocked(procs.get(ip), "on-hold", null);
5175                }
5176            }
5177
5178            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5179                // Start looking for apps that are abusing wake locks.
5180                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5181                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5182                // Tell anyone interested that we are done booting!
5183                SystemProperties.set("sys.boot_completed", "1");
5184                SystemProperties.set("dev.bootcomplete", "1");
5185                for (int i=0; i<mStartedUsers.size(); i++) {
5186                    UserStartedState uss = mStartedUsers.valueAt(i);
5187                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5188                        uss.mState = UserStartedState.STATE_RUNNING;
5189                        final int userId = mStartedUsers.keyAt(i);
5190                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5191                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5192                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5193                        broadcastIntentLocked(null, null, intent, null,
5194                                new IIntentReceiver.Stub() {
5195                                    @Override
5196                                    public void performReceive(Intent intent, int resultCode,
5197                                            String data, Bundle extras, boolean ordered,
5198                                            boolean sticky, int sendingUser) {
5199                                        synchronized (ActivityManagerService.this) {
5200                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5201                                                    true, false);
5202                                        }
5203                                    }
5204                                },
5205                                0, null, null,
5206                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5207                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5208                                userId);
5209                    }
5210                }
5211                scheduleStartProfilesLocked();
5212            }
5213        }
5214    }
5215
5216    final void ensureBootCompleted() {
5217        boolean booting;
5218        boolean enableScreen;
5219        synchronized (this) {
5220            booting = mBooting;
5221            mBooting = false;
5222            enableScreen = !mBooted;
5223            mBooted = true;
5224        }
5225
5226        if (booting) {
5227            finishBooting();
5228        }
5229
5230        if (enableScreen) {
5231            enableScreenAfterBoot();
5232        }
5233    }
5234
5235    @Override
5236    public final void activityResumed(IBinder token) {
5237        final long origId = Binder.clearCallingIdentity();
5238        synchronized(this) {
5239            ActivityStack stack = ActivityRecord.getStackLocked(token);
5240            if (stack != null) {
5241                ActivityRecord.activityResumedLocked(token);
5242            }
5243        }
5244        Binder.restoreCallingIdentity(origId);
5245    }
5246
5247    @Override
5248    public final void activityPaused(IBinder token) {
5249        final long origId = Binder.clearCallingIdentity();
5250        synchronized(this) {
5251            ActivityStack stack = ActivityRecord.getStackLocked(token);
5252            if (stack != null) {
5253                stack.activityPausedLocked(token, false);
5254            }
5255        }
5256        Binder.restoreCallingIdentity(origId);
5257    }
5258
5259    @Override
5260    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5261            CharSequence description) {
5262        if (localLOGV) Slog.v(
5263            TAG, "Activity stopped: token=" + token);
5264
5265        // Refuse possible leaked file descriptors
5266        if (icicle != null && icicle.hasFileDescriptors()) {
5267            throw new IllegalArgumentException("File descriptors passed in Bundle");
5268        }
5269
5270        ActivityRecord r = null;
5271
5272        final long origId = Binder.clearCallingIdentity();
5273
5274        synchronized (this) {
5275            r = ActivityRecord.isInStackLocked(token);
5276            if (r != null) {
5277                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5278            }
5279        }
5280
5281        if (r != null) {
5282            sendPendingThumbnail(r, null, null, null, false);
5283        }
5284
5285        trimApplications();
5286
5287        Binder.restoreCallingIdentity(origId);
5288    }
5289
5290    @Override
5291    public final void activityDestroyed(IBinder token) {
5292        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5293        synchronized (this) {
5294            ActivityStack stack = ActivityRecord.getStackLocked(token);
5295            if (stack != null) {
5296                stack.activityDestroyedLocked(token);
5297            }
5298        }
5299    }
5300
5301    @Override
5302    public String getCallingPackage(IBinder token) {
5303        synchronized (this) {
5304            ActivityRecord r = getCallingRecordLocked(token);
5305            return r != null ? r.info.packageName : null;
5306        }
5307    }
5308
5309    @Override
5310    public ComponentName getCallingActivity(IBinder token) {
5311        synchronized (this) {
5312            ActivityRecord r = getCallingRecordLocked(token);
5313            return r != null ? r.intent.getComponent() : null;
5314        }
5315    }
5316
5317    private ActivityRecord getCallingRecordLocked(IBinder token) {
5318        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5319        if (r == null) {
5320            return null;
5321        }
5322        return r.resultTo;
5323    }
5324
5325    @Override
5326    public ComponentName getActivityClassForToken(IBinder token) {
5327        synchronized(this) {
5328            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5329            if (r == null) {
5330                return null;
5331            }
5332            return r.intent.getComponent();
5333        }
5334    }
5335
5336    @Override
5337    public String getPackageForToken(IBinder token) {
5338        synchronized(this) {
5339            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5340            if (r == null) {
5341                return null;
5342            }
5343            return r.packageName;
5344        }
5345    }
5346
5347    @Override
5348    public IIntentSender getIntentSender(int type,
5349            String packageName, IBinder token, String resultWho,
5350            int requestCode, Intent[] intents, String[] resolvedTypes,
5351            int flags, Bundle options, int userId) {
5352        enforceNotIsolatedCaller("getIntentSender");
5353        // Refuse possible leaked file descriptors
5354        if (intents != null) {
5355            if (intents.length < 1) {
5356                throw new IllegalArgumentException("Intents array length must be >= 1");
5357            }
5358            for (int i=0; i<intents.length; i++) {
5359                Intent intent = intents[i];
5360                if (intent != null) {
5361                    if (intent.hasFileDescriptors()) {
5362                        throw new IllegalArgumentException("File descriptors passed in Intent");
5363                    }
5364                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5365                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5366                        throw new IllegalArgumentException(
5367                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5368                    }
5369                    intents[i] = new Intent(intent);
5370                }
5371            }
5372            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5373                throw new IllegalArgumentException(
5374                        "Intent array length does not match resolvedTypes length");
5375            }
5376        }
5377        if (options != null) {
5378            if (options.hasFileDescriptors()) {
5379                throw new IllegalArgumentException("File descriptors passed in options");
5380            }
5381        }
5382
5383        synchronized(this) {
5384            int callingUid = Binder.getCallingUid();
5385            int origUserId = userId;
5386            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5387                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5388                    "getIntentSender", null);
5389            if (origUserId == UserHandle.USER_CURRENT) {
5390                // We don't want to evaluate this until the pending intent is
5391                // actually executed.  However, we do want to always do the
5392                // security checking for it above.
5393                userId = UserHandle.USER_CURRENT;
5394            }
5395            try {
5396                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5397                    int uid = AppGlobals.getPackageManager()
5398                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5399                    if (!UserHandle.isSameApp(callingUid, uid)) {
5400                        String msg = "Permission Denial: getIntentSender() from pid="
5401                            + Binder.getCallingPid()
5402                            + ", uid=" + Binder.getCallingUid()
5403                            + ", (need uid=" + uid + ")"
5404                            + " is not allowed to send as package " + packageName;
5405                        Slog.w(TAG, msg);
5406                        throw new SecurityException(msg);
5407                    }
5408                }
5409
5410                return getIntentSenderLocked(type, packageName, callingUid, userId,
5411                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5412
5413            } catch (RemoteException e) {
5414                throw new SecurityException(e);
5415            }
5416        }
5417    }
5418
5419    IIntentSender getIntentSenderLocked(int type, String packageName,
5420            int callingUid, int userId, IBinder token, String resultWho,
5421            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5422            Bundle options) {
5423        if (DEBUG_MU)
5424            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5425        ActivityRecord activity = null;
5426        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5427            activity = ActivityRecord.isInStackLocked(token);
5428            if (activity == null) {
5429                return null;
5430            }
5431            if (activity.finishing) {
5432                return null;
5433            }
5434        }
5435
5436        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5437        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5438        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5439        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5440                |PendingIntent.FLAG_UPDATE_CURRENT);
5441
5442        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5443                type, packageName, activity, resultWho,
5444                requestCode, intents, resolvedTypes, flags, options, userId);
5445        WeakReference<PendingIntentRecord> ref;
5446        ref = mIntentSenderRecords.get(key);
5447        PendingIntentRecord rec = ref != null ? ref.get() : null;
5448        if (rec != null) {
5449            if (!cancelCurrent) {
5450                if (updateCurrent) {
5451                    if (rec.key.requestIntent != null) {
5452                        rec.key.requestIntent.replaceExtras(intents != null ?
5453                                intents[intents.length - 1] : null);
5454                    }
5455                    if (intents != null) {
5456                        intents[intents.length-1] = rec.key.requestIntent;
5457                        rec.key.allIntents = intents;
5458                        rec.key.allResolvedTypes = resolvedTypes;
5459                    } else {
5460                        rec.key.allIntents = null;
5461                        rec.key.allResolvedTypes = null;
5462                    }
5463                }
5464                return rec;
5465            }
5466            rec.canceled = true;
5467            mIntentSenderRecords.remove(key);
5468        }
5469        if (noCreate) {
5470            return rec;
5471        }
5472        rec = new PendingIntentRecord(this, key, callingUid);
5473        mIntentSenderRecords.put(key, rec.ref);
5474        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5475            if (activity.pendingResults == null) {
5476                activity.pendingResults
5477                        = new HashSet<WeakReference<PendingIntentRecord>>();
5478            }
5479            activity.pendingResults.add(rec.ref);
5480        }
5481        return rec;
5482    }
5483
5484    @Override
5485    public void cancelIntentSender(IIntentSender sender) {
5486        if (!(sender instanceof PendingIntentRecord)) {
5487            return;
5488        }
5489        synchronized(this) {
5490            PendingIntentRecord rec = (PendingIntentRecord)sender;
5491            try {
5492                int uid = AppGlobals.getPackageManager()
5493                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5494                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5495                    String msg = "Permission Denial: cancelIntentSender() from pid="
5496                        + Binder.getCallingPid()
5497                        + ", uid=" + Binder.getCallingUid()
5498                        + " is not allowed to cancel packges "
5499                        + rec.key.packageName;
5500                    Slog.w(TAG, msg);
5501                    throw new SecurityException(msg);
5502                }
5503            } catch (RemoteException e) {
5504                throw new SecurityException(e);
5505            }
5506            cancelIntentSenderLocked(rec, true);
5507        }
5508    }
5509
5510    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5511        rec.canceled = true;
5512        mIntentSenderRecords.remove(rec.key);
5513        if (cleanActivity && rec.key.activity != null) {
5514            rec.key.activity.pendingResults.remove(rec.ref);
5515        }
5516    }
5517
5518    @Override
5519    public String getPackageForIntentSender(IIntentSender pendingResult) {
5520        if (!(pendingResult instanceof PendingIntentRecord)) {
5521            return null;
5522        }
5523        try {
5524            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5525            return res.key.packageName;
5526        } catch (ClassCastException e) {
5527        }
5528        return null;
5529    }
5530
5531    @Override
5532    public int getUidForIntentSender(IIntentSender sender) {
5533        if (sender instanceof PendingIntentRecord) {
5534            try {
5535                PendingIntentRecord res = (PendingIntentRecord)sender;
5536                return res.uid;
5537            } catch (ClassCastException e) {
5538            }
5539        }
5540        return -1;
5541    }
5542
5543    @Override
5544    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5545        if (!(pendingResult instanceof PendingIntentRecord)) {
5546            return false;
5547        }
5548        try {
5549            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5550            if (res.key.allIntents == null) {
5551                return false;
5552            }
5553            for (int i=0; i<res.key.allIntents.length; i++) {
5554                Intent intent = res.key.allIntents[i];
5555                if (intent.getPackage() != null && intent.getComponent() != null) {
5556                    return false;
5557                }
5558            }
5559            return true;
5560        } catch (ClassCastException e) {
5561        }
5562        return false;
5563    }
5564
5565    @Override
5566    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5567        if (!(pendingResult instanceof PendingIntentRecord)) {
5568            return false;
5569        }
5570        try {
5571            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5572            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5573                return true;
5574            }
5575            return false;
5576        } catch (ClassCastException e) {
5577        }
5578        return false;
5579    }
5580
5581    @Override
5582    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5583        if (!(pendingResult instanceof PendingIntentRecord)) {
5584            return null;
5585        }
5586        try {
5587            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5588            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5589        } catch (ClassCastException e) {
5590        }
5591        return null;
5592    }
5593
5594    @Override
5595    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5596        if (!(pendingResult instanceof PendingIntentRecord)) {
5597            return null;
5598        }
5599        try {
5600            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5601            Intent intent = res.key.requestIntent;
5602            if (intent != null) {
5603                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5604                        || res.lastTagPrefix.equals(prefix))) {
5605                    return res.lastTag;
5606                }
5607                res.lastTagPrefix = prefix;
5608                StringBuilder sb = new StringBuilder(128);
5609                if (prefix != null) {
5610                    sb.append(prefix);
5611                }
5612                if (intent.getAction() != null) {
5613                    sb.append(intent.getAction());
5614                } else if (intent.getComponent() != null) {
5615                    intent.getComponent().appendShortString(sb);
5616                } else {
5617                    sb.append("?");
5618                }
5619                return res.lastTag = sb.toString();
5620            }
5621        } catch (ClassCastException e) {
5622        }
5623        return null;
5624    }
5625
5626    @Override
5627    public void setProcessLimit(int max) {
5628        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5629                "setProcessLimit()");
5630        synchronized (this) {
5631            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5632            mProcessLimitOverride = max;
5633        }
5634        trimApplications();
5635    }
5636
5637    @Override
5638    public int getProcessLimit() {
5639        synchronized (this) {
5640            return mProcessLimitOverride;
5641        }
5642    }
5643
5644    void foregroundTokenDied(ForegroundToken token) {
5645        synchronized (ActivityManagerService.this) {
5646            synchronized (mPidsSelfLocked) {
5647                ForegroundToken cur
5648                    = mForegroundProcesses.get(token.pid);
5649                if (cur != token) {
5650                    return;
5651                }
5652                mForegroundProcesses.remove(token.pid);
5653                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5654                if (pr == null) {
5655                    return;
5656                }
5657                pr.forcingToForeground = null;
5658                updateProcessForegroundLocked(pr, false, false);
5659            }
5660            updateOomAdjLocked();
5661        }
5662    }
5663
5664    @Override
5665    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5666        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5667                "setProcessForeground()");
5668        synchronized(this) {
5669            boolean changed = false;
5670
5671            synchronized (mPidsSelfLocked) {
5672                ProcessRecord pr = mPidsSelfLocked.get(pid);
5673                if (pr == null && isForeground) {
5674                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5675                    return;
5676                }
5677                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5678                if (oldToken != null) {
5679                    oldToken.token.unlinkToDeath(oldToken, 0);
5680                    mForegroundProcesses.remove(pid);
5681                    if (pr != null) {
5682                        pr.forcingToForeground = null;
5683                    }
5684                    changed = true;
5685                }
5686                if (isForeground && token != null) {
5687                    ForegroundToken newToken = new ForegroundToken() {
5688                        @Override
5689                        public void binderDied() {
5690                            foregroundTokenDied(this);
5691                        }
5692                    };
5693                    newToken.pid = pid;
5694                    newToken.token = token;
5695                    try {
5696                        token.linkToDeath(newToken, 0);
5697                        mForegroundProcesses.put(pid, newToken);
5698                        pr.forcingToForeground = token;
5699                        changed = true;
5700                    } catch (RemoteException e) {
5701                        // If the process died while doing this, we will later
5702                        // do the cleanup with the process death link.
5703                    }
5704                }
5705            }
5706
5707            if (changed) {
5708                updateOomAdjLocked();
5709            }
5710        }
5711    }
5712
5713    // =========================================================
5714    // PERMISSIONS
5715    // =========================================================
5716
5717    static class PermissionController extends IPermissionController.Stub {
5718        ActivityManagerService mActivityManagerService;
5719        PermissionController(ActivityManagerService activityManagerService) {
5720            mActivityManagerService = activityManagerService;
5721        }
5722
5723        @Override
5724        public boolean checkPermission(String permission, int pid, int uid) {
5725            return mActivityManagerService.checkPermission(permission, pid,
5726                    uid) == PackageManager.PERMISSION_GRANTED;
5727        }
5728    }
5729
5730    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5731        @Override
5732        public int checkComponentPermission(String permission, int pid, int uid,
5733                int owningUid, boolean exported) {
5734            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5735                    owningUid, exported);
5736        }
5737
5738        @Override
5739        public Object getAMSLock() {
5740            return ActivityManagerService.this;
5741        }
5742    }
5743
5744    /**
5745     * This can be called with or without the global lock held.
5746     */
5747    int checkComponentPermission(String permission, int pid, int uid,
5748            int owningUid, boolean exported) {
5749        // We might be performing an operation on behalf of an indirect binder
5750        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5751        // client identity accordingly before proceeding.
5752        Identity tlsIdentity = sCallerIdentity.get();
5753        if (tlsIdentity != null) {
5754            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5755                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5756            uid = tlsIdentity.uid;
5757            pid = tlsIdentity.pid;
5758        }
5759
5760        if (pid == MY_PID) {
5761            return PackageManager.PERMISSION_GRANTED;
5762        }
5763
5764        return ActivityManager.checkComponentPermission(permission, uid,
5765                owningUid, exported);
5766    }
5767
5768    /**
5769     * As the only public entry point for permissions checking, this method
5770     * can enforce the semantic that requesting a check on a null global
5771     * permission is automatically denied.  (Internally a null permission
5772     * string is used when calling {@link #checkComponentPermission} in cases
5773     * when only uid-based security is needed.)
5774     *
5775     * This can be called with or without the global lock held.
5776     */
5777    @Override
5778    public int checkPermission(String permission, int pid, int uid) {
5779        if (permission == null) {
5780            return PackageManager.PERMISSION_DENIED;
5781        }
5782        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5783    }
5784
5785    /**
5786     * Binder IPC calls go through the public entry point.
5787     * This can be called with or without the global lock held.
5788     */
5789    int checkCallingPermission(String permission) {
5790        return checkPermission(permission,
5791                Binder.getCallingPid(),
5792                UserHandle.getAppId(Binder.getCallingUid()));
5793    }
5794
5795    /**
5796     * This can be called with or without the global lock held.
5797     */
5798    void enforceCallingPermission(String permission, String func) {
5799        if (checkCallingPermission(permission)
5800                == PackageManager.PERMISSION_GRANTED) {
5801            return;
5802        }
5803
5804        String msg = "Permission Denial: " + func + " from pid="
5805                + Binder.getCallingPid()
5806                + ", uid=" + Binder.getCallingUid()
5807                + " requires " + permission;
5808        Slog.w(TAG, msg);
5809        throw new SecurityException(msg);
5810    }
5811
5812    /**
5813     * Determine if UID is holding permissions required to access {@link Uri} in
5814     * the given {@link ProviderInfo}. Final permission checking is always done
5815     * in {@link ContentProvider}.
5816     */
5817    private final boolean checkHoldingPermissionsLocked(
5818            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5819        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5820                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5821
5822        if (pi.applicationInfo.uid == uid) {
5823            return true;
5824        } else if (!pi.exported) {
5825            return false;
5826        }
5827
5828        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5829        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5830        try {
5831            // check if target holds top-level <provider> permissions
5832            if (!readMet && pi.readPermission != null
5833                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5834                readMet = true;
5835            }
5836            if (!writeMet && pi.writePermission != null
5837                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5838                writeMet = true;
5839            }
5840
5841            // track if unprotected read/write is allowed; any denied
5842            // <path-permission> below removes this ability
5843            boolean allowDefaultRead = pi.readPermission == null;
5844            boolean allowDefaultWrite = pi.writePermission == null;
5845
5846            // check if target holds any <path-permission> that match uri
5847            final PathPermission[] pps = pi.pathPermissions;
5848            if (pps != null) {
5849                final String path = uri.getPath();
5850                int i = pps.length;
5851                while (i > 0 && (!readMet || !writeMet)) {
5852                    i--;
5853                    PathPermission pp = pps[i];
5854                    if (pp.match(path)) {
5855                        if (!readMet) {
5856                            final String pprperm = pp.getReadPermission();
5857                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5858                                    + pprperm + " for " + pp.getPath()
5859                                    + ": match=" + pp.match(path)
5860                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5861                            if (pprperm != null) {
5862                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5863                                    readMet = true;
5864                                } else {
5865                                    allowDefaultRead = false;
5866                                }
5867                            }
5868                        }
5869                        if (!writeMet) {
5870                            final String ppwperm = pp.getWritePermission();
5871                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5872                                    + ppwperm + " for " + pp.getPath()
5873                                    + ": match=" + pp.match(path)
5874                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5875                            if (ppwperm != null) {
5876                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5877                                    writeMet = true;
5878                                } else {
5879                                    allowDefaultWrite = false;
5880                                }
5881                            }
5882                        }
5883                    }
5884                }
5885            }
5886
5887            // grant unprotected <provider> read/write, if not blocked by
5888            // <path-permission> above
5889            if (allowDefaultRead) readMet = true;
5890            if (allowDefaultWrite) writeMet = true;
5891
5892        } catch (RemoteException e) {
5893            return false;
5894        }
5895
5896        return readMet && writeMet;
5897    }
5898
5899    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5900        ProviderInfo pi = null;
5901        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5902        if (cpr != null) {
5903            pi = cpr.info;
5904        } else {
5905            try {
5906                pi = AppGlobals.getPackageManager().resolveContentProvider(
5907                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5908            } catch (RemoteException ex) {
5909            }
5910        }
5911        return pi;
5912    }
5913
5914    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5915        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5916        if (targetUris != null) {
5917            return targetUris.get(uri);
5918        } else {
5919            return null;
5920        }
5921    }
5922
5923    private UriPermission findOrCreateUriPermissionLocked(
5924            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5925        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5926        if (targetUris == null) {
5927            targetUris = Maps.newArrayMap();
5928            mGrantedUriPermissions.put(targetUid, targetUris);
5929        }
5930
5931        UriPermission perm = targetUris.get(uri);
5932        if (perm == null) {
5933            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5934            targetUris.put(uri, perm);
5935        }
5936
5937        return perm;
5938    }
5939
5940    private final boolean checkUriPermissionLocked(
5941            Uri uri, int uid, int modeFlags, int minStrength) {
5942        // Root gets to do everything.
5943        if (uid == 0) {
5944            return true;
5945        }
5946        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5947        if (perms == null) return false;
5948        UriPermission perm = perms.get(uri);
5949        if (perm == null) return false;
5950        return perm.getStrength(modeFlags) >= minStrength;
5951    }
5952
5953    @Override
5954    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5955        enforceNotIsolatedCaller("checkUriPermission");
5956
5957        // Another redirected-binder-call permissions check as in
5958        // {@link checkComponentPermission}.
5959        Identity tlsIdentity = sCallerIdentity.get();
5960        if (tlsIdentity != null) {
5961            uid = tlsIdentity.uid;
5962            pid = tlsIdentity.pid;
5963        }
5964
5965        // Our own process gets to do everything.
5966        if (pid == MY_PID) {
5967            return PackageManager.PERMISSION_GRANTED;
5968        }
5969        synchronized(this) {
5970            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5971                    ? PackageManager.PERMISSION_GRANTED
5972                    : PackageManager.PERMISSION_DENIED;
5973        }
5974    }
5975
5976    /**
5977     * Check if the targetPkg can be granted permission to access uri by
5978     * the callingUid using the given modeFlags.  Throws a security exception
5979     * if callingUid is not allowed to do this.  Returns the uid of the target
5980     * if the URI permission grant should be performed; returns -1 if it is not
5981     * needed (for example targetPkg already has permission to access the URI).
5982     * If you already know the uid of the target, you can supply it in
5983     * lastTargetUid else set that to -1.
5984     */
5985    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5986            Uri uri, int modeFlags, int lastTargetUid) {
5987        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5988        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5989                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5990        if (modeFlags == 0) {
5991            return -1;
5992        }
5993
5994        if (targetPkg != null) {
5995            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5996                    "Checking grant " + targetPkg + " permission to " + uri);
5997        }
5998
5999        final IPackageManager pm = AppGlobals.getPackageManager();
6000
6001        // If this is not a content: uri, we can't do anything with it.
6002        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6003            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6004                    "Can't grant URI permission for non-content URI: " + uri);
6005            return -1;
6006        }
6007
6008        final String authority = uri.getAuthority();
6009        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6010        if (pi == null) {
6011            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6012            return -1;
6013        }
6014
6015        int targetUid = lastTargetUid;
6016        if (targetUid < 0 && targetPkg != null) {
6017            try {
6018                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6019                if (targetUid < 0) {
6020                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6021                            "Can't grant URI permission no uid for: " + targetPkg);
6022                    return -1;
6023                }
6024            } catch (RemoteException ex) {
6025                return -1;
6026            }
6027        }
6028
6029        if (targetUid >= 0) {
6030            // First...  does the target actually need this permission?
6031            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6032                // No need to grant the target this permission.
6033                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6034                        "Target " + targetPkg + " already has full permission to " + uri);
6035                return -1;
6036            }
6037        } else {
6038            // First...  there is no target package, so can anyone access it?
6039            boolean allowed = pi.exported;
6040            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6041                if (pi.readPermission != null) {
6042                    allowed = false;
6043                }
6044            }
6045            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6046                if (pi.writePermission != null) {
6047                    allowed = false;
6048                }
6049            }
6050            if (allowed) {
6051                return -1;
6052            }
6053        }
6054
6055        // Second...  is the provider allowing granting of URI permissions?
6056        if (!pi.grantUriPermissions) {
6057            throw new SecurityException("Provider " + pi.packageName
6058                    + "/" + pi.name
6059                    + " does not allow granting of Uri permissions (uri "
6060                    + uri + ")");
6061        }
6062        if (pi.uriPermissionPatterns != null) {
6063            final int N = pi.uriPermissionPatterns.length;
6064            boolean allowed = false;
6065            for (int i=0; i<N; i++) {
6066                if (pi.uriPermissionPatterns[i] != null
6067                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6068                    allowed = true;
6069                    break;
6070                }
6071            }
6072            if (!allowed) {
6073                throw new SecurityException("Provider " + pi.packageName
6074                        + "/" + pi.name
6075                        + " does not allow granting of permission to path of Uri "
6076                        + uri);
6077            }
6078        }
6079
6080        // Third...  does the caller itself have permission to access
6081        // this uri?
6082        if (callingUid != Process.myUid()) {
6083            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6084                // Require they hold a strong enough Uri permission
6085                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6086                        : UriPermission.STRENGTH_OWNED;
6087                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6088                    throw new SecurityException("Uid " + callingUid
6089                            + " does not have permission to uri " + uri);
6090                }
6091            }
6092        }
6093
6094        return targetUid;
6095    }
6096
6097    @Override
6098    public int checkGrantUriPermission(int callingUid, String targetPkg,
6099            Uri uri, int modeFlags) {
6100        enforceNotIsolatedCaller("checkGrantUriPermission");
6101        synchronized(this) {
6102            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6103        }
6104    }
6105
6106    void grantUriPermissionUncheckedLocked(
6107            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6108        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6109        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6110                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6111        if (modeFlags == 0) {
6112            return;
6113        }
6114
6115        // So here we are: the caller has the assumed permission
6116        // to the uri, and the target doesn't.  Let's now give this to
6117        // the target.
6118
6119        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6120                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6121
6122        final String authority = uri.getAuthority();
6123        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6124        if (pi == null) {
6125            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6126            return;
6127        }
6128
6129        final UriPermission perm = findOrCreateUriPermissionLocked(
6130                pi.packageName, targetPkg, targetUid, uri);
6131        perm.grantModes(modeFlags, persistable, owner);
6132    }
6133
6134    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6135            int modeFlags, UriPermissionOwner owner) {
6136        if (targetPkg == null) {
6137            throw new NullPointerException("targetPkg");
6138        }
6139
6140        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6141        if (targetUid < 0) {
6142            return;
6143        }
6144
6145        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6146    }
6147
6148    static class NeededUriGrants extends ArrayList<Uri> {
6149        final String targetPkg;
6150        final int targetUid;
6151        final int flags;
6152
6153        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6154            this.targetPkg = targetPkg;
6155            this.targetUid = targetUid;
6156            this.flags = flags;
6157        }
6158    }
6159
6160    /**
6161     * Like checkGrantUriPermissionLocked, but takes an Intent.
6162     */
6163    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6164            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6165        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6166                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6167                + " clip=" + (intent != null ? intent.getClipData() : null)
6168                + " from " + intent + "; flags=0x"
6169                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6170
6171        if (targetPkg == null) {
6172            throw new NullPointerException("targetPkg");
6173        }
6174
6175        if (intent == null) {
6176            return null;
6177        }
6178        Uri data = intent.getData();
6179        ClipData clip = intent.getClipData();
6180        if (data == null && clip == null) {
6181            return null;
6182        }
6183
6184        if (data != null) {
6185            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6186                mode, needed != null ? needed.targetUid : -1);
6187            if (targetUid > 0) {
6188                if (needed == null) {
6189                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6190                }
6191                needed.add(data);
6192            }
6193        }
6194        if (clip != null) {
6195            for (int i=0; i<clip.getItemCount(); i++) {
6196                Uri uri = clip.getItemAt(i).getUri();
6197                if (uri != null) {
6198                    int targetUid = -1;
6199                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6200                            mode, needed != null ? needed.targetUid : -1);
6201                    if (targetUid > 0) {
6202                        if (needed == null) {
6203                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6204                        }
6205                        needed.add(uri);
6206                    }
6207                } else {
6208                    Intent clipIntent = clip.getItemAt(i).getIntent();
6209                    if (clipIntent != null) {
6210                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6211                                callingUid, targetPkg, clipIntent, mode, needed);
6212                        if (newNeeded != null) {
6213                            needed = newNeeded;
6214                        }
6215                    }
6216                }
6217            }
6218        }
6219
6220        return needed;
6221    }
6222
6223    /**
6224     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6225     */
6226    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6227            UriPermissionOwner owner) {
6228        if (needed != null) {
6229            for (int i=0; i<needed.size(); i++) {
6230                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6231                        needed.get(i), needed.flags, owner);
6232            }
6233        }
6234    }
6235
6236    void grantUriPermissionFromIntentLocked(int callingUid,
6237            String targetPkg, Intent intent, UriPermissionOwner owner) {
6238        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6239                intent, intent != null ? intent.getFlags() : 0, null);
6240        if (needed == null) {
6241            return;
6242        }
6243
6244        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6245    }
6246
6247    @Override
6248    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6249            Uri uri, int modeFlags) {
6250        enforceNotIsolatedCaller("grantUriPermission");
6251        synchronized(this) {
6252            final ProcessRecord r = getRecordForAppLocked(caller);
6253            if (r == null) {
6254                throw new SecurityException("Unable to find app for caller "
6255                        + caller
6256                        + " when granting permission to uri " + uri);
6257            }
6258            if (targetPkg == null) {
6259                throw new IllegalArgumentException("null target");
6260            }
6261            if (uri == null) {
6262                throw new IllegalArgumentException("null uri");
6263            }
6264
6265            // Persistable only supported through Intents
6266            Preconditions.checkFlagsArgument(modeFlags,
6267                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6268
6269            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6270                    null);
6271        }
6272    }
6273
6274    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6275        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6276                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6277            ArrayMap<Uri, UriPermission> perms
6278                    = mGrantedUriPermissions.get(perm.targetUid);
6279            if (perms != null) {
6280                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6281                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6282                perms.remove(perm.uri);
6283                if (perms.size() == 0) {
6284                    mGrantedUriPermissions.remove(perm.targetUid);
6285                }
6286            }
6287        }
6288    }
6289
6290    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6291        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6292
6293        final IPackageManager pm = AppGlobals.getPackageManager();
6294        final String authority = uri.getAuthority();
6295        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6296        if (pi == null) {
6297            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6298            return;
6299        }
6300
6301        // Does the caller have this permission on the URI?
6302        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6303            // Right now, if you are not the original owner of the permission,
6304            // you are not allowed to revoke it.
6305            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6306                throw new SecurityException("Uid " + callingUid
6307                        + " does not have permission to uri " + uri);
6308            //}
6309        }
6310
6311        boolean persistChanged = false;
6312
6313        // Go through all of the permissions and remove any that match.
6314        final List<String> SEGMENTS = uri.getPathSegments();
6315        if (SEGMENTS != null) {
6316            final int NS = SEGMENTS.size();
6317            int N = mGrantedUriPermissions.size();
6318            for (int i=0; i<N; i++) {
6319                ArrayMap<Uri, UriPermission> perms
6320                        = mGrantedUriPermissions.valueAt(i);
6321                Iterator<UriPermission> it = perms.values().iterator();
6322            toploop:
6323                while (it.hasNext()) {
6324                    UriPermission perm = it.next();
6325                    Uri targetUri = perm.uri;
6326                    if (!authority.equals(targetUri.getAuthority())) {
6327                        continue;
6328                    }
6329                    List<String> targetSegments = targetUri.getPathSegments();
6330                    if (targetSegments == null) {
6331                        continue;
6332                    }
6333                    if (targetSegments.size() < NS) {
6334                        continue;
6335                    }
6336                    for (int j=0; j<NS; j++) {
6337                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6338                            continue toploop;
6339                        }
6340                    }
6341                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6342                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6343                    persistChanged |= perm.clearModes(modeFlags, true);
6344                    if (perm.modeFlags == 0) {
6345                        it.remove();
6346                    }
6347                }
6348                if (perms.size() == 0) {
6349                    mGrantedUriPermissions.remove(
6350                            mGrantedUriPermissions.keyAt(i));
6351                    N--;
6352                    i--;
6353                }
6354            }
6355        }
6356
6357        if (persistChanged) {
6358            schedulePersistUriGrants();
6359        }
6360    }
6361
6362    @Override
6363    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6364            int modeFlags) {
6365        enforceNotIsolatedCaller("revokeUriPermission");
6366        synchronized(this) {
6367            final ProcessRecord r = getRecordForAppLocked(caller);
6368            if (r == null) {
6369                throw new SecurityException("Unable to find app for caller "
6370                        + caller
6371                        + " when revoking permission to uri " + uri);
6372            }
6373            if (uri == null) {
6374                Slog.w(TAG, "revokeUriPermission: null uri");
6375                return;
6376            }
6377
6378            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6379                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6380            if (modeFlags == 0) {
6381                return;
6382            }
6383
6384            final IPackageManager pm = AppGlobals.getPackageManager();
6385            final String authority = uri.getAuthority();
6386            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6387            if (pi == null) {
6388                Slog.w(TAG, "No content provider found for permission revoke: "
6389                        + uri.toSafeString());
6390                return;
6391            }
6392
6393            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6394        }
6395    }
6396
6397    /**
6398     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6399     * given package.
6400     *
6401     * @param packageName Package name to match, or {@code null} to apply to all
6402     *            packages.
6403     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6404     *            to all users.
6405     * @param persistable If persistable grants should be removed.
6406     */
6407    private void removeUriPermissionsForPackageLocked(
6408            String packageName, int userHandle, boolean persistable) {
6409        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6410            throw new IllegalArgumentException("Must narrow by either package or user");
6411        }
6412
6413        boolean persistChanged = false;
6414
6415        final int size = mGrantedUriPermissions.size();
6416        for (int i = 0; i < size; i++) {
6417            // Only inspect grants matching user
6418            if (userHandle == UserHandle.USER_ALL
6419                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6420                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6421                        .values().iterator();
6422                while (it.hasNext()) {
6423                    final UriPermission perm = it.next();
6424
6425                    // Only inspect grants matching package
6426                    if (packageName == null || perm.sourcePkg.equals(packageName)
6427                            || perm.targetPkg.equals(packageName)) {
6428                        persistChanged |= perm.clearModes(~0, persistable);
6429
6430                        // Only remove when no modes remain; any persisted grants
6431                        // will keep this alive.
6432                        if (perm.modeFlags == 0) {
6433                            it.remove();
6434                        }
6435                    }
6436                }
6437            }
6438        }
6439
6440        if (persistChanged) {
6441            schedulePersistUriGrants();
6442        }
6443    }
6444
6445    @Override
6446    public IBinder newUriPermissionOwner(String name) {
6447        enforceNotIsolatedCaller("newUriPermissionOwner");
6448        synchronized(this) {
6449            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6450            return owner.getExternalTokenLocked();
6451        }
6452    }
6453
6454    @Override
6455    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6456            Uri uri, int modeFlags) {
6457        synchronized(this) {
6458            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6459            if (owner == null) {
6460                throw new IllegalArgumentException("Unknown owner: " + token);
6461            }
6462            if (fromUid != Binder.getCallingUid()) {
6463                if (Binder.getCallingUid() != Process.myUid()) {
6464                    // Only system code can grant URI permissions on behalf
6465                    // of other users.
6466                    throw new SecurityException("nice try");
6467                }
6468            }
6469            if (targetPkg == null) {
6470                throw new IllegalArgumentException("null target");
6471            }
6472            if (uri == null) {
6473                throw new IllegalArgumentException("null uri");
6474            }
6475
6476            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6477        }
6478    }
6479
6480    @Override
6481    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6482        synchronized(this) {
6483            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6484            if (owner == null) {
6485                throw new IllegalArgumentException("Unknown owner: " + token);
6486            }
6487
6488            if (uri == null) {
6489                owner.removeUriPermissionsLocked(mode);
6490            } else {
6491                owner.removeUriPermissionLocked(uri, mode);
6492            }
6493        }
6494    }
6495
6496    private void schedulePersistUriGrants() {
6497        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6498            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6499                    10 * DateUtils.SECOND_IN_MILLIS);
6500        }
6501    }
6502
6503    private void writeGrantedUriPermissions() {
6504        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6505
6506        // Snapshot permissions so we can persist without lock
6507        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6508        synchronized (this) {
6509            final int size = mGrantedUriPermissions.size();
6510            for (int i = 0 ; i < size; i++) {
6511                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6512                    if (perm.persistedModeFlags != 0) {
6513                        persist.add(perm.snapshot());
6514                    }
6515                }
6516            }
6517        }
6518
6519        FileOutputStream fos = null;
6520        try {
6521            fos = mGrantFile.startWrite();
6522
6523            XmlSerializer out = new FastXmlSerializer();
6524            out.setOutput(fos, "utf-8");
6525            out.startDocument(null, true);
6526            out.startTag(null, TAG_URI_GRANTS);
6527            for (UriPermission.Snapshot perm : persist) {
6528                out.startTag(null, TAG_URI_GRANT);
6529                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6530                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6531                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6532                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6533                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6534                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6535                out.endTag(null, TAG_URI_GRANT);
6536            }
6537            out.endTag(null, TAG_URI_GRANTS);
6538            out.endDocument();
6539
6540            mGrantFile.finishWrite(fos);
6541        } catch (IOException e) {
6542            if (fos != null) {
6543                mGrantFile.failWrite(fos);
6544            }
6545        }
6546    }
6547
6548    private void readGrantedUriPermissionsLocked() {
6549        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6550
6551        final long now = System.currentTimeMillis();
6552
6553        FileInputStream fis = null;
6554        try {
6555            fis = mGrantFile.openRead();
6556            final XmlPullParser in = Xml.newPullParser();
6557            in.setInput(fis, null);
6558
6559            int type;
6560            while ((type = in.next()) != END_DOCUMENT) {
6561                final String tag = in.getName();
6562                if (type == START_TAG) {
6563                    if (TAG_URI_GRANT.equals(tag)) {
6564                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6565                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6566                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6567                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6568                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6569                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6570
6571                        // Sanity check that provider still belongs to source package
6572                        final ProviderInfo pi = getProviderInfoLocked(
6573                                uri.getAuthority(), userHandle);
6574                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6575                            int targetUid = -1;
6576                            try {
6577                                targetUid = AppGlobals.getPackageManager()
6578                                        .getPackageUid(targetPkg, userHandle);
6579                            } catch (RemoteException e) {
6580                            }
6581                            if (targetUid != -1) {
6582                                final UriPermission perm = findOrCreateUriPermissionLocked(
6583                                        sourcePkg, targetPkg, targetUid, uri);
6584                                perm.initPersistedModes(modeFlags, createdTime);
6585                            }
6586                        } else {
6587                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6588                                    + " but instead found " + pi);
6589                        }
6590                    }
6591                }
6592            }
6593        } catch (FileNotFoundException e) {
6594            // Missing grants is okay
6595        } catch (IOException e) {
6596            Log.wtf(TAG, "Failed reading Uri grants", e);
6597        } catch (XmlPullParserException e) {
6598            Log.wtf(TAG, "Failed reading Uri grants", e);
6599        } finally {
6600            IoUtils.closeQuietly(fis);
6601        }
6602    }
6603
6604    @Override
6605    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6606        enforceNotIsolatedCaller("takePersistableUriPermission");
6607
6608        Preconditions.checkFlagsArgument(modeFlags,
6609                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6610
6611        synchronized (this) {
6612            final int callingUid = Binder.getCallingUid();
6613            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6614            if (perm == null) {
6615                throw new SecurityException("No permission grant found for UID " + callingUid
6616                        + " and Uri " + uri.toSafeString());
6617            }
6618
6619            boolean persistChanged = perm.takePersistableModes(modeFlags);
6620            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6621
6622            if (persistChanged) {
6623                schedulePersistUriGrants();
6624            }
6625        }
6626    }
6627
6628    @Override
6629    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6630        enforceNotIsolatedCaller("releasePersistableUriPermission");
6631
6632        Preconditions.checkFlagsArgument(modeFlags,
6633                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6634
6635        synchronized (this) {
6636            final int callingUid = Binder.getCallingUid();
6637
6638            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6639            if (perm == null) {
6640                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6641                        + uri.toSafeString());
6642                return;
6643            }
6644
6645            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6646            removeUriPermissionIfNeededLocked(perm);
6647            if (persistChanged) {
6648                schedulePersistUriGrants();
6649            }
6650        }
6651    }
6652
6653    /**
6654     * Prune any older {@link UriPermission} for the given UID until outstanding
6655     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6656     *
6657     * @return if any mutations occured that require persisting.
6658     */
6659    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6660        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6661        if (perms == null) return false;
6662        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6663
6664        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6665        for (UriPermission perm : perms.values()) {
6666            if (perm.persistedModeFlags != 0) {
6667                persisted.add(perm);
6668            }
6669        }
6670
6671        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6672        if (trimCount <= 0) return false;
6673
6674        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6675        for (int i = 0; i < trimCount; i++) {
6676            final UriPermission perm = persisted.get(i);
6677
6678            if (DEBUG_URI_PERMISSION) {
6679                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6680            }
6681
6682            perm.releasePersistableModes(~0);
6683            removeUriPermissionIfNeededLocked(perm);
6684        }
6685
6686        return true;
6687    }
6688
6689    @Override
6690    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6691            String packageName, boolean incoming) {
6692        enforceNotIsolatedCaller("getPersistedUriPermissions");
6693        Preconditions.checkNotNull(packageName, "packageName");
6694
6695        final int callingUid = Binder.getCallingUid();
6696        final IPackageManager pm = AppGlobals.getPackageManager();
6697        try {
6698            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6699            if (packageUid != callingUid) {
6700                throw new SecurityException(
6701                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6702            }
6703        } catch (RemoteException e) {
6704            throw new SecurityException("Failed to verify package name ownership");
6705        }
6706
6707        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6708        synchronized (this) {
6709            if (incoming) {
6710                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6711                if (perms == null) {
6712                    Slog.w(TAG, "No permission grants found for " + packageName);
6713                } else {
6714                    final int size = perms.size();
6715                    for (int i = 0; i < size; i++) {
6716                        final UriPermission perm = perms.valueAt(i);
6717                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6718                            result.add(perm.buildPersistedPublicApiObject());
6719                        }
6720                    }
6721                }
6722            } else {
6723                final int size = mGrantedUriPermissions.size();
6724                for (int i = 0; i < size; i++) {
6725                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6726                    final int permsSize = perms.size();
6727                    for (int j = 0; j < permsSize; j++) {
6728                        final UriPermission perm = perms.valueAt(j);
6729                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6730                            result.add(perm.buildPersistedPublicApiObject());
6731                        }
6732                    }
6733                }
6734            }
6735        }
6736        return new ParceledListSlice<android.content.UriPermission>(result);
6737    }
6738
6739    @Override
6740    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6741        synchronized (this) {
6742            ProcessRecord app =
6743                who != null ? getRecordForAppLocked(who) : null;
6744            if (app == null) return;
6745
6746            Message msg = Message.obtain();
6747            msg.what = WAIT_FOR_DEBUGGER_MSG;
6748            msg.obj = app;
6749            msg.arg1 = waiting ? 1 : 0;
6750            mHandler.sendMessage(msg);
6751        }
6752    }
6753
6754    @Override
6755    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6756        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6757        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6758        outInfo.availMem = Process.getFreeMemory();
6759        outInfo.totalMem = Process.getTotalMemory();
6760        outInfo.threshold = homeAppMem;
6761        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6762        outInfo.hiddenAppThreshold = cachedAppMem;
6763        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6764                ProcessList.SERVICE_ADJ);
6765        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6766                ProcessList.VISIBLE_APP_ADJ);
6767        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6768                ProcessList.FOREGROUND_APP_ADJ);
6769    }
6770
6771    // =========================================================
6772    // TASK MANAGEMENT
6773    // =========================================================
6774
6775    @Override
6776    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6777                         IThumbnailReceiver receiver) {
6778        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6779
6780        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6781        ActivityRecord topRecord = null;
6782
6783        synchronized(this) {
6784            if (localLOGV) Slog.v(
6785                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6786                + ", receiver=" + receiver);
6787
6788            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6789                    != PackageManager.PERMISSION_GRANTED) {
6790                if (receiver != null) {
6791                    // If the caller wants to wait for pending thumbnails,
6792                    // it ain't gonna get them.
6793                    try {
6794                        receiver.finished();
6795                    } catch (RemoteException ex) {
6796                    }
6797                }
6798                String msg = "Permission Denial: getTasks() from pid="
6799                        + Binder.getCallingPid()
6800                        + ", uid=" + Binder.getCallingUid()
6801                        + " requires " + android.Manifest.permission.GET_TASKS;
6802                Slog.w(TAG, msg);
6803                throw new SecurityException(msg);
6804            }
6805
6806            // TODO: Improve with MRU list from all ActivityStacks.
6807            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6808
6809            if (!pending.pendingRecords.isEmpty()) {
6810                mPendingThumbnails.add(pending);
6811            }
6812        }
6813
6814        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6815
6816        if (topRecord != null) {
6817            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6818            try {
6819                IApplicationThread topThumbnail = topRecord.app.thread;
6820                topThumbnail.requestThumbnail(topRecord.appToken);
6821            } catch (Exception e) {
6822                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6823                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6824            }
6825        }
6826
6827        if (pending.pendingRecords.isEmpty() && receiver != null) {
6828            // In this case all thumbnails were available and the client
6829            // is being asked to be told when the remaining ones come in...
6830            // which is unusually, since the top-most currently running
6831            // activity should never have a canned thumbnail!  Oh well.
6832            try {
6833                receiver.finished();
6834            } catch (RemoteException ex) {
6835            }
6836        }
6837
6838        return list;
6839    }
6840
6841    TaskRecord getMostRecentTask() {
6842        return mRecentTasks.get(0);
6843    }
6844
6845    @Override
6846    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6847            int flags, int userId) {
6848        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6849                false, true, "getRecentTasks", null);
6850
6851        synchronized (this) {
6852            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6853                    "getRecentTasks()");
6854            final boolean detailed = checkCallingPermission(
6855                    android.Manifest.permission.GET_DETAILED_TASKS)
6856                    == PackageManager.PERMISSION_GRANTED;
6857
6858            IPackageManager pm = AppGlobals.getPackageManager();
6859
6860            final int N = mRecentTasks.size();
6861            ArrayList<ActivityManager.RecentTaskInfo> res
6862                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6863                            maxNum < N ? maxNum : N);
6864
6865            final Set<Integer> includedUsers;
6866            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
6867                includedUsers = getProfileIdsLocked(userId);
6868            } else {
6869                includedUsers = new HashSet<Integer>();
6870            }
6871            includedUsers.add(Integer.valueOf(userId));
6872            for (int i=0; i<N && maxNum > 0; i++) {
6873                TaskRecord tr = mRecentTasks.get(i);
6874                // Only add calling user or related users recent tasks
6875                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6876
6877                // Return the entry if desired by the caller.  We always return
6878                // the first entry, because callers always expect this to be the
6879                // foreground app.  We may filter others if the caller has
6880                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6881                // we should exclude the entry.
6882
6883                if (i == 0
6884                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6885                        || (tr.intent == null)
6886                        || ((tr.intent.getFlags()
6887                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6888                    ActivityManager.RecentTaskInfo rti
6889                            = new ActivityManager.RecentTaskInfo();
6890                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6891                    rti.persistentId = tr.taskId;
6892                    rti.baseIntent = new Intent(
6893                            tr.intent != null ? tr.intent : tr.affinityIntent);
6894                    if (!detailed) {
6895                        rti.baseIntent.replaceExtras((Bundle)null);
6896                    }
6897                    rti.origActivity = tr.origActivity;
6898                    rti.description = tr.lastDescription;
6899                    rti.stackId = tr.stack.mStackId;
6900                    rti.userId = tr.userId;
6901
6902                    final ArrayList<ActivityRecord> activities = tr.mActivities;
6903                    int numSet = 0;
6904                    for (int activityNdx = activities.size() - 1; activityNdx >= 0 && numSet < 2;
6905                            --activityNdx) {
6906                        final ActivityRecord r = activities.get(activityNdx);
6907                        if (rti.activityLabel == null && r.recentsLabel != null) {
6908                            rti.activityLabel = r.recentsLabel;
6909                            ++numSet;
6910                        }
6911                        if (rti.activityIcon == null && r.recentsIcon != null) {
6912                            rti.activityIcon = r.recentsIcon;
6913                            ++numSet;
6914                        }
6915                    }
6916
6917                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6918                        // Check whether this activity is currently available.
6919                        try {
6920                            if (rti.origActivity != null) {
6921                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6922                                        == null) {
6923                                    continue;
6924                                }
6925                            } else if (rti.baseIntent != null) {
6926                                if (pm.queryIntentActivities(rti.baseIntent,
6927                                        null, 0, userId) == null) {
6928                                    continue;
6929                                }
6930                            }
6931                        } catch (RemoteException e) {
6932                            // Will never happen.
6933                        }
6934                    }
6935
6936                    res.add(rti);
6937                    maxNum--;
6938                }
6939            }
6940            return res;
6941        }
6942    }
6943
6944    private TaskRecord recentTaskForIdLocked(int id) {
6945        final int N = mRecentTasks.size();
6946            for (int i=0; i<N; i++) {
6947                TaskRecord tr = mRecentTasks.get(i);
6948                if (tr.taskId == id) {
6949                    return tr;
6950                }
6951            }
6952            return null;
6953    }
6954
6955    @Override
6956    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6957        synchronized (this) {
6958            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6959                    "getTaskThumbnails()");
6960            TaskRecord tr = recentTaskForIdLocked(id);
6961            if (tr != null) {
6962                return tr.getTaskThumbnailsLocked();
6963            }
6964        }
6965        return null;
6966    }
6967
6968    @Override
6969    public Bitmap getTaskTopThumbnail(int id) {
6970        synchronized (this) {
6971            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6972                    "getTaskTopThumbnail()");
6973            TaskRecord tr = recentTaskForIdLocked(id);
6974            if (tr != null) {
6975                return tr.getTaskTopThumbnailLocked();
6976            }
6977        }
6978        return null;
6979    }
6980
6981    @Override
6982    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) {
6983        synchronized (this) {
6984            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6985            if (r != null) {
6986                r.recentsLabel = recentsLabel.toString();
6987            }
6988        }
6989    }
6990
6991    @Override
6992    public void setRecentsIcon(IBinder token, Bitmap recentsIcon) {
6993        synchronized (this) {
6994            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6995            if (r != null) {
6996                r.recentsIcon = recentsIcon;
6997            }
6998        }
6999    }
7000
7001    @Override
7002    public boolean removeSubTask(int taskId, int subTaskIndex) {
7003        synchronized (this) {
7004            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7005                    "removeSubTask()");
7006            long ident = Binder.clearCallingIdentity();
7007            try {
7008                TaskRecord tr = recentTaskForIdLocked(taskId);
7009                if (tr != null) {
7010                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7011                }
7012                return false;
7013            } finally {
7014                Binder.restoreCallingIdentity(ident);
7015            }
7016        }
7017    }
7018
7019    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7020        if (!pr.killedByAm) {
7021            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7022            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7023                    pr.processName, pr.setAdj, reason);
7024            pr.killedByAm = true;
7025            Process.killProcessQuiet(pr.pid);
7026        }
7027    }
7028
7029    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7030        tr.disposeThumbnail();
7031        mRecentTasks.remove(tr);
7032        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7033        Intent baseIntent = new Intent(
7034                tr.intent != null ? tr.intent : tr.affinityIntent);
7035        ComponentName component = baseIntent.getComponent();
7036        if (component == null) {
7037            Slog.w(TAG, "Now component for base intent of task: " + tr);
7038            return;
7039        }
7040
7041        // Find any running services associated with this app.
7042        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7043
7044        if (killProcesses) {
7045            // Find any running processes associated with this app.
7046            final String pkg = component.getPackageName();
7047            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7048            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7049            for (int i=0; i<pmap.size(); i++) {
7050                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7051                for (int j=0; j<uids.size(); j++) {
7052                    ProcessRecord proc = uids.valueAt(j);
7053                    if (proc.userId != tr.userId) {
7054                        continue;
7055                    }
7056                    if (!proc.pkgList.containsKey(pkg)) {
7057                        continue;
7058                    }
7059                    procs.add(proc);
7060                }
7061            }
7062
7063            // Kill the running processes.
7064            for (int i=0; i<procs.size(); i++) {
7065                ProcessRecord pr = procs.get(i);
7066                if (pr == mHomeProcess) {
7067                    // Don't kill the home process along with tasks from the same package.
7068                    continue;
7069                }
7070                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7071                    killUnneededProcessLocked(pr, "remove task");
7072                } else {
7073                    pr.waitingToKill = "remove task";
7074                }
7075            }
7076        }
7077    }
7078
7079    @Override
7080    public boolean removeTask(int taskId, int flags) {
7081        synchronized (this) {
7082            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7083                    "removeTask()");
7084            long ident = Binder.clearCallingIdentity();
7085            try {
7086                TaskRecord tr = recentTaskForIdLocked(taskId);
7087                if (tr != null) {
7088                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7089                    if (r != null) {
7090                        cleanUpRemovedTaskLocked(tr, flags);
7091                        return true;
7092                    }
7093                    if (tr.mActivities.size() == 0) {
7094                        // Caller is just removing a recent task that is
7095                        // not actively running.  That is easy!
7096                        cleanUpRemovedTaskLocked(tr, flags);
7097                        return true;
7098                    }
7099                    Slog.w(TAG, "removeTask: task " + taskId
7100                            + " does not have activities to remove, "
7101                            + " but numActivities=" + tr.numActivities
7102                            + ": " + tr);
7103                }
7104            } finally {
7105                Binder.restoreCallingIdentity(ident);
7106            }
7107        }
7108        return false;
7109    }
7110
7111    /**
7112     * TODO: Add mController hook
7113     */
7114    @Override
7115    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7116        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7117                "moveTaskToFront()");
7118
7119        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7120        synchronized(this) {
7121            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7122                    Binder.getCallingUid(), "Task to front")) {
7123                ActivityOptions.abort(options);
7124                return;
7125            }
7126            final long origId = Binder.clearCallingIdentity();
7127            try {
7128                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7129                if (task == null) {
7130                    return;
7131                }
7132                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7133                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7134                    return;
7135                }
7136                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7137            } finally {
7138                Binder.restoreCallingIdentity(origId);
7139            }
7140            ActivityOptions.abort(options);
7141        }
7142    }
7143
7144    @Override
7145    public void moveTaskToBack(int taskId) {
7146        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7147                "moveTaskToBack()");
7148
7149        synchronized(this) {
7150            TaskRecord tr = recentTaskForIdLocked(taskId);
7151            if (tr != null) {
7152                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7153                ActivityStack stack = tr.stack;
7154                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7155                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7156                            Binder.getCallingUid(), "Task to back")) {
7157                        return;
7158                    }
7159                }
7160                final long origId = Binder.clearCallingIdentity();
7161                try {
7162                    stack.moveTaskToBackLocked(taskId, null);
7163                } finally {
7164                    Binder.restoreCallingIdentity(origId);
7165                }
7166            }
7167        }
7168    }
7169
7170    /**
7171     * Moves an activity, and all of the other activities within the same task, to the bottom
7172     * of the history stack.  The activity's order within the task is unchanged.
7173     *
7174     * @param token A reference to the activity we wish to move
7175     * @param nonRoot If false then this only works if the activity is the root
7176     *                of a task; if true it will work for any activity in a task.
7177     * @return Returns true if the move completed, false if not.
7178     */
7179    @Override
7180    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7181        enforceNotIsolatedCaller("moveActivityTaskToBack");
7182        synchronized(this) {
7183            final long origId = Binder.clearCallingIdentity();
7184            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7185            if (taskId >= 0) {
7186                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7187            }
7188            Binder.restoreCallingIdentity(origId);
7189        }
7190        return false;
7191    }
7192
7193    @Override
7194    public void moveTaskBackwards(int task) {
7195        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7196                "moveTaskBackwards()");
7197
7198        synchronized(this) {
7199            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7200                    Binder.getCallingUid(), "Task backwards")) {
7201                return;
7202            }
7203            final long origId = Binder.clearCallingIdentity();
7204            moveTaskBackwardsLocked(task);
7205            Binder.restoreCallingIdentity(origId);
7206        }
7207    }
7208
7209    private final void moveTaskBackwardsLocked(int task) {
7210        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7211    }
7212
7213    @Override
7214    public IBinder getHomeActivityToken() throws RemoteException {
7215        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7216                "getHomeActivityToken()");
7217        synchronized (this) {
7218            return mStackSupervisor.getHomeActivityToken();
7219        }
7220    }
7221
7222    @Override
7223    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7224            IActivityContainerCallback callback) throws RemoteException {
7225        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7226                "createActivityContainer()");
7227        synchronized (this) {
7228            if (parentActivityToken == null) {
7229                throw new IllegalArgumentException("parent token must not be null");
7230            }
7231            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7232            if (r == null) {
7233                return null;
7234            }
7235            return mStackSupervisor.createActivityContainer(r, callback);
7236        }
7237    }
7238
7239    @Override
7240    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7241        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7242                "deleteActivityContainer()");
7243        synchronized (this) {
7244            mStackSupervisor.deleteActivityContainer(container);
7245        }
7246    }
7247
7248    @Override
7249    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7250            throws RemoteException {
7251        synchronized (this) {
7252            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7253            if (stack != null) {
7254                return stack.mActivityContainer;
7255            }
7256            return null;
7257        }
7258    }
7259
7260    @Override
7261    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7262        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7263                "moveTaskToStack()");
7264        if (stackId == HOME_STACK_ID) {
7265            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7266                    new RuntimeException("here").fillInStackTrace());
7267        }
7268        synchronized (this) {
7269            long ident = Binder.clearCallingIdentity();
7270            try {
7271                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7272                        + stackId + " toTop=" + toTop);
7273                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7274            } finally {
7275                Binder.restoreCallingIdentity(ident);
7276            }
7277        }
7278    }
7279
7280    @Override
7281    public void resizeStack(int stackBoxId, Rect bounds) {
7282        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7283                "resizeStackBox()");
7284        long ident = Binder.clearCallingIdentity();
7285        try {
7286            mWindowManager.resizeStack(stackBoxId, bounds);
7287        } finally {
7288            Binder.restoreCallingIdentity(ident);
7289        }
7290    }
7291
7292    @Override
7293    public List<StackInfo> getAllStackInfos() {
7294        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7295                "getAllStackInfos()");
7296        long ident = Binder.clearCallingIdentity();
7297        try {
7298            synchronized (this) {
7299                return mStackSupervisor.getAllStackInfosLocked();
7300            }
7301        } finally {
7302            Binder.restoreCallingIdentity(ident);
7303        }
7304    }
7305
7306    @Override
7307    public StackInfo getStackInfo(int stackId) {
7308        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7309                "getStackInfo()");
7310        long ident = Binder.clearCallingIdentity();
7311        try {
7312            synchronized (this) {
7313                return mStackSupervisor.getStackInfoLocked(stackId);
7314            }
7315        } finally {
7316            Binder.restoreCallingIdentity(ident);
7317        }
7318    }
7319
7320    @Override
7321    public boolean isInHomeStack(int taskId) {
7322        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7323                "getStackInfo()");
7324        long ident = Binder.clearCallingIdentity();
7325        try {
7326            synchronized (this) {
7327                TaskRecord tr = recentTaskForIdLocked(taskId);
7328                if (tr != null) {
7329                    return tr.stack.isHomeStack();
7330                }
7331            }
7332        } finally {
7333            Binder.restoreCallingIdentity(ident);
7334        }
7335        return false;
7336    }
7337
7338    @Override
7339    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7340        synchronized(this) {
7341            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7342        }
7343    }
7344
7345    private boolean isLockTaskAuthorized(ComponentName name) {
7346//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7347//                "startLockTaskMode()");
7348//        DevicePolicyManager dpm = (DevicePolicyManager)
7349//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7350//        return dpm != null && dpm.isLockTaskPermitted(name);
7351        return true;
7352    }
7353
7354    private void startLockTaskMode(TaskRecord task) {
7355        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7356            return;
7357        }
7358        long ident = Binder.clearCallingIdentity();
7359        try {
7360            synchronized (this) {
7361                // Since we lost lock on task, make sure it is still there.
7362                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7363                if (task != null) {
7364                    mStackSupervisor.setLockTaskModeLocked(task);
7365                }
7366            }
7367        } finally {
7368            Binder.restoreCallingIdentity(ident);
7369        }
7370    }
7371
7372    @Override
7373    public void startLockTaskMode(int taskId) {
7374        long ident = Binder.clearCallingIdentity();
7375        try {
7376            final TaskRecord task;
7377            synchronized (this) {
7378                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7379            }
7380            if (task != null) {
7381                startLockTaskMode(task);
7382            }
7383        } finally {
7384            Binder.restoreCallingIdentity(ident);
7385        }
7386    }
7387
7388    @Override
7389    public void startLockTaskMode(IBinder token) {
7390        long ident = Binder.clearCallingIdentity();
7391        try {
7392            final TaskRecord task;
7393            synchronized (this) {
7394                final ActivityRecord r = ActivityRecord.forToken(token);
7395                if (r == null) {
7396                    return;
7397                }
7398                task = r.task;
7399            }
7400            if (task != null) {
7401                startLockTaskMode(task);
7402            }
7403        } finally {
7404            Binder.restoreCallingIdentity(ident);
7405        }
7406    }
7407
7408    @Override
7409    public void stopLockTaskMode() {
7410//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7411//                "stopLockTaskMode()");
7412        synchronized (this) {
7413            mStackSupervisor.setLockTaskModeLocked(null);
7414        }
7415    }
7416
7417    @Override
7418    public boolean isInLockTaskMode() {
7419        synchronized (this) {
7420            return mStackSupervisor.isInLockTaskMode();
7421        }
7422    }
7423
7424    // =========================================================
7425    // THUMBNAILS
7426    // =========================================================
7427
7428    public void reportThumbnail(IBinder token,
7429            Bitmap thumbnail, CharSequence description) {
7430        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7431        final long origId = Binder.clearCallingIdentity();
7432        sendPendingThumbnail(null, token, thumbnail, description, true);
7433        Binder.restoreCallingIdentity(origId);
7434    }
7435
7436    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7437            Bitmap thumbnail, CharSequence description, boolean always) {
7438        TaskRecord task;
7439        ArrayList<PendingThumbnailsRecord> receivers = null;
7440
7441        //System.out.println("Send pending thumbnail: " + r);
7442
7443        synchronized(this) {
7444            if (r == null) {
7445                r = ActivityRecord.isInStackLocked(token);
7446                if (r == null) {
7447                    return;
7448                }
7449            }
7450            if (thumbnail == null && r.thumbHolder != null) {
7451                thumbnail = r.thumbHolder.lastThumbnail;
7452                description = r.thumbHolder.lastDescription;
7453            }
7454            if (thumbnail == null && !always) {
7455                // If there is no thumbnail, and this entry is not actually
7456                // going away, then abort for now and pick up the next
7457                // thumbnail we get.
7458                return;
7459            }
7460            task = r.task;
7461
7462            int N = mPendingThumbnails.size();
7463            int i=0;
7464            while (i<N) {
7465                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7466                //System.out.println("Looking in " + pr.pendingRecords);
7467                if (pr.pendingRecords.remove(r)) {
7468                    if (receivers == null) {
7469                        receivers = new ArrayList<PendingThumbnailsRecord>();
7470                    }
7471                    receivers.add(pr);
7472                    if (pr.pendingRecords.size() == 0) {
7473                        pr.finished = true;
7474                        mPendingThumbnails.remove(i);
7475                        N--;
7476                        continue;
7477                    }
7478                }
7479                i++;
7480            }
7481        }
7482
7483        if (receivers != null) {
7484            final int N = receivers.size();
7485            for (int i=0; i<N; i++) {
7486                try {
7487                    PendingThumbnailsRecord pr = receivers.get(i);
7488                    pr.receiver.newThumbnail(
7489                        task != null ? task.taskId : -1, thumbnail, description);
7490                    if (pr.finished) {
7491                        pr.receiver.finished();
7492                    }
7493                } catch (Exception e) {
7494                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7495                }
7496            }
7497        }
7498    }
7499
7500    // =========================================================
7501    // CONTENT PROVIDERS
7502    // =========================================================
7503
7504    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7505        List<ProviderInfo> providers = null;
7506        try {
7507            providers = AppGlobals.getPackageManager().
7508                queryContentProviders(app.processName, app.uid,
7509                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7510        } catch (RemoteException ex) {
7511        }
7512        if (DEBUG_MU)
7513            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7514        int userId = app.userId;
7515        if (providers != null) {
7516            int N = providers.size();
7517            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7518            for (int i=0; i<N; i++) {
7519                ProviderInfo cpi =
7520                    (ProviderInfo)providers.get(i);
7521                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7522                        cpi.name, cpi.flags);
7523                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7524                    // This is a singleton provider, but a user besides the
7525                    // default user is asking to initialize a process it runs
7526                    // in...  well, no, it doesn't actually run in this process,
7527                    // it runs in the process of the default user.  Get rid of it.
7528                    providers.remove(i);
7529                    N--;
7530                    i--;
7531                    continue;
7532                }
7533
7534                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7535                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7536                if (cpr == null) {
7537                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7538                    mProviderMap.putProviderByClass(comp, cpr);
7539                }
7540                if (DEBUG_MU)
7541                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7542                app.pubProviders.put(cpi.name, cpr);
7543                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7544                    // Don't add this if it is a platform component that is marked
7545                    // to run in multiple processes, because this is actually
7546                    // part of the framework so doesn't make sense to track as a
7547                    // separate apk in the process.
7548                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7549                }
7550                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7551            }
7552        }
7553        return providers;
7554    }
7555
7556    /**
7557     * Check if {@link ProcessRecord} has a possible chance at accessing the
7558     * given {@link ProviderInfo}. Final permission checking is always done
7559     * in {@link ContentProvider}.
7560     */
7561    private final String checkContentProviderPermissionLocked(
7562            ProviderInfo cpi, ProcessRecord r) {
7563        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7564        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7565        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7566                cpi.applicationInfo.uid, cpi.exported)
7567                == PackageManager.PERMISSION_GRANTED) {
7568            return null;
7569        }
7570        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7571                cpi.applicationInfo.uid, cpi.exported)
7572                == PackageManager.PERMISSION_GRANTED) {
7573            return null;
7574        }
7575
7576        PathPermission[] pps = cpi.pathPermissions;
7577        if (pps != null) {
7578            int i = pps.length;
7579            while (i > 0) {
7580                i--;
7581                PathPermission pp = pps[i];
7582                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7583                        cpi.applicationInfo.uid, cpi.exported)
7584                        == PackageManager.PERMISSION_GRANTED) {
7585                    return null;
7586                }
7587                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7588                        cpi.applicationInfo.uid, cpi.exported)
7589                        == PackageManager.PERMISSION_GRANTED) {
7590                    return null;
7591                }
7592            }
7593        }
7594
7595        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7596        if (perms != null) {
7597            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7598                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7599                    return null;
7600                }
7601            }
7602        }
7603
7604        String msg;
7605        if (!cpi.exported) {
7606            msg = "Permission Denial: opening provider " + cpi.name
7607                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7608                    + ", uid=" + callingUid + ") that is not exported from uid "
7609                    + cpi.applicationInfo.uid;
7610        } else {
7611            msg = "Permission Denial: opening provider " + cpi.name
7612                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7613                    + ", uid=" + callingUid + ") requires "
7614                    + cpi.readPermission + " or " + cpi.writePermission;
7615        }
7616        Slog.w(TAG, msg);
7617        return msg;
7618    }
7619
7620    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7621            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7622        if (r != null) {
7623            for (int i=0; i<r.conProviders.size(); i++) {
7624                ContentProviderConnection conn = r.conProviders.get(i);
7625                if (conn.provider == cpr) {
7626                    if (DEBUG_PROVIDER) Slog.v(TAG,
7627                            "Adding provider requested by "
7628                            + r.processName + " from process "
7629                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7630                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7631                    if (stable) {
7632                        conn.stableCount++;
7633                        conn.numStableIncs++;
7634                    } else {
7635                        conn.unstableCount++;
7636                        conn.numUnstableIncs++;
7637                    }
7638                    return conn;
7639                }
7640            }
7641            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7642            if (stable) {
7643                conn.stableCount = 1;
7644                conn.numStableIncs = 1;
7645            } else {
7646                conn.unstableCount = 1;
7647                conn.numUnstableIncs = 1;
7648            }
7649            cpr.connections.add(conn);
7650            r.conProviders.add(conn);
7651            return conn;
7652        }
7653        cpr.addExternalProcessHandleLocked(externalProcessToken);
7654        return null;
7655    }
7656
7657    boolean decProviderCountLocked(ContentProviderConnection conn,
7658            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7659        if (conn != null) {
7660            cpr = conn.provider;
7661            if (DEBUG_PROVIDER) Slog.v(TAG,
7662                    "Removing provider requested by "
7663                    + conn.client.processName + " from process "
7664                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7665                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7666            if (stable) {
7667                conn.stableCount--;
7668            } else {
7669                conn.unstableCount--;
7670            }
7671            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7672                cpr.connections.remove(conn);
7673                conn.client.conProviders.remove(conn);
7674                return true;
7675            }
7676            return false;
7677        }
7678        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7679        return false;
7680    }
7681
7682    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7683            String name, IBinder token, boolean stable, int userId) {
7684        ContentProviderRecord cpr;
7685        ContentProviderConnection conn = null;
7686        ProviderInfo cpi = null;
7687
7688        synchronized(this) {
7689            ProcessRecord r = null;
7690            if (caller != null) {
7691                r = getRecordForAppLocked(caller);
7692                if (r == null) {
7693                    throw new SecurityException(
7694                            "Unable to find app for caller " + caller
7695                          + " (pid=" + Binder.getCallingPid()
7696                          + ") when getting content provider " + name);
7697                }
7698            }
7699
7700            // First check if this content provider has been published...
7701            cpr = mProviderMap.getProviderByName(name, userId);
7702            boolean providerRunning = cpr != null;
7703            if (providerRunning) {
7704                cpi = cpr.info;
7705                String msg;
7706                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7707                    throw new SecurityException(msg);
7708                }
7709
7710                if (r != null && cpr.canRunHere(r)) {
7711                    // This provider has been published or is in the process
7712                    // of being published...  but it is also allowed to run
7713                    // in the caller's process, so don't make a connection
7714                    // and just let the caller instantiate its own instance.
7715                    ContentProviderHolder holder = cpr.newHolder(null);
7716                    // don't give caller the provider object, it needs
7717                    // to make its own.
7718                    holder.provider = null;
7719                    return holder;
7720                }
7721
7722                final long origId = Binder.clearCallingIdentity();
7723
7724                // In this case the provider instance already exists, so we can
7725                // return it right away.
7726                conn = incProviderCountLocked(r, cpr, token, stable);
7727                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7728                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7729                        // If this is a perceptible app accessing the provider,
7730                        // make sure to count it as being accessed and thus
7731                        // back up on the LRU list.  This is good because
7732                        // content providers are often expensive to start.
7733                        updateLruProcessLocked(cpr.proc, false, null);
7734                    }
7735                }
7736
7737                if (cpr.proc != null) {
7738                    if (false) {
7739                        if (cpr.name.flattenToShortString().equals(
7740                                "com.android.providers.calendar/.CalendarProvider2")) {
7741                            Slog.v(TAG, "****************** KILLING "
7742                                + cpr.name.flattenToShortString());
7743                            Process.killProcess(cpr.proc.pid);
7744                        }
7745                    }
7746                    boolean success = updateOomAdjLocked(cpr.proc);
7747                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7748                    // NOTE: there is still a race here where a signal could be
7749                    // pending on the process even though we managed to update its
7750                    // adj level.  Not sure what to do about this, but at least
7751                    // the race is now smaller.
7752                    if (!success) {
7753                        // Uh oh...  it looks like the provider's process
7754                        // has been killed on us.  We need to wait for a new
7755                        // process to be started, and make sure its death
7756                        // doesn't kill our process.
7757                        Slog.i(TAG,
7758                                "Existing provider " + cpr.name.flattenToShortString()
7759                                + " is crashing; detaching " + r);
7760                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7761                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7762                        if (!lastRef) {
7763                            // This wasn't the last ref our process had on
7764                            // the provider...  we have now been killed, bail.
7765                            return null;
7766                        }
7767                        providerRunning = false;
7768                        conn = null;
7769                    }
7770                }
7771
7772                Binder.restoreCallingIdentity(origId);
7773            }
7774
7775            boolean singleton;
7776            if (!providerRunning) {
7777                try {
7778                    cpi = AppGlobals.getPackageManager().
7779                        resolveContentProvider(name,
7780                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7781                } catch (RemoteException ex) {
7782                }
7783                if (cpi == null) {
7784                    return null;
7785                }
7786                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7787                        cpi.name, cpi.flags);
7788                if (singleton) {
7789                    userId = 0;
7790                }
7791                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7792
7793                String msg;
7794                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7795                    throw new SecurityException(msg);
7796                }
7797
7798                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7799                        && !cpi.processName.equals("system")) {
7800                    // If this content provider does not run in the system
7801                    // process, and the system is not yet ready to run other
7802                    // processes, then fail fast instead of hanging.
7803                    throw new IllegalArgumentException(
7804                            "Attempt to launch content provider before system ready");
7805                }
7806
7807                // Make sure that the user who owns this provider is started.  If not,
7808                // we don't want to allow it to run.
7809                if (mStartedUsers.get(userId) == null) {
7810                    Slog.w(TAG, "Unable to launch app "
7811                            + cpi.applicationInfo.packageName + "/"
7812                            + cpi.applicationInfo.uid + " for provider "
7813                            + name + ": user " + userId + " is stopped");
7814                    return null;
7815                }
7816
7817                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7818                cpr = mProviderMap.getProviderByClass(comp, userId);
7819                final boolean firstClass = cpr == null;
7820                if (firstClass) {
7821                    try {
7822                        ApplicationInfo ai =
7823                            AppGlobals.getPackageManager().
7824                                getApplicationInfo(
7825                                        cpi.applicationInfo.packageName,
7826                                        STOCK_PM_FLAGS, userId);
7827                        if (ai == null) {
7828                            Slog.w(TAG, "No package info for content provider "
7829                                    + cpi.name);
7830                            return null;
7831                        }
7832                        ai = getAppInfoForUser(ai, userId);
7833                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7834                    } catch (RemoteException ex) {
7835                        // pm is in same process, this will never happen.
7836                    }
7837                }
7838
7839                if (r != null && cpr.canRunHere(r)) {
7840                    // If this is a multiprocess provider, then just return its
7841                    // info and allow the caller to instantiate it.  Only do
7842                    // this if the provider is the same user as the caller's
7843                    // process, or can run as root (so can be in any process).
7844                    return cpr.newHolder(null);
7845                }
7846
7847                if (DEBUG_PROVIDER) {
7848                    RuntimeException e = new RuntimeException("here");
7849                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7850                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7851                }
7852
7853                // This is single process, and our app is now connecting to it.
7854                // See if we are already in the process of launching this
7855                // provider.
7856                final int N = mLaunchingProviders.size();
7857                int i;
7858                for (i=0; i<N; i++) {
7859                    if (mLaunchingProviders.get(i) == cpr) {
7860                        break;
7861                    }
7862                }
7863
7864                // If the provider is not already being launched, then get it
7865                // started.
7866                if (i >= N) {
7867                    final long origId = Binder.clearCallingIdentity();
7868
7869                    try {
7870                        // Content provider is now in use, its package can't be stopped.
7871                        try {
7872                            AppGlobals.getPackageManager().setPackageStoppedState(
7873                                    cpr.appInfo.packageName, false, userId);
7874                        } catch (RemoteException e) {
7875                        } catch (IllegalArgumentException e) {
7876                            Slog.w(TAG, "Failed trying to unstop package "
7877                                    + cpr.appInfo.packageName + ": " + e);
7878                        }
7879
7880                        // Use existing process if already started
7881                        ProcessRecord proc = getProcessRecordLocked(
7882                                cpi.processName, cpr.appInfo.uid, false);
7883                        if (proc != null && proc.thread != null) {
7884                            if (DEBUG_PROVIDER) {
7885                                Slog.d(TAG, "Installing in existing process " + proc);
7886                            }
7887                            proc.pubProviders.put(cpi.name, cpr);
7888                            try {
7889                                proc.thread.scheduleInstallProvider(cpi);
7890                            } catch (RemoteException e) {
7891                            }
7892                        } else {
7893                            proc = startProcessLocked(cpi.processName,
7894                                    cpr.appInfo, false, 0, "content provider",
7895                                    new ComponentName(cpi.applicationInfo.packageName,
7896                                            cpi.name), false, false, false);
7897                            if (proc == null) {
7898                                Slog.w(TAG, "Unable to launch app "
7899                                        + cpi.applicationInfo.packageName + "/"
7900                                        + cpi.applicationInfo.uid + " for provider "
7901                                        + name + ": process is bad");
7902                                return null;
7903                            }
7904                        }
7905                        cpr.launchingApp = proc;
7906                        mLaunchingProviders.add(cpr);
7907                    } finally {
7908                        Binder.restoreCallingIdentity(origId);
7909                    }
7910                }
7911
7912                // Make sure the provider is published (the same provider class
7913                // may be published under multiple names).
7914                if (firstClass) {
7915                    mProviderMap.putProviderByClass(comp, cpr);
7916                }
7917
7918                mProviderMap.putProviderByName(name, cpr);
7919                conn = incProviderCountLocked(r, cpr, token, stable);
7920                if (conn != null) {
7921                    conn.waiting = true;
7922                }
7923            }
7924        }
7925
7926        // Wait for the provider to be published...
7927        synchronized (cpr) {
7928            while (cpr.provider == null) {
7929                if (cpr.launchingApp == null) {
7930                    Slog.w(TAG, "Unable to launch app "
7931                            + cpi.applicationInfo.packageName + "/"
7932                            + cpi.applicationInfo.uid + " for provider "
7933                            + name + ": launching app became null");
7934                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7935                            UserHandle.getUserId(cpi.applicationInfo.uid),
7936                            cpi.applicationInfo.packageName,
7937                            cpi.applicationInfo.uid, name);
7938                    return null;
7939                }
7940                try {
7941                    if (DEBUG_MU) {
7942                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7943                                + cpr.launchingApp);
7944                    }
7945                    if (conn != null) {
7946                        conn.waiting = true;
7947                    }
7948                    cpr.wait();
7949                } catch (InterruptedException ex) {
7950                } finally {
7951                    if (conn != null) {
7952                        conn.waiting = false;
7953                    }
7954                }
7955            }
7956        }
7957        return cpr != null ? cpr.newHolder(conn) : null;
7958    }
7959
7960    public final ContentProviderHolder getContentProvider(
7961            IApplicationThread caller, String name, int userId, boolean stable) {
7962        enforceNotIsolatedCaller("getContentProvider");
7963        if (caller == null) {
7964            String msg = "null IApplicationThread when getting content provider "
7965                    + name;
7966            Slog.w(TAG, msg);
7967            throw new SecurityException(msg);
7968        }
7969
7970        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7971                false, true, "getContentProvider", null);
7972        return getContentProviderImpl(caller, name, null, stable, userId);
7973    }
7974
7975    public ContentProviderHolder getContentProviderExternal(
7976            String name, int userId, IBinder token) {
7977        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7978            "Do not have permission in call getContentProviderExternal()");
7979        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7980                false, true, "getContentProvider", null);
7981        return getContentProviderExternalUnchecked(name, token, userId);
7982    }
7983
7984    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7985            IBinder token, int userId) {
7986        return getContentProviderImpl(null, name, token, true, userId);
7987    }
7988
7989    /**
7990     * Drop a content provider from a ProcessRecord's bookkeeping
7991     */
7992    public void removeContentProvider(IBinder connection, boolean stable) {
7993        enforceNotIsolatedCaller("removeContentProvider");
7994        long ident = Binder.clearCallingIdentity();
7995        try {
7996            synchronized (this) {
7997                ContentProviderConnection conn;
7998                try {
7999                    conn = (ContentProviderConnection)connection;
8000                } catch (ClassCastException e) {
8001                    String msg ="removeContentProvider: " + connection
8002                            + " not a ContentProviderConnection";
8003                    Slog.w(TAG, msg);
8004                    throw new IllegalArgumentException(msg);
8005                }
8006                if (conn == null) {
8007                    throw new NullPointerException("connection is null");
8008                }
8009                if (decProviderCountLocked(conn, null, null, stable)) {
8010                    updateOomAdjLocked();
8011                }
8012            }
8013        } finally {
8014            Binder.restoreCallingIdentity(ident);
8015        }
8016    }
8017
8018    public void removeContentProviderExternal(String name, IBinder token) {
8019        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8020            "Do not have permission in call removeContentProviderExternal()");
8021        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8022    }
8023
8024    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8025        synchronized (this) {
8026            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8027            if(cpr == null) {
8028                //remove from mProvidersByClass
8029                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8030                return;
8031            }
8032
8033            //update content provider record entry info
8034            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8035            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8036            if (localCpr.hasExternalProcessHandles()) {
8037                if (localCpr.removeExternalProcessHandleLocked(token)) {
8038                    updateOomAdjLocked();
8039                } else {
8040                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8041                            + " with no external reference for token: "
8042                            + token + ".");
8043                }
8044            } else {
8045                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8046                        + " with no external references.");
8047            }
8048        }
8049    }
8050
8051    public final void publishContentProviders(IApplicationThread caller,
8052            List<ContentProviderHolder> providers) {
8053        if (providers == null) {
8054            return;
8055        }
8056
8057        enforceNotIsolatedCaller("publishContentProviders");
8058        synchronized (this) {
8059            final ProcessRecord r = getRecordForAppLocked(caller);
8060            if (DEBUG_MU)
8061                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8062            if (r == null) {
8063                throw new SecurityException(
8064                        "Unable to find app for caller " + caller
8065                      + " (pid=" + Binder.getCallingPid()
8066                      + ") when publishing content providers");
8067            }
8068
8069            final long origId = Binder.clearCallingIdentity();
8070
8071            final int N = providers.size();
8072            for (int i=0; i<N; i++) {
8073                ContentProviderHolder src = providers.get(i);
8074                if (src == null || src.info == null || src.provider == null) {
8075                    continue;
8076                }
8077                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8078                if (DEBUG_MU)
8079                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8080                if (dst != null) {
8081                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8082                    mProviderMap.putProviderByClass(comp, dst);
8083                    String names[] = dst.info.authority.split(";");
8084                    for (int j = 0; j < names.length; j++) {
8085                        mProviderMap.putProviderByName(names[j], dst);
8086                    }
8087
8088                    int NL = mLaunchingProviders.size();
8089                    int j;
8090                    for (j=0; j<NL; j++) {
8091                        if (mLaunchingProviders.get(j) == dst) {
8092                            mLaunchingProviders.remove(j);
8093                            j--;
8094                            NL--;
8095                        }
8096                    }
8097                    synchronized (dst) {
8098                        dst.provider = src.provider;
8099                        dst.proc = r;
8100                        dst.notifyAll();
8101                    }
8102                    updateOomAdjLocked(r);
8103                }
8104            }
8105
8106            Binder.restoreCallingIdentity(origId);
8107        }
8108    }
8109
8110    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8111        ContentProviderConnection conn;
8112        try {
8113            conn = (ContentProviderConnection)connection;
8114        } catch (ClassCastException e) {
8115            String msg ="refContentProvider: " + connection
8116                    + " not a ContentProviderConnection";
8117            Slog.w(TAG, msg);
8118            throw new IllegalArgumentException(msg);
8119        }
8120        if (conn == null) {
8121            throw new NullPointerException("connection is null");
8122        }
8123
8124        synchronized (this) {
8125            if (stable > 0) {
8126                conn.numStableIncs += stable;
8127            }
8128            stable = conn.stableCount + stable;
8129            if (stable < 0) {
8130                throw new IllegalStateException("stableCount < 0: " + stable);
8131            }
8132
8133            if (unstable > 0) {
8134                conn.numUnstableIncs += unstable;
8135            }
8136            unstable = conn.unstableCount + unstable;
8137            if (unstable < 0) {
8138                throw new IllegalStateException("unstableCount < 0: " + unstable);
8139            }
8140
8141            if ((stable+unstable) <= 0) {
8142                throw new IllegalStateException("ref counts can't go to zero here: stable="
8143                        + stable + " unstable=" + unstable);
8144            }
8145            conn.stableCount = stable;
8146            conn.unstableCount = unstable;
8147            return !conn.dead;
8148        }
8149    }
8150
8151    public void unstableProviderDied(IBinder connection) {
8152        ContentProviderConnection conn;
8153        try {
8154            conn = (ContentProviderConnection)connection;
8155        } catch (ClassCastException e) {
8156            String msg ="refContentProvider: " + connection
8157                    + " not a ContentProviderConnection";
8158            Slog.w(TAG, msg);
8159            throw new IllegalArgumentException(msg);
8160        }
8161        if (conn == null) {
8162            throw new NullPointerException("connection is null");
8163        }
8164
8165        // Safely retrieve the content provider associated with the connection.
8166        IContentProvider provider;
8167        synchronized (this) {
8168            provider = conn.provider.provider;
8169        }
8170
8171        if (provider == null) {
8172            // Um, yeah, we're way ahead of you.
8173            return;
8174        }
8175
8176        // Make sure the caller is being honest with us.
8177        if (provider.asBinder().pingBinder()) {
8178            // Er, no, still looks good to us.
8179            synchronized (this) {
8180                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8181                        + " says " + conn + " died, but we don't agree");
8182                return;
8183            }
8184        }
8185
8186        // Well look at that!  It's dead!
8187        synchronized (this) {
8188            if (conn.provider.provider != provider) {
8189                // But something changed...  good enough.
8190                return;
8191            }
8192
8193            ProcessRecord proc = conn.provider.proc;
8194            if (proc == null || proc.thread == null) {
8195                // Seems like the process is already cleaned up.
8196                return;
8197            }
8198
8199            // As far as we're concerned, this is just like receiving a
8200            // death notification...  just a bit prematurely.
8201            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8202                    + ") early provider death");
8203            final long ident = Binder.clearCallingIdentity();
8204            try {
8205                appDiedLocked(proc, proc.pid, proc.thread);
8206            } finally {
8207                Binder.restoreCallingIdentity(ident);
8208            }
8209        }
8210    }
8211
8212    @Override
8213    public void appNotRespondingViaProvider(IBinder connection) {
8214        enforceCallingPermission(
8215                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8216
8217        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8218        if (conn == null) {
8219            Slog.w(TAG, "ContentProviderConnection is null");
8220            return;
8221        }
8222
8223        final ProcessRecord host = conn.provider.proc;
8224        if (host == null) {
8225            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8226            return;
8227        }
8228
8229        final long token = Binder.clearCallingIdentity();
8230        try {
8231            appNotResponding(host, null, null, false, "ContentProvider not responding");
8232        } finally {
8233            Binder.restoreCallingIdentity(token);
8234        }
8235    }
8236
8237    public final void installSystemProviders() {
8238        List<ProviderInfo> providers;
8239        synchronized (this) {
8240            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8241            providers = generateApplicationProvidersLocked(app);
8242            if (providers != null) {
8243                for (int i=providers.size()-1; i>=0; i--) {
8244                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8245                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8246                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8247                                + ": not system .apk");
8248                        providers.remove(i);
8249                    }
8250                }
8251            }
8252        }
8253        if (providers != null) {
8254            mSystemThread.installSystemProviders(providers);
8255        }
8256
8257        mCoreSettingsObserver = new CoreSettingsObserver(this);
8258
8259        mUsageStatsService.monitorPackages();
8260    }
8261
8262    /**
8263     * Allows app to retrieve the MIME type of a URI without having permission
8264     * to access its content provider.
8265     *
8266     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8267     *
8268     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8269     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8270     */
8271    public String getProviderMimeType(Uri uri, int userId) {
8272        enforceNotIsolatedCaller("getProviderMimeType");
8273        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8274                userId, false, true, "getProviderMimeType", null);
8275        final String name = uri.getAuthority();
8276        final long ident = Binder.clearCallingIdentity();
8277        ContentProviderHolder holder = null;
8278
8279        try {
8280            holder = getContentProviderExternalUnchecked(name, null, userId);
8281            if (holder != null) {
8282                return holder.provider.getType(uri);
8283            }
8284        } catch (RemoteException e) {
8285            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8286            return null;
8287        } finally {
8288            if (holder != null) {
8289                removeContentProviderExternalUnchecked(name, null, userId);
8290            }
8291            Binder.restoreCallingIdentity(ident);
8292        }
8293
8294        return null;
8295    }
8296
8297    // =========================================================
8298    // GLOBAL MANAGEMENT
8299    // =========================================================
8300
8301    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8302            boolean isolated) {
8303        String proc = customProcess != null ? customProcess : info.processName;
8304        BatteryStatsImpl.Uid.Proc ps = null;
8305        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8306        int uid = info.uid;
8307        if (isolated) {
8308            int userId = UserHandle.getUserId(uid);
8309            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8310            while (true) {
8311                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8312                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8313                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8314                }
8315                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8316                mNextIsolatedProcessUid++;
8317                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8318                    // No process for this uid, use it.
8319                    break;
8320                }
8321                stepsLeft--;
8322                if (stepsLeft <= 0) {
8323                    return null;
8324                }
8325            }
8326        }
8327        return new ProcessRecord(stats, info, proc, uid);
8328    }
8329
8330    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8331        ProcessRecord app;
8332        if (!isolated) {
8333            app = getProcessRecordLocked(info.processName, info.uid, true);
8334        } else {
8335            app = null;
8336        }
8337
8338        if (app == null) {
8339            app = newProcessRecordLocked(info, null, isolated);
8340            mProcessNames.put(info.processName, app.uid, app);
8341            if (isolated) {
8342                mIsolatedProcesses.put(app.uid, app);
8343            }
8344            updateLruProcessLocked(app, false, null);
8345            updateOomAdjLocked();
8346        }
8347
8348        // This package really, really can not be stopped.
8349        try {
8350            AppGlobals.getPackageManager().setPackageStoppedState(
8351                    info.packageName, false, UserHandle.getUserId(app.uid));
8352        } catch (RemoteException e) {
8353        } catch (IllegalArgumentException e) {
8354            Slog.w(TAG, "Failed trying to unstop package "
8355                    + info.packageName + ": " + e);
8356        }
8357
8358        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8359                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8360            app.persistent = true;
8361            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8362        }
8363        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8364            mPersistentStartingProcesses.add(app);
8365            startProcessLocked(app, "added application", app.processName);
8366        }
8367
8368        return app;
8369    }
8370
8371    public void unhandledBack() {
8372        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8373                "unhandledBack()");
8374
8375        synchronized(this) {
8376            final long origId = Binder.clearCallingIdentity();
8377            try {
8378                getFocusedStack().unhandledBackLocked();
8379            } finally {
8380                Binder.restoreCallingIdentity(origId);
8381            }
8382        }
8383    }
8384
8385    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8386        enforceNotIsolatedCaller("openContentUri");
8387        final int userId = UserHandle.getCallingUserId();
8388        String name = uri.getAuthority();
8389        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8390        ParcelFileDescriptor pfd = null;
8391        if (cph != null) {
8392            // We record the binder invoker's uid in thread-local storage before
8393            // going to the content provider to open the file.  Later, in the code
8394            // that handles all permissions checks, we look for this uid and use
8395            // that rather than the Activity Manager's own uid.  The effect is that
8396            // we do the check against the caller's permissions even though it looks
8397            // to the content provider like the Activity Manager itself is making
8398            // the request.
8399            sCallerIdentity.set(new Identity(
8400                    Binder.getCallingPid(), Binder.getCallingUid()));
8401            try {
8402                pfd = cph.provider.openFile(null, uri, "r", null);
8403            } catch (FileNotFoundException e) {
8404                // do nothing; pfd will be returned null
8405            } finally {
8406                // Ensure that whatever happens, we clean up the identity state
8407                sCallerIdentity.remove();
8408            }
8409
8410            // We've got the fd now, so we're done with the provider.
8411            removeContentProviderExternalUnchecked(name, null, userId);
8412        } else {
8413            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8414        }
8415        return pfd;
8416    }
8417
8418    // Actually is sleeping or shutting down or whatever else in the future
8419    // is an inactive state.
8420    public boolean isSleepingOrShuttingDown() {
8421        return mSleeping || mShuttingDown;
8422    }
8423
8424    public void goingToSleep() {
8425        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8426                != PackageManager.PERMISSION_GRANTED) {
8427            throw new SecurityException("Requires permission "
8428                    + android.Manifest.permission.DEVICE_POWER);
8429        }
8430
8431        synchronized(this) {
8432            mWentToSleep = true;
8433            updateEventDispatchingLocked();
8434
8435            if (!mSleeping) {
8436                mSleeping = true;
8437                mStackSupervisor.goingToSleepLocked();
8438
8439                // Initialize the wake times of all processes.
8440                checkExcessivePowerUsageLocked(false);
8441                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8442                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8443                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8444            }
8445        }
8446    }
8447
8448    @Override
8449    public boolean shutdown(int timeout) {
8450        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8451                != PackageManager.PERMISSION_GRANTED) {
8452            throw new SecurityException("Requires permission "
8453                    + android.Manifest.permission.SHUTDOWN);
8454        }
8455
8456        boolean timedout = false;
8457
8458        synchronized(this) {
8459            mShuttingDown = true;
8460            updateEventDispatchingLocked();
8461            timedout = mStackSupervisor.shutdownLocked(timeout);
8462        }
8463
8464        mAppOpsService.shutdown();
8465        mUsageStatsService.shutdown();
8466        mBatteryStatsService.shutdown();
8467        synchronized (this) {
8468            mProcessStats.shutdownLocked();
8469        }
8470
8471        return timedout;
8472    }
8473
8474    public final void activitySlept(IBinder token) {
8475        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8476
8477        final long origId = Binder.clearCallingIdentity();
8478
8479        synchronized (this) {
8480            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8481            if (r != null) {
8482                mStackSupervisor.activitySleptLocked(r);
8483            }
8484        }
8485
8486        Binder.restoreCallingIdentity(origId);
8487    }
8488
8489    void logLockScreen(String msg) {
8490        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8491                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8492                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8493                mStackSupervisor.mDismissKeyguardOnNextActivity);
8494    }
8495
8496    private void comeOutOfSleepIfNeededLocked() {
8497        if (!mWentToSleep && !mLockScreenShown) {
8498            if (mSleeping) {
8499                mSleeping = false;
8500                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8501            }
8502        }
8503    }
8504
8505    public void wakingUp() {
8506        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8507                != PackageManager.PERMISSION_GRANTED) {
8508            throw new SecurityException("Requires permission "
8509                    + android.Manifest.permission.DEVICE_POWER);
8510        }
8511
8512        synchronized(this) {
8513            mWentToSleep = false;
8514            updateEventDispatchingLocked();
8515            comeOutOfSleepIfNeededLocked();
8516        }
8517    }
8518
8519    private void updateEventDispatchingLocked() {
8520        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8521    }
8522
8523    public void setLockScreenShown(boolean shown) {
8524        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8525                != PackageManager.PERMISSION_GRANTED) {
8526            throw new SecurityException("Requires permission "
8527                    + android.Manifest.permission.DEVICE_POWER);
8528        }
8529
8530        synchronized(this) {
8531            long ident = Binder.clearCallingIdentity();
8532            try {
8533                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8534                mLockScreenShown = shown;
8535                comeOutOfSleepIfNeededLocked();
8536            } finally {
8537                Binder.restoreCallingIdentity(ident);
8538            }
8539        }
8540    }
8541
8542    public void stopAppSwitches() {
8543        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8544                != PackageManager.PERMISSION_GRANTED) {
8545            throw new SecurityException("Requires permission "
8546                    + android.Manifest.permission.STOP_APP_SWITCHES);
8547        }
8548
8549        synchronized(this) {
8550            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8551                    + APP_SWITCH_DELAY_TIME;
8552            mDidAppSwitch = false;
8553            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8554            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8555            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8556        }
8557    }
8558
8559    public void resumeAppSwitches() {
8560        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8561                != PackageManager.PERMISSION_GRANTED) {
8562            throw new SecurityException("Requires permission "
8563                    + android.Manifest.permission.STOP_APP_SWITCHES);
8564        }
8565
8566        synchronized(this) {
8567            // Note that we don't execute any pending app switches... we will
8568            // let those wait until either the timeout, or the next start
8569            // activity request.
8570            mAppSwitchesAllowedTime = 0;
8571        }
8572    }
8573
8574    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8575            String name) {
8576        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8577            return true;
8578        }
8579
8580        final int perm = checkComponentPermission(
8581                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8582                callingUid, -1, true);
8583        if (perm == PackageManager.PERMISSION_GRANTED) {
8584            return true;
8585        }
8586
8587        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8588        return false;
8589    }
8590
8591    public void setDebugApp(String packageName, boolean waitForDebugger,
8592            boolean persistent) {
8593        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8594                "setDebugApp()");
8595
8596        long ident = Binder.clearCallingIdentity();
8597        try {
8598            // Note that this is not really thread safe if there are multiple
8599            // callers into it at the same time, but that's not a situation we
8600            // care about.
8601            if (persistent) {
8602                final ContentResolver resolver = mContext.getContentResolver();
8603                Settings.Global.putString(
8604                    resolver, Settings.Global.DEBUG_APP,
8605                    packageName);
8606                Settings.Global.putInt(
8607                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8608                    waitForDebugger ? 1 : 0);
8609            }
8610
8611            synchronized (this) {
8612                if (!persistent) {
8613                    mOrigDebugApp = mDebugApp;
8614                    mOrigWaitForDebugger = mWaitForDebugger;
8615                }
8616                mDebugApp = packageName;
8617                mWaitForDebugger = waitForDebugger;
8618                mDebugTransient = !persistent;
8619                if (packageName != null) {
8620                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8621                            false, UserHandle.USER_ALL, "set debug app");
8622                }
8623            }
8624        } finally {
8625            Binder.restoreCallingIdentity(ident);
8626        }
8627    }
8628
8629    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8630        synchronized (this) {
8631            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8632            if (!isDebuggable) {
8633                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8634                    throw new SecurityException("Process not debuggable: " + app.packageName);
8635                }
8636            }
8637
8638            mOpenGlTraceApp = processName;
8639        }
8640    }
8641
8642    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8643            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8644        synchronized (this) {
8645            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8646            if (!isDebuggable) {
8647                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8648                    throw new SecurityException("Process not debuggable: " + app.packageName);
8649                }
8650            }
8651            mProfileApp = processName;
8652            mProfileFile = profileFile;
8653            if (mProfileFd != null) {
8654                try {
8655                    mProfileFd.close();
8656                } catch (IOException e) {
8657                }
8658                mProfileFd = null;
8659            }
8660            mProfileFd = profileFd;
8661            mProfileType = 0;
8662            mAutoStopProfiler = autoStopProfiler;
8663        }
8664    }
8665
8666    @Override
8667    public void setAlwaysFinish(boolean enabled) {
8668        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8669                "setAlwaysFinish()");
8670
8671        Settings.Global.putInt(
8672                mContext.getContentResolver(),
8673                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8674
8675        synchronized (this) {
8676            mAlwaysFinishActivities = enabled;
8677        }
8678    }
8679
8680    @Override
8681    public void setActivityController(IActivityController controller) {
8682        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8683                "setActivityController()");
8684        synchronized (this) {
8685            mController = controller;
8686            Watchdog.getInstance().setActivityController(controller);
8687        }
8688    }
8689
8690    @Override
8691    public void setUserIsMonkey(boolean userIsMonkey) {
8692        synchronized (this) {
8693            synchronized (mPidsSelfLocked) {
8694                final int callingPid = Binder.getCallingPid();
8695                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8696                if (precessRecord == null) {
8697                    throw new SecurityException("Unknown process: " + callingPid);
8698                }
8699                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8700                    throw new SecurityException("Only an instrumentation process "
8701                            + "with a UiAutomation can call setUserIsMonkey");
8702                }
8703            }
8704            mUserIsMonkey = userIsMonkey;
8705        }
8706    }
8707
8708    @Override
8709    public boolean isUserAMonkey() {
8710        synchronized (this) {
8711            // If there is a controller also implies the user is a monkey.
8712            return (mUserIsMonkey || mController != null);
8713        }
8714    }
8715
8716    public void requestBugReport() {
8717        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8718        SystemProperties.set("ctl.start", "bugreport");
8719    }
8720
8721    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8722        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8723    }
8724
8725    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8726        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8727            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8728        }
8729        return KEY_DISPATCHING_TIMEOUT;
8730    }
8731
8732    @Override
8733    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8734        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8735                != PackageManager.PERMISSION_GRANTED) {
8736            throw new SecurityException("Requires permission "
8737                    + android.Manifest.permission.FILTER_EVENTS);
8738        }
8739        ProcessRecord proc;
8740        long timeout;
8741        synchronized (this) {
8742            synchronized (mPidsSelfLocked) {
8743                proc = mPidsSelfLocked.get(pid);
8744            }
8745            timeout = getInputDispatchingTimeoutLocked(proc);
8746        }
8747
8748        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8749            return -1;
8750        }
8751
8752        return timeout;
8753    }
8754
8755    /**
8756     * Handle input dispatching timeouts.
8757     * Returns whether input dispatching should be aborted or not.
8758     */
8759    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8760            final ActivityRecord activity, final ActivityRecord parent,
8761            final boolean aboveSystem, String reason) {
8762        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8763                != PackageManager.PERMISSION_GRANTED) {
8764            throw new SecurityException("Requires permission "
8765                    + android.Manifest.permission.FILTER_EVENTS);
8766        }
8767
8768        final String annotation;
8769        if (reason == null) {
8770            annotation = "Input dispatching timed out";
8771        } else {
8772            annotation = "Input dispatching timed out (" + reason + ")";
8773        }
8774
8775        if (proc != null) {
8776            synchronized (this) {
8777                if (proc.debugging) {
8778                    return false;
8779                }
8780
8781                if (mDidDexOpt) {
8782                    // Give more time since we were dexopting.
8783                    mDidDexOpt = false;
8784                    return false;
8785                }
8786
8787                if (proc.instrumentationClass != null) {
8788                    Bundle info = new Bundle();
8789                    info.putString("shortMsg", "keyDispatchingTimedOut");
8790                    info.putString("longMsg", annotation);
8791                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8792                    return true;
8793                }
8794            }
8795            mHandler.post(new Runnable() {
8796                @Override
8797                public void run() {
8798                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8799                }
8800            });
8801        }
8802
8803        return true;
8804    }
8805
8806    public Bundle getAssistContextExtras(int requestType) {
8807        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8808                "getAssistContextExtras()");
8809        PendingAssistExtras pae;
8810        Bundle extras = new Bundle();
8811        synchronized (this) {
8812            ActivityRecord activity = getFocusedStack().mResumedActivity;
8813            if (activity == null) {
8814                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8815                return null;
8816            }
8817            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8818            if (activity.app == null || activity.app.thread == null) {
8819                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8820                return extras;
8821            }
8822            if (activity.app.pid == Binder.getCallingPid()) {
8823                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8824                return extras;
8825            }
8826            pae = new PendingAssistExtras(activity);
8827            try {
8828                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8829                        requestType);
8830                mPendingAssistExtras.add(pae);
8831                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8832            } catch (RemoteException e) {
8833                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8834                return extras;
8835            }
8836        }
8837        synchronized (pae) {
8838            while (!pae.haveResult) {
8839                try {
8840                    pae.wait();
8841                } catch (InterruptedException e) {
8842                }
8843            }
8844            if (pae.result != null) {
8845                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8846            }
8847        }
8848        synchronized (this) {
8849            mPendingAssistExtras.remove(pae);
8850            mHandler.removeCallbacks(pae);
8851        }
8852        return extras;
8853    }
8854
8855    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8856        PendingAssistExtras pae = (PendingAssistExtras)token;
8857        synchronized (pae) {
8858            pae.result = extras;
8859            pae.haveResult = true;
8860            pae.notifyAll();
8861        }
8862    }
8863
8864    public void registerProcessObserver(IProcessObserver observer) {
8865        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8866                "registerProcessObserver()");
8867        synchronized (this) {
8868            mProcessObservers.register(observer);
8869        }
8870    }
8871
8872    @Override
8873    public void unregisterProcessObserver(IProcessObserver observer) {
8874        synchronized (this) {
8875            mProcessObservers.unregister(observer);
8876        }
8877    }
8878
8879    @Override
8880    public boolean convertFromTranslucent(IBinder token) {
8881        final long origId = Binder.clearCallingIdentity();
8882        try {
8883            synchronized (this) {
8884                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8885                if (r == null) {
8886                    return false;
8887                }
8888                if (r.changeWindowTranslucency(true)) {
8889                    mWindowManager.setAppFullscreen(token, true);
8890                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8891                    return true;
8892                }
8893                return false;
8894            }
8895        } finally {
8896            Binder.restoreCallingIdentity(origId);
8897        }
8898    }
8899
8900    @Override
8901    public boolean convertToTranslucent(IBinder token) {
8902        final long origId = Binder.clearCallingIdentity();
8903        try {
8904            synchronized (this) {
8905                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8906                if (r == null) {
8907                    return false;
8908                }
8909                if (r.changeWindowTranslucency(false)) {
8910                    r.task.stack.convertToTranslucent(r);
8911                    mWindowManager.setAppFullscreen(token, false);
8912                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8913                    return true;
8914                }
8915                return false;
8916            }
8917        } finally {
8918            Binder.restoreCallingIdentity(origId);
8919        }
8920    }
8921
8922    @Override
8923    public void setImmersive(IBinder token, boolean immersive) {
8924        synchronized(this) {
8925            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8926            if (r == null) {
8927                throw new IllegalArgumentException();
8928            }
8929            r.immersive = immersive;
8930
8931            // update associated state if we're frontmost
8932            if (r == mFocusedActivity) {
8933                if (DEBUG_IMMERSIVE) {
8934                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8935                }
8936                applyUpdateLockStateLocked(r);
8937            }
8938        }
8939    }
8940
8941    @Override
8942    public boolean isImmersive(IBinder token) {
8943        synchronized (this) {
8944            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8945            if (r == null) {
8946                throw new IllegalArgumentException();
8947            }
8948            return r.immersive;
8949        }
8950    }
8951
8952    public boolean isTopActivityImmersive() {
8953        enforceNotIsolatedCaller("startActivity");
8954        synchronized (this) {
8955            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8956            return (r != null) ? r.immersive : false;
8957        }
8958    }
8959
8960    public final void enterSafeMode() {
8961        synchronized(this) {
8962            // It only makes sense to do this before the system is ready
8963            // and started launching other packages.
8964            if (!mSystemReady) {
8965                try {
8966                    AppGlobals.getPackageManager().enterSafeMode();
8967                } catch (RemoteException e) {
8968                }
8969            }
8970
8971            mSafeMode = true;
8972        }
8973    }
8974
8975    public final void showSafeModeOverlay() {
8976        View v = LayoutInflater.from(mContext).inflate(
8977                com.android.internal.R.layout.safe_mode, null);
8978        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8979        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8980        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8981        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8982        lp.gravity = Gravity.BOTTOM | Gravity.START;
8983        lp.format = v.getBackground().getOpacity();
8984        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8985                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8986        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8987        ((WindowManager)mContext.getSystemService(
8988                Context.WINDOW_SERVICE)).addView(v, lp);
8989    }
8990
8991    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8992        if (!(sender instanceof PendingIntentRecord)) {
8993            return;
8994        }
8995        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8996        synchronized (stats) {
8997            if (mBatteryStatsService.isOnBattery()) {
8998                mBatteryStatsService.enforceCallingPermission();
8999                PendingIntentRecord rec = (PendingIntentRecord)sender;
9000                int MY_UID = Binder.getCallingUid();
9001                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9002                BatteryStatsImpl.Uid.Pkg pkg =
9003                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9004                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9005                pkg.incWakeupsLocked();
9006            }
9007        }
9008    }
9009
9010    public boolean killPids(int[] pids, String pReason, boolean secure) {
9011        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9012            throw new SecurityException("killPids only available to the system");
9013        }
9014        String reason = (pReason == null) ? "Unknown" : pReason;
9015        // XXX Note: don't acquire main activity lock here, because the window
9016        // manager calls in with its locks held.
9017
9018        boolean killed = false;
9019        synchronized (mPidsSelfLocked) {
9020            int[] types = new int[pids.length];
9021            int worstType = 0;
9022            for (int i=0; i<pids.length; i++) {
9023                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9024                if (proc != null) {
9025                    int type = proc.setAdj;
9026                    types[i] = type;
9027                    if (type > worstType) {
9028                        worstType = type;
9029                    }
9030                }
9031            }
9032
9033            // If the worst oom_adj is somewhere in the cached proc LRU range,
9034            // then constrain it so we will kill all cached procs.
9035            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9036                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9037                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9038            }
9039
9040            // If this is not a secure call, don't let it kill processes that
9041            // are important.
9042            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9043                worstType = ProcessList.SERVICE_ADJ;
9044            }
9045
9046            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9047            for (int i=0; i<pids.length; i++) {
9048                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9049                if (proc == null) {
9050                    continue;
9051                }
9052                int adj = proc.setAdj;
9053                if (adj >= worstType && !proc.killedByAm) {
9054                    killUnneededProcessLocked(proc, reason);
9055                    killed = true;
9056                }
9057            }
9058        }
9059        return killed;
9060    }
9061
9062    @Override
9063    public void killUid(int uid, String reason) {
9064        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9065            throw new SecurityException("killUid only available to the system");
9066        }
9067        synchronized (this) {
9068            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9069                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9070                    reason != null ? reason : "kill uid");
9071        }
9072    }
9073
9074    @Override
9075    public boolean killProcessesBelowForeground(String reason) {
9076        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9077            throw new SecurityException("killProcessesBelowForeground() only available to system");
9078        }
9079
9080        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9081    }
9082
9083    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9084        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9085            throw new SecurityException("killProcessesBelowAdj() only available to system");
9086        }
9087
9088        boolean killed = false;
9089        synchronized (mPidsSelfLocked) {
9090            final int size = mPidsSelfLocked.size();
9091            for (int i = 0; i < size; i++) {
9092                final int pid = mPidsSelfLocked.keyAt(i);
9093                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9094                if (proc == null) continue;
9095
9096                final int adj = proc.setAdj;
9097                if (adj > belowAdj && !proc.killedByAm) {
9098                    killUnneededProcessLocked(proc, reason);
9099                    killed = true;
9100                }
9101            }
9102        }
9103        return killed;
9104    }
9105
9106    @Override
9107    public void hang(final IBinder who, boolean allowRestart) {
9108        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9109                != PackageManager.PERMISSION_GRANTED) {
9110            throw new SecurityException("Requires permission "
9111                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9112        }
9113
9114        final IBinder.DeathRecipient death = new DeathRecipient() {
9115            @Override
9116            public void binderDied() {
9117                synchronized (this) {
9118                    notifyAll();
9119                }
9120            }
9121        };
9122
9123        try {
9124            who.linkToDeath(death, 0);
9125        } catch (RemoteException e) {
9126            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9127            return;
9128        }
9129
9130        synchronized (this) {
9131            Watchdog.getInstance().setAllowRestart(allowRestart);
9132            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9133            synchronized (death) {
9134                while (who.isBinderAlive()) {
9135                    try {
9136                        death.wait();
9137                    } catch (InterruptedException e) {
9138                    }
9139                }
9140            }
9141            Watchdog.getInstance().setAllowRestart(true);
9142        }
9143    }
9144
9145    @Override
9146    public void restart() {
9147        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9148                != PackageManager.PERMISSION_GRANTED) {
9149            throw new SecurityException("Requires permission "
9150                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9151        }
9152
9153        Log.i(TAG, "Sending shutdown broadcast...");
9154
9155        BroadcastReceiver br = new BroadcastReceiver() {
9156            @Override public void onReceive(Context context, Intent intent) {
9157                // Now the broadcast is done, finish up the low-level shutdown.
9158                Log.i(TAG, "Shutting down activity manager...");
9159                shutdown(10000);
9160                Log.i(TAG, "Shutdown complete, restarting!");
9161                Process.killProcess(Process.myPid());
9162                System.exit(10);
9163            }
9164        };
9165
9166        // First send the high-level shut down broadcast.
9167        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9168        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9169        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9170        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9171        mContext.sendOrderedBroadcastAsUser(intent,
9172                UserHandle.ALL, null, br, mHandler, 0, null, null);
9173        */
9174        br.onReceive(mContext, intent);
9175    }
9176
9177    private long getLowRamTimeSinceIdle(long now) {
9178        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9179    }
9180
9181    @Override
9182    public void performIdleMaintenance() {
9183        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9184                != PackageManager.PERMISSION_GRANTED) {
9185            throw new SecurityException("Requires permission "
9186                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9187        }
9188
9189        synchronized (this) {
9190            final long now = SystemClock.uptimeMillis();
9191            final long timeSinceLastIdle = now - mLastIdleTime;
9192            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9193            mLastIdleTime = now;
9194            mLowRamTimeSinceLastIdle = 0;
9195            if (mLowRamStartTime != 0) {
9196                mLowRamStartTime = now;
9197            }
9198
9199            StringBuilder sb = new StringBuilder(128);
9200            sb.append("Idle maintenance over ");
9201            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9202            sb.append(" low RAM for ");
9203            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9204            Slog.i(TAG, sb.toString());
9205
9206            // If at least 1/3 of our time since the last idle period has been spent
9207            // with RAM low, then we want to kill processes.
9208            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9209
9210            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9211                ProcessRecord proc = mLruProcesses.get(i);
9212                if (proc.notCachedSinceIdle) {
9213                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9214                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9215                        if (doKilling && proc.initialIdlePss != 0
9216                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9217                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9218                                    + " from " + proc.initialIdlePss + ")");
9219                        }
9220                    }
9221                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9222                    proc.notCachedSinceIdle = true;
9223                    proc.initialIdlePss = 0;
9224                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9225                            mSleeping, now);
9226                }
9227            }
9228
9229            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9230            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9231        }
9232    }
9233
9234    public final void startRunning(String pkg, String cls, String action,
9235            String data) {
9236        synchronized(this) {
9237            if (mStartRunning) {
9238                return;
9239            }
9240            mStartRunning = true;
9241            mTopComponent = pkg != null && cls != null
9242                    ? new ComponentName(pkg, cls) : null;
9243            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9244            mTopData = data;
9245            if (!mSystemReady) {
9246                return;
9247            }
9248        }
9249
9250        systemReady(null);
9251    }
9252
9253    private void retrieveSettings() {
9254        final ContentResolver resolver = mContext.getContentResolver();
9255        String debugApp = Settings.Global.getString(
9256            resolver, Settings.Global.DEBUG_APP);
9257        boolean waitForDebugger = Settings.Global.getInt(
9258            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9259        boolean alwaysFinishActivities = Settings.Global.getInt(
9260            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9261        boolean forceRtl = Settings.Global.getInt(
9262                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9263        // Transfer any global setting for forcing RTL layout, into a System Property
9264        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9265
9266        Configuration configuration = new Configuration();
9267        Settings.System.getConfiguration(resolver, configuration);
9268        if (forceRtl) {
9269            // This will take care of setting the correct layout direction flags
9270            configuration.setLayoutDirection(configuration.locale);
9271        }
9272
9273        synchronized (this) {
9274            mDebugApp = mOrigDebugApp = debugApp;
9275            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9276            mAlwaysFinishActivities = alwaysFinishActivities;
9277            // This happens before any activities are started, so we can
9278            // change mConfiguration in-place.
9279            updateConfigurationLocked(configuration, null, false, true);
9280            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9281        }
9282    }
9283
9284    public boolean testIsSystemReady() {
9285        // no need to synchronize(this) just to read & return the value
9286        return mSystemReady;
9287    }
9288
9289    private static File getCalledPreBootReceiversFile() {
9290        File dataDir = Environment.getDataDirectory();
9291        File systemDir = new File(dataDir, "system");
9292        File fname = new File(systemDir, "called_pre_boots.dat");
9293        return fname;
9294    }
9295
9296    static final int LAST_DONE_VERSION = 10000;
9297
9298    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9299        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9300        File file = getCalledPreBootReceiversFile();
9301        FileInputStream fis = null;
9302        try {
9303            fis = new FileInputStream(file);
9304            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9305            int fvers = dis.readInt();
9306            if (fvers == LAST_DONE_VERSION) {
9307                String vers = dis.readUTF();
9308                String codename = dis.readUTF();
9309                String build = dis.readUTF();
9310                if (android.os.Build.VERSION.RELEASE.equals(vers)
9311                        && android.os.Build.VERSION.CODENAME.equals(codename)
9312                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9313                    int num = dis.readInt();
9314                    while (num > 0) {
9315                        num--;
9316                        String pkg = dis.readUTF();
9317                        String cls = dis.readUTF();
9318                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9319                    }
9320                }
9321            }
9322        } catch (FileNotFoundException e) {
9323        } catch (IOException e) {
9324            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9325        } finally {
9326            if (fis != null) {
9327                try {
9328                    fis.close();
9329                } catch (IOException e) {
9330                }
9331            }
9332        }
9333        return lastDoneReceivers;
9334    }
9335
9336    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9337        File file = getCalledPreBootReceiversFile();
9338        FileOutputStream fos = null;
9339        DataOutputStream dos = null;
9340        try {
9341            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9342            fos = new FileOutputStream(file);
9343            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9344            dos.writeInt(LAST_DONE_VERSION);
9345            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9346            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9347            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9348            dos.writeInt(list.size());
9349            for (int i=0; i<list.size(); i++) {
9350                dos.writeUTF(list.get(i).getPackageName());
9351                dos.writeUTF(list.get(i).getClassName());
9352            }
9353        } catch (IOException e) {
9354            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9355            file.delete();
9356        } finally {
9357            FileUtils.sync(fos);
9358            if (dos != null) {
9359                try {
9360                    dos.close();
9361                } catch (IOException e) {
9362                    // TODO Auto-generated catch block
9363                    e.printStackTrace();
9364                }
9365            }
9366        }
9367    }
9368
9369    public void systemReady(final Runnable goingCallback) {
9370        synchronized(this) {
9371            if (mSystemReady) {
9372                if (goingCallback != null) goingCallback.run();
9373                return;
9374            }
9375
9376            // Check to see if there are any update receivers to run.
9377            if (!mDidUpdate) {
9378                if (mWaitingUpdate) {
9379                    return;
9380                }
9381                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9382                List<ResolveInfo> ris = null;
9383                try {
9384                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9385                            intent, null, 0, 0);
9386                } catch (RemoteException e) {
9387                }
9388                if (ris != null) {
9389                    for (int i=ris.size()-1; i>=0; i--) {
9390                        if ((ris.get(i).activityInfo.applicationInfo.flags
9391                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9392                            ris.remove(i);
9393                        }
9394                    }
9395                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9396
9397                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9398
9399                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9400                    for (int i=0; i<ris.size(); i++) {
9401                        ActivityInfo ai = ris.get(i).activityInfo;
9402                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9403                        if (lastDoneReceivers.contains(comp)) {
9404                            // We already did the pre boot receiver for this app with the current
9405                            // platform version, so don't do it again...
9406                            ris.remove(i);
9407                            i--;
9408                            // ...however, do keep it as one that has been done, so we don't
9409                            // forget about it when rewriting the file of last done receivers.
9410                            doneReceivers.add(comp);
9411                        }
9412                    }
9413
9414                    final int[] users = getUsersLocked();
9415                    for (int i=0; i<ris.size(); i++) {
9416                        ActivityInfo ai = ris.get(i).activityInfo;
9417                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9418                        doneReceivers.add(comp);
9419                        intent.setComponent(comp);
9420                        for (int j=0; j<users.length; j++) {
9421                            IIntentReceiver finisher = null;
9422                            if (i == ris.size()-1 && j == users.length-1) {
9423                                finisher = new IIntentReceiver.Stub() {
9424                                    public void performReceive(Intent intent, int resultCode,
9425                                            String data, Bundle extras, boolean ordered,
9426                                            boolean sticky, int sendingUser) {
9427                                        // The raw IIntentReceiver interface is called
9428                                        // with the AM lock held, so redispatch to
9429                                        // execute our code without the lock.
9430                                        mHandler.post(new Runnable() {
9431                                            public void run() {
9432                                                synchronized (ActivityManagerService.this) {
9433                                                    mDidUpdate = true;
9434                                                }
9435                                                writeLastDonePreBootReceivers(doneReceivers);
9436                                                showBootMessage(mContext.getText(
9437                                                        R.string.android_upgrading_complete),
9438                                                        false);
9439                                                systemReady(goingCallback);
9440                                            }
9441                                        });
9442                                    }
9443                                };
9444                            }
9445                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9446                                    + " for user " + users[j]);
9447                            broadcastIntentLocked(null, null, intent, null, finisher,
9448                                    0, null, null, null, AppOpsManager.OP_NONE,
9449                                    true, false, MY_PID, Process.SYSTEM_UID,
9450                                    users[j]);
9451                            if (finisher != null) {
9452                                mWaitingUpdate = true;
9453                            }
9454                        }
9455                    }
9456                }
9457                if (mWaitingUpdate) {
9458                    return;
9459                }
9460                mDidUpdate = true;
9461            }
9462
9463            mAppOpsService.systemReady();
9464            mSystemReady = true;
9465            if (!mStartRunning) {
9466                return;
9467            }
9468        }
9469
9470        ArrayList<ProcessRecord> procsToKill = null;
9471        synchronized(mPidsSelfLocked) {
9472            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9473                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9474                if (!isAllowedWhileBooting(proc.info)){
9475                    if (procsToKill == null) {
9476                        procsToKill = new ArrayList<ProcessRecord>();
9477                    }
9478                    procsToKill.add(proc);
9479                }
9480            }
9481        }
9482
9483        synchronized(this) {
9484            if (procsToKill != null) {
9485                for (int i=procsToKill.size()-1; i>=0; i--) {
9486                    ProcessRecord proc = procsToKill.get(i);
9487                    Slog.i(TAG, "Removing system update proc: " + proc);
9488                    removeProcessLocked(proc, true, false, "system update done");
9489                }
9490            }
9491
9492            // Now that we have cleaned up any update processes, we
9493            // are ready to start launching real processes and know that
9494            // we won't trample on them any more.
9495            mProcessesReady = true;
9496        }
9497
9498        Slog.i(TAG, "System now ready");
9499        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9500            SystemClock.uptimeMillis());
9501
9502        synchronized(this) {
9503            // Make sure we have no pre-ready processes sitting around.
9504
9505            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9506                ResolveInfo ri = mContext.getPackageManager()
9507                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9508                                STOCK_PM_FLAGS);
9509                CharSequence errorMsg = null;
9510                if (ri != null) {
9511                    ActivityInfo ai = ri.activityInfo;
9512                    ApplicationInfo app = ai.applicationInfo;
9513                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9514                        mTopAction = Intent.ACTION_FACTORY_TEST;
9515                        mTopData = null;
9516                        mTopComponent = new ComponentName(app.packageName,
9517                                ai.name);
9518                    } else {
9519                        errorMsg = mContext.getResources().getText(
9520                                com.android.internal.R.string.factorytest_not_system);
9521                    }
9522                } else {
9523                    errorMsg = mContext.getResources().getText(
9524                            com.android.internal.R.string.factorytest_no_action);
9525                }
9526                if (errorMsg != null) {
9527                    mTopAction = null;
9528                    mTopData = null;
9529                    mTopComponent = null;
9530                    Message msg = Message.obtain();
9531                    msg.what = SHOW_FACTORY_ERROR_MSG;
9532                    msg.getData().putCharSequence("msg", errorMsg);
9533                    mHandler.sendMessage(msg);
9534                }
9535            }
9536        }
9537
9538        retrieveSettings();
9539
9540        synchronized (this) {
9541            readGrantedUriPermissionsLocked();
9542        }
9543
9544        if (goingCallback != null) goingCallback.run();
9545
9546        synchronized (this) {
9547            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9548                try {
9549                    List apps = AppGlobals.getPackageManager().
9550                        getPersistentApplications(STOCK_PM_FLAGS);
9551                    if (apps != null) {
9552                        int N = apps.size();
9553                        int i;
9554                        for (i=0; i<N; i++) {
9555                            ApplicationInfo info
9556                                = (ApplicationInfo)apps.get(i);
9557                            if (info != null &&
9558                                    !info.packageName.equals("android")) {
9559                                addAppLocked(info, false);
9560                            }
9561                        }
9562                    }
9563                } catch (RemoteException ex) {
9564                    // pm is in same process, this will never happen.
9565                }
9566            }
9567
9568            // Start up initial activity.
9569            mBooting = true;
9570
9571            try {
9572                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9573                    Message msg = Message.obtain();
9574                    msg.what = SHOW_UID_ERROR_MSG;
9575                    mHandler.sendMessage(msg);
9576                }
9577            } catch (RemoteException e) {
9578            }
9579
9580            long ident = Binder.clearCallingIdentity();
9581            try {
9582                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9583                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9584                        | Intent.FLAG_RECEIVER_FOREGROUND);
9585                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9586                broadcastIntentLocked(null, null, intent,
9587                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9588                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9589                intent = new Intent(Intent.ACTION_USER_STARTING);
9590                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9591                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9592                broadcastIntentLocked(null, null, intent,
9593                        null, new IIntentReceiver.Stub() {
9594                            @Override
9595                            public void performReceive(Intent intent, int resultCode, String data,
9596                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9597                                    throws RemoteException {
9598                            }
9599                        }, 0, null, null,
9600                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9601                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9602            } finally {
9603                Binder.restoreCallingIdentity(ident);
9604            }
9605            mStackSupervisor.resumeTopActivitiesLocked();
9606            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9607        }
9608    }
9609
9610    private boolean makeAppCrashingLocked(ProcessRecord app,
9611            String shortMsg, String longMsg, String stackTrace) {
9612        app.crashing = true;
9613        app.crashingReport = generateProcessError(app,
9614                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9615        startAppProblemLocked(app);
9616        app.stopFreezingAllLocked();
9617        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9618    }
9619
9620    private void makeAppNotRespondingLocked(ProcessRecord app,
9621            String activity, String shortMsg, String longMsg) {
9622        app.notResponding = true;
9623        app.notRespondingReport = generateProcessError(app,
9624                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9625                activity, shortMsg, longMsg, null);
9626        startAppProblemLocked(app);
9627        app.stopFreezingAllLocked();
9628    }
9629
9630    /**
9631     * Generate a process error record, suitable for attachment to a ProcessRecord.
9632     *
9633     * @param app The ProcessRecord in which the error occurred.
9634     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9635     *                      ActivityManager.AppErrorStateInfo
9636     * @param activity The activity associated with the crash, if known.
9637     * @param shortMsg Short message describing the crash.
9638     * @param longMsg Long message describing the crash.
9639     * @param stackTrace Full crash stack trace, may be null.
9640     *
9641     * @return Returns a fully-formed AppErrorStateInfo record.
9642     */
9643    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9644            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9645        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9646
9647        report.condition = condition;
9648        report.processName = app.processName;
9649        report.pid = app.pid;
9650        report.uid = app.info.uid;
9651        report.tag = activity;
9652        report.shortMsg = shortMsg;
9653        report.longMsg = longMsg;
9654        report.stackTrace = stackTrace;
9655
9656        return report;
9657    }
9658
9659    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9660        synchronized (this) {
9661            app.crashing = false;
9662            app.crashingReport = null;
9663            app.notResponding = false;
9664            app.notRespondingReport = null;
9665            if (app.anrDialog == fromDialog) {
9666                app.anrDialog = null;
9667            }
9668            if (app.waitDialog == fromDialog) {
9669                app.waitDialog = null;
9670            }
9671            if (app.pid > 0 && app.pid != MY_PID) {
9672                handleAppCrashLocked(app, null, null, null);
9673                killUnneededProcessLocked(app, "user request after error");
9674            }
9675        }
9676    }
9677
9678    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9679            String stackTrace) {
9680        long now = SystemClock.uptimeMillis();
9681
9682        Long crashTime;
9683        if (!app.isolated) {
9684            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9685        } else {
9686            crashTime = null;
9687        }
9688        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9689            // This process loses!
9690            Slog.w(TAG, "Process " + app.info.processName
9691                    + " has crashed too many times: killing!");
9692            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9693                    app.userId, app.info.processName, app.uid);
9694            mStackSupervisor.handleAppCrashLocked(app);
9695            if (!app.persistent) {
9696                // We don't want to start this process again until the user
9697                // explicitly does so...  but for persistent process, we really
9698                // need to keep it running.  If a persistent process is actually
9699                // repeatedly crashing, then badness for everyone.
9700                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9701                        app.info.processName);
9702                if (!app.isolated) {
9703                    // XXX We don't have a way to mark isolated processes
9704                    // as bad, since they don't have a peristent identity.
9705                    mBadProcesses.put(app.info.processName, app.uid,
9706                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9707                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9708                }
9709                app.bad = true;
9710                app.removed = true;
9711                // Don't let services in this process be restarted and potentially
9712                // annoy the user repeatedly.  Unless it is persistent, since those
9713                // processes run critical code.
9714                removeProcessLocked(app, false, false, "crash");
9715                mStackSupervisor.resumeTopActivitiesLocked();
9716                return false;
9717            }
9718            mStackSupervisor.resumeTopActivitiesLocked();
9719        } else {
9720            mStackSupervisor.finishTopRunningActivityLocked(app);
9721        }
9722
9723        // Bump up the crash count of any services currently running in the proc.
9724        for (int i=app.services.size()-1; i>=0; i--) {
9725            // Any services running in the application need to be placed
9726            // back in the pending list.
9727            ServiceRecord sr = app.services.valueAt(i);
9728            sr.crashCount++;
9729        }
9730
9731        // If the crashing process is what we consider to be the "home process" and it has been
9732        // replaced by a third-party app, clear the package preferred activities from packages
9733        // with a home activity running in the process to prevent a repeatedly crashing app
9734        // from blocking the user to manually clear the list.
9735        final ArrayList<ActivityRecord> activities = app.activities;
9736        if (app == mHomeProcess && activities.size() > 0
9737                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9738            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9739                final ActivityRecord r = activities.get(activityNdx);
9740                if (r.isHomeActivity()) {
9741                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9742                    try {
9743                        ActivityThread.getPackageManager()
9744                                .clearPackagePreferredActivities(r.packageName);
9745                    } catch (RemoteException c) {
9746                        // pm is in same process, this will never happen.
9747                    }
9748                }
9749            }
9750        }
9751
9752        if (!app.isolated) {
9753            // XXX Can't keep track of crash times for isolated processes,
9754            // because they don't have a perisistent identity.
9755            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9756        }
9757
9758        return true;
9759    }
9760
9761    void startAppProblemLocked(ProcessRecord app) {
9762        if (app.userId == mCurrentUserId) {
9763            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9764                    mContext, app.info.packageName, app.info.flags);
9765        } else {
9766            // If this app is not running under the current user, then we
9767            // can't give it a report button because that would require
9768            // launching the report UI under a different user.
9769            app.errorReportReceiver = null;
9770        }
9771        skipCurrentReceiverLocked(app);
9772    }
9773
9774    void skipCurrentReceiverLocked(ProcessRecord app) {
9775        for (BroadcastQueue queue : mBroadcastQueues) {
9776            queue.skipCurrentReceiverLocked(app);
9777        }
9778    }
9779
9780    /**
9781     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9782     * The application process will exit immediately after this call returns.
9783     * @param app object of the crashing app, null for the system server
9784     * @param crashInfo describing the exception
9785     */
9786    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9787        ProcessRecord r = findAppProcess(app, "Crash");
9788        final String processName = app == null ? "system_server"
9789                : (r == null ? "unknown" : r.processName);
9790
9791        handleApplicationCrashInner("crash", r, processName, crashInfo);
9792    }
9793
9794    /* Native crash reporting uses this inner version because it needs to be somewhat
9795     * decoupled from the AM-managed cleanup lifecycle
9796     */
9797    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9798            ApplicationErrorReport.CrashInfo crashInfo) {
9799        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9800                UserHandle.getUserId(Binder.getCallingUid()), processName,
9801                r == null ? -1 : r.info.flags,
9802                crashInfo.exceptionClassName,
9803                crashInfo.exceptionMessage,
9804                crashInfo.throwFileName,
9805                crashInfo.throwLineNumber);
9806
9807        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9808
9809        crashApplication(r, crashInfo);
9810    }
9811
9812    public void handleApplicationStrictModeViolation(
9813            IBinder app,
9814            int violationMask,
9815            StrictMode.ViolationInfo info) {
9816        ProcessRecord r = findAppProcess(app, "StrictMode");
9817        if (r == null) {
9818            return;
9819        }
9820
9821        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9822            Integer stackFingerprint = info.hashCode();
9823            boolean logIt = true;
9824            synchronized (mAlreadyLoggedViolatedStacks) {
9825                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9826                    logIt = false;
9827                    // TODO: sub-sample into EventLog for these, with
9828                    // the info.durationMillis?  Then we'd get
9829                    // the relative pain numbers, without logging all
9830                    // the stack traces repeatedly.  We'd want to do
9831                    // likewise in the client code, which also does
9832                    // dup suppression, before the Binder call.
9833                } else {
9834                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9835                        mAlreadyLoggedViolatedStacks.clear();
9836                    }
9837                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9838                }
9839            }
9840            if (logIt) {
9841                logStrictModeViolationToDropBox(r, info);
9842            }
9843        }
9844
9845        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9846            AppErrorResult result = new AppErrorResult();
9847            synchronized (this) {
9848                final long origId = Binder.clearCallingIdentity();
9849
9850                Message msg = Message.obtain();
9851                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9852                HashMap<String, Object> data = new HashMap<String, Object>();
9853                data.put("result", result);
9854                data.put("app", r);
9855                data.put("violationMask", violationMask);
9856                data.put("info", info);
9857                msg.obj = data;
9858                mHandler.sendMessage(msg);
9859
9860                Binder.restoreCallingIdentity(origId);
9861            }
9862            int res = result.get();
9863            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9864        }
9865    }
9866
9867    // Depending on the policy in effect, there could be a bunch of
9868    // these in quick succession so we try to batch these together to
9869    // minimize disk writes, number of dropbox entries, and maximize
9870    // compression, by having more fewer, larger records.
9871    private void logStrictModeViolationToDropBox(
9872            ProcessRecord process,
9873            StrictMode.ViolationInfo info) {
9874        if (info == null) {
9875            return;
9876        }
9877        final boolean isSystemApp = process == null ||
9878                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9879                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9880        final String processName = process == null ? "unknown" : process.processName;
9881        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9882        final DropBoxManager dbox = (DropBoxManager)
9883                mContext.getSystemService(Context.DROPBOX_SERVICE);
9884
9885        // Exit early if the dropbox isn't configured to accept this report type.
9886        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9887
9888        boolean bufferWasEmpty;
9889        boolean needsFlush;
9890        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9891        synchronized (sb) {
9892            bufferWasEmpty = sb.length() == 0;
9893            appendDropBoxProcessHeaders(process, processName, sb);
9894            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9895            sb.append("System-App: ").append(isSystemApp).append("\n");
9896            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9897            if (info.violationNumThisLoop != 0) {
9898                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9899            }
9900            if (info.numAnimationsRunning != 0) {
9901                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9902            }
9903            if (info.broadcastIntentAction != null) {
9904                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9905            }
9906            if (info.durationMillis != -1) {
9907                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9908            }
9909            if (info.numInstances != -1) {
9910                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9911            }
9912            if (info.tags != null) {
9913                for (String tag : info.tags) {
9914                    sb.append("Span-Tag: ").append(tag).append("\n");
9915                }
9916            }
9917            sb.append("\n");
9918            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9919                sb.append(info.crashInfo.stackTrace);
9920            }
9921            sb.append("\n");
9922
9923            // Only buffer up to ~64k.  Various logging bits truncate
9924            // things at 128k.
9925            needsFlush = (sb.length() > 64 * 1024);
9926        }
9927
9928        // Flush immediately if the buffer's grown too large, or this
9929        // is a non-system app.  Non-system apps are isolated with a
9930        // different tag & policy and not batched.
9931        //
9932        // Batching is useful during internal testing with
9933        // StrictMode settings turned up high.  Without batching,
9934        // thousands of separate files could be created on boot.
9935        if (!isSystemApp || needsFlush) {
9936            new Thread("Error dump: " + dropboxTag) {
9937                @Override
9938                public void run() {
9939                    String report;
9940                    synchronized (sb) {
9941                        report = sb.toString();
9942                        sb.delete(0, sb.length());
9943                        sb.trimToSize();
9944                    }
9945                    if (report.length() != 0) {
9946                        dbox.addText(dropboxTag, report);
9947                    }
9948                }
9949            }.start();
9950            return;
9951        }
9952
9953        // System app batching:
9954        if (!bufferWasEmpty) {
9955            // An existing dropbox-writing thread is outstanding, so
9956            // we don't need to start it up.  The existing thread will
9957            // catch the buffer appends we just did.
9958            return;
9959        }
9960
9961        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9962        // (After this point, we shouldn't access AMS internal data structures.)
9963        new Thread("Error dump: " + dropboxTag) {
9964            @Override
9965            public void run() {
9966                // 5 second sleep to let stacks arrive and be batched together
9967                try {
9968                    Thread.sleep(5000);  // 5 seconds
9969                } catch (InterruptedException e) {}
9970
9971                String errorReport;
9972                synchronized (mStrictModeBuffer) {
9973                    errorReport = mStrictModeBuffer.toString();
9974                    if (errorReport.length() == 0) {
9975                        return;
9976                    }
9977                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9978                    mStrictModeBuffer.trimToSize();
9979                }
9980                dbox.addText(dropboxTag, errorReport);
9981            }
9982        }.start();
9983    }
9984
9985    /**
9986     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9987     * @param app object of the crashing app, null for the system server
9988     * @param tag reported by the caller
9989     * @param crashInfo describing the context of the error
9990     * @return true if the process should exit immediately (WTF is fatal)
9991     */
9992    public boolean handleApplicationWtf(IBinder app, String tag,
9993            ApplicationErrorReport.CrashInfo crashInfo) {
9994        ProcessRecord r = findAppProcess(app, "WTF");
9995        final String processName = app == null ? "system_server"
9996                : (r == null ? "unknown" : r.processName);
9997
9998        EventLog.writeEvent(EventLogTags.AM_WTF,
9999                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10000                processName,
10001                r == null ? -1 : r.info.flags,
10002                tag, crashInfo.exceptionMessage);
10003
10004        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10005
10006        if (r != null && r.pid != Process.myPid() &&
10007                Settings.Global.getInt(mContext.getContentResolver(),
10008                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10009            crashApplication(r, crashInfo);
10010            return true;
10011        } else {
10012            return false;
10013        }
10014    }
10015
10016    /**
10017     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10018     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10019     */
10020    private ProcessRecord findAppProcess(IBinder app, String reason) {
10021        if (app == null) {
10022            return null;
10023        }
10024
10025        synchronized (this) {
10026            final int NP = mProcessNames.getMap().size();
10027            for (int ip=0; ip<NP; ip++) {
10028                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10029                final int NA = apps.size();
10030                for (int ia=0; ia<NA; ia++) {
10031                    ProcessRecord p = apps.valueAt(ia);
10032                    if (p.thread != null && p.thread.asBinder() == app) {
10033                        return p;
10034                    }
10035                }
10036            }
10037
10038            Slog.w(TAG, "Can't find mystery application for " + reason
10039                    + " from pid=" + Binder.getCallingPid()
10040                    + " uid=" + Binder.getCallingUid() + ": " + app);
10041            return null;
10042        }
10043    }
10044
10045    /**
10046     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10047     * to append various headers to the dropbox log text.
10048     */
10049    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10050            StringBuilder sb) {
10051        // Watchdog thread ends up invoking this function (with
10052        // a null ProcessRecord) to add the stack file to dropbox.
10053        // Do not acquire a lock on this (am) in such cases, as it
10054        // could cause a potential deadlock, if and when watchdog
10055        // is invoked due to unavailability of lock on am and it
10056        // would prevent watchdog from killing system_server.
10057        if (process == null) {
10058            sb.append("Process: ").append(processName).append("\n");
10059            return;
10060        }
10061        // Note: ProcessRecord 'process' is guarded by the service
10062        // instance.  (notably process.pkgList, which could otherwise change
10063        // concurrently during execution of this method)
10064        synchronized (this) {
10065            sb.append("Process: ").append(processName).append("\n");
10066            int flags = process.info.flags;
10067            IPackageManager pm = AppGlobals.getPackageManager();
10068            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10069            for (int ip=0; ip<process.pkgList.size(); ip++) {
10070                String pkg = process.pkgList.keyAt(ip);
10071                sb.append("Package: ").append(pkg);
10072                try {
10073                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10074                    if (pi != null) {
10075                        sb.append(" v").append(pi.versionCode);
10076                        if (pi.versionName != null) {
10077                            sb.append(" (").append(pi.versionName).append(")");
10078                        }
10079                    }
10080                } catch (RemoteException e) {
10081                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10082                }
10083                sb.append("\n");
10084            }
10085        }
10086    }
10087
10088    private static String processClass(ProcessRecord process) {
10089        if (process == null || process.pid == MY_PID) {
10090            return "system_server";
10091        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10092            return "system_app";
10093        } else {
10094            return "data_app";
10095        }
10096    }
10097
10098    /**
10099     * Write a description of an error (crash, WTF, ANR) to the drop box.
10100     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10101     * @param process which caused the error, null means the system server
10102     * @param activity which triggered the error, null if unknown
10103     * @param parent activity related to the error, null if unknown
10104     * @param subject line related to the error, null if absent
10105     * @param report in long form describing the error, null if absent
10106     * @param logFile to include in the report, null if none
10107     * @param crashInfo giving an application stack trace, null if absent
10108     */
10109    public void addErrorToDropBox(String eventType,
10110            ProcessRecord process, String processName, ActivityRecord activity,
10111            ActivityRecord parent, String subject,
10112            final String report, final File logFile,
10113            final ApplicationErrorReport.CrashInfo crashInfo) {
10114        // NOTE -- this must never acquire the ActivityManagerService lock,
10115        // otherwise the watchdog may be prevented from resetting the system.
10116
10117        final String dropboxTag = processClass(process) + "_" + eventType;
10118        final DropBoxManager dbox = (DropBoxManager)
10119                mContext.getSystemService(Context.DROPBOX_SERVICE);
10120
10121        // Exit early if the dropbox isn't configured to accept this report type.
10122        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10123
10124        final StringBuilder sb = new StringBuilder(1024);
10125        appendDropBoxProcessHeaders(process, processName, sb);
10126        if (activity != null) {
10127            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10128        }
10129        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10130            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10131        }
10132        if (parent != null && parent != activity) {
10133            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10134        }
10135        if (subject != null) {
10136            sb.append("Subject: ").append(subject).append("\n");
10137        }
10138        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10139        if (Debug.isDebuggerConnected()) {
10140            sb.append("Debugger: Connected\n");
10141        }
10142        sb.append("\n");
10143
10144        // Do the rest in a worker thread to avoid blocking the caller on I/O
10145        // (After this point, we shouldn't access AMS internal data structures.)
10146        Thread worker = new Thread("Error dump: " + dropboxTag) {
10147            @Override
10148            public void run() {
10149                if (report != null) {
10150                    sb.append(report);
10151                }
10152                if (logFile != null) {
10153                    try {
10154                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10155                                    "\n\n[[TRUNCATED]]"));
10156                    } catch (IOException e) {
10157                        Slog.e(TAG, "Error reading " + logFile, e);
10158                    }
10159                }
10160                if (crashInfo != null && crashInfo.stackTrace != null) {
10161                    sb.append(crashInfo.stackTrace);
10162                }
10163
10164                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10165                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10166                if (lines > 0) {
10167                    sb.append("\n");
10168
10169                    // Merge several logcat streams, and take the last N lines
10170                    InputStreamReader input = null;
10171                    try {
10172                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10173                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10174                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10175
10176                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10177                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10178                        input = new InputStreamReader(logcat.getInputStream());
10179
10180                        int num;
10181                        char[] buf = new char[8192];
10182                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10183                    } catch (IOException e) {
10184                        Slog.e(TAG, "Error running logcat", e);
10185                    } finally {
10186                        if (input != null) try { input.close(); } catch (IOException e) {}
10187                    }
10188                }
10189
10190                dbox.addText(dropboxTag, sb.toString());
10191            }
10192        };
10193
10194        if (process == null) {
10195            // If process is null, we are being called from some internal code
10196            // and may be about to die -- run this synchronously.
10197            worker.run();
10198        } else {
10199            worker.start();
10200        }
10201    }
10202
10203    /**
10204     * Bring up the "unexpected error" dialog box for a crashing app.
10205     * Deal with edge cases (intercepts from instrumented applications,
10206     * ActivityController, error intent receivers, that sort of thing).
10207     * @param r the application crashing
10208     * @param crashInfo describing the failure
10209     */
10210    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10211        long timeMillis = System.currentTimeMillis();
10212        String shortMsg = crashInfo.exceptionClassName;
10213        String longMsg = crashInfo.exceptionMessage;
10214        String stackTrace = crashInfo.stackTrace;
10215        if (shortMsg != null && longMsg != null) {
10216            longMsg = shortMsg + ": " + longMsg;
10217        } else if (shortMsg != null) {
10218            longMsg = shortMsg;
10219        }
10220
10221        AppErrorResult result = new AppErrorResult();
10222        synchronized (this) {
10223            if (mController != null) {
10224                try {
10225                    String name = r != null ? r.processName : null;
10226                    int pid = r != null ? r.pid : Binder.getCallingPid();
10227                    if (!mController.appCrashed(name, pid,
10228                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10229                        Slog.w(TAG, "Force-killing crashed app " + name
10230                                + " at watcher's request");
10231                        Process.killProcess(pid);
10232                        return;
10233                    }
10234                } catch (RemoteException e) {
10235                    mController = null;
10236                    Watchdog.getInstance().setActivityController(null);
10237                }
10238            }
10239
10240            final long origId = Binder.clearCallingIdentity();
10241
10242            // If this process is running instrumentation, finish it.
10243            if (r != null && r.instrumentationClass != null) {
10244                Slog.w(TAG, "Error in app " + r.processName
10245                      + " running instrumentation " + r.instrumentationClass + ":");
10246                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10247                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10248                Bundle info = new Bundle();
10249                info.putString("shortMsg", shortMsg);
10250                info.putString("longMsg", longMsg);
10251                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10252                Binder.restoreCallingIdentity(origId);
10253                return;
10254            }
10255
10256            // If we can't identify the process or it's already exceeded its crash quota,
10257            // quit right away without showing a crash dialog.
10258            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10259                Binder.restoreCallingIdentity(origId);
10260                return;
10261            }
10262
10263            Message msg = Message.obtain();
10264            msg.what = SHOW_ERROR_MSG;
10265            HashMap data = new HashMap();
10266            data.put("result", result);
10267            data.put("app", r);
10268            msg.obj = data;
10269            mHandler.sendMessage(msg);
10270
10271            Binder.restoreCallingIdentity(origId);
10272        }
10273
10274        int res = result.get();
10275
10276        Intent appErrorIntent = null;
10277        synchronized (this) {
10278            if (r != null && !r.isolated) {
10279                // XXX Can't keep track of crash time for isolated processes,
10280                // since they don't have a persistent identity.
10281                mProcessCrashTimes.put(r.info.processName, r.uid,
10282                        SystemClock.uptimeMillis());
10283            }
10284            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10285                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10286            }
10287        }
10288
10289        if (appErrorIntent != null) {
10290            try {
10291                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10292            } catch (ActivityNotFoundException e) {
10293                Slog.w(TAG, "bug report receiver dissappeared", e);
10294            }
10295        }
10296    }
10297
10298    Intent createAppErrorIntentLocked(ProcessRecord r,
10299            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10300        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10301        if (report == null) {
10302            return null;
10303        }
10304        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10305        result.setComponent(r.errorReportReceiver);
10306        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10307        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10308        return result;
10309    }
10310
10311    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10312            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10313        if (r.errorReportReceiver == null) {
10314            return null;
10315        }
10316
10317        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10318            return null;
10319        }
10320
10321        ApplicationErrorReport report = new ApplicationErrorReport();
10322        report.packageName = r.info.packageName;
10323        report.installerPackageName = r.errorReportReceiver.getPackageName();
10324        report.processName = r.processName;
10325        report.time = timeMillis;
10326        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10327
10328        if (r.crashing || r.forceCrashReport) {
10329            report.type = ApplicationErrorReport.TYPE_CRASH;
10330            report.crashInfo = crashInfo;
10331        } else if (r.notResponding) {
10332            report.type = ApplicationErrorReport.TYPE_ANR;
10333            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10334
10335            report.anrInfo.activity = r.notRespondingReport.tag;
10336            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10337            report.anrInfo.info = r.notRespondingReport.longMsg;
10338        }
10339
10340        return report;
10341    }
10342
10343    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10344        enforceNotIsolatedCaller("getProcessesInErrorState");
10345        // assume our apps are happy - lazy create the list
10346        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10347
10348        final boolean allUsers = ActivityManager.checkUidPermission(
10349                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10350                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10351        int userId = UserHandle.getUserId(Binder.getCallingUid());
10352
10353        synchronized (this) {
10354
10355            // iterate across all processes
10356            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10357                ProcessRecord app = mLruProcesses.get(i);
10358                if (!allUsers && app.userId != userId) {
10359                    continue;
10360                }
10361                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10362                    // This one's in trouble, so we'll generate a report for it
10363                    // crashes are higher priority (in case there's a crash *and* an anr)
10364                    ActivityManager.ProcessErrorStateInfo report = null;
10365                    if (app.crashing) {
10366                        report = app.crashingReport;
10367                    } else if (app.notResponding) {
10368                        report = app.notRespondingReport;
10369                    }
10370
10371                    if (report != null) {
10372                        if (errList == null) {
10373                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10374                        }
10375                        errList.add(report);
10376                    } else {
10377                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10378                                " crashing = " + app.crashing +
10379                                " notResponding = " + app.notResponding);
10380                    }
10381                }
10382            }
10383        }
10384
10385        return errList;
10386    }
10387
10388    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10389        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10390            if (currApp != null) {
10391                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10392            }
10393            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10394        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10395            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10396        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10397            if (currApp != null) {
10398                currApp.lru = 0;
10399            }
10400            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10401        } else if (adj >= ProcessList.SERVICE_ADJ) {
10402            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10403        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10404            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10405        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10406            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10407        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10408            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10409        } else {
10410            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10411        }
10412    }
10413
10414    private void fillInProcMemInfo(ProcessRecord app,
10415            ActivityManager.RunningAppProcessInfo outInfo) {
10416        outInfo.pid = app.pid;
10417        outInfo.uid = app.info.uid;
10418        if (mHeavyWeightProcess == app) {
10419            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10420        }
10421        if (app.persistent) {
10422            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10423        }
10424        if (app.activities.size() > 0) {
10425            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10426        }
10427        outInfo.lastTrimLevel = app.trimMemoryLevel;
10428        int adj = app.curAdj;
10429        outInfo.importance = oomAdjToImportance(adj, outInfo);
10430        outInfo.importanceReasonCode = app.adjTypeCode;
10431    }
10432
10433    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10434        enforceNotIsolatedCaller("getRunningAppProcesses");
10435        // Lazy instantiation of list
10436        List<ActivityManager.RunningAppProcessInfo> runList = null;
10437        final boolean allUsers = ActivityManager.checkUidPermission(
10438                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10439                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10440        int userId = UserHandle.getUserId(Binder.getCallingUid());
10441        synchronized (this) {
10442            // Iterate across all processes
10443            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10444                ProcessRecord app = mLruProcesses.get(i);
10445                if (!allUsers && app.userId != userId) {
10446                    continue;
10447                }
10448                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10449                    // Generate process state info for running application
10450                    ActivityManager.RunningAppProcessInfo currApp =
10451                        new ActivityManager.RunningAppProcessInfo(app.processName,
10452                                app.pid, app.getPackageList());
10453                    fillInProcMemInfo(app, currApp);
10454                    if (app.adjSource instanceof ProcessRecord) {
10455                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10456                        currApp.importanceReasonImportance = oomAdjToImportance(
10457                                app.adjSourceOom, null);
10458                    } else if (app.adjSource instanceof ActivityRecord) {
10459                        ActivityRecord r = (ActivityRecord)app.adjSource;
10460                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10461                    }
10462                    if (app.adjTarget instanceof ComponentName) {
10463                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10464                    }
10465                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10466                    //        + " lru=" + currApp.lru);
10467                    if (runList == null) {
10468                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10469                    }
10470                    runList.add(currApp);
10471                }
10472            }
10473        }
10474        return runList;
10475    }
10476
10477    public List<ApplicationInfo> getRunningExternalApplications() {
10478        enforceNotIsolatedCaller("getRunningExternalApplications");
10479        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10480        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10481        if (runningApps != null && runningApps.size() > 0) {
10482            Set<String> extList = new HashSet<String>();
10483            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10484                if (app.pkgList != null) {
10485                    for (String pkg : app.pkgList) {
10486                        extList.add(pkg);
10487                    }
10488                }
10489            }
10490            IPackageManager pm = AppGlobals.getPackageManager();
10491            for (String pkg : extList) {
10492                try {
10493                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10494                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10495                        retList.add(info);
10496                    }
10497                } catch (RemoteException e) {
10498                }
10499            }
10500        }
10501        return retList;
10502    }
10503
10504    @Override
10505    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10506        enforceNotIsolatedCaller("getMyMemoryState");
10507        synchronized (this) {
10508            ProcessRecord proc;
10509            synchronized (mPidsSelfLocked) {
10510                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10511            }
10512            fillInProcMemInfo(proc, outInfo);
10513        }
10514    }
10515
10516    @Override
10517    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10518        if (checkCallingPermission(android.Manifest.permission.DUMP)
10519                != PackageManager.PERMISSION_GRANTED) {
10520            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10521                    + Binder.getCallingPid()
10522                    + ", uid=" + Binder.getCallingUid()
10523                    + " without permission "
10524                    + android.Manifest.permission.DUMP);
10525            return;
10526        }
10527
10528        boolean dumpAll = false;
10529        boolean dumpClient = false;
10530        String dumpPackage = null;
10531
10532        int opti = 0;
10533        while (opti < args.length) {
10534            String opt = args[opti];
10535            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10536                break;
10537            }
10538            opti++;
10539            if ("-a".equals(opt)) {
10540                dumpAll = true;
10541            } else if ("-c".equals(opt)) {
10542                dumpClient = true;
10543            } else if ("-h".equals(opt)) {
10544                pw.println("Activity manager dump options:");
10545                pw.println("  [-a] [-c] [-h] [cmd] ...");
10546                pw.println("  cmd may be one of:");
10547                pw.println("    a[ctivities]: activity stack state");
10548                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10549                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10550                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10551                pw.println("    o[om]: out of memory management");
10552                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10553                pw.println("    provider [COMP_SPEC]: provider client-side state");
10554                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10555                pw.println("    service [COMP_SPEC]: service client-side state");
10556                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10557                pw.println("    all: dump all activities");
10558                pw.println("    top: dump the top activity");
10559                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10560                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10561                pw.println("    a partial substring in a component name, a");
10562                pw.println("    hex object identifier.");
10563                pw.println("  -a: include all available server state.");
10564                pw.println("  -c: include client state.");
10565                return;
10566            } else {
10567                pw.println("Unknown argument: " + opt + "; use -h for help");
10568            }
10569        }
10570
10571        long origId = Binder.clearCallingIdentity();
10572        boolean more = false;
10573        // Is the caller requesting to dump a particular piece of data?
10574        if (opti < args.length) {
10575            String cmd = args[opti];
10576            opti++;
10577            if ("activities".equals(cmd) || "a".equals(cmd)) {
10578                synchronized (this) {
10579                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10580                }
10581            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10582                String[] newArgs;
10583                String name;
10584                if (opti >= args.length) {
10585                    name = null;
10586                    newArgs = EMPTY_STRING_ARRAY;
10587                } else {
10588                    name = args[opti];
10589                    opti++;
10590                    newArgs = new String[args.length - opti];
10591                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10592                            args.length - opti);
10593                }
10594                synchronized (this) {
10595                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10596                }
10597            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10598                String[] newArgs;
10599                String name;
10600                if (opti >= args.length) {
10601                    name = null;
10602                    newArgs = EMPTY_STRING_ARRAY;
10603                } else {
10604                    name = args[opti];
10605                    opti++;
10606                    newArgs = new String[args.length - opti];
10607                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10608                            args.length - opti);
10609                }
10610                synchronized (this) {
10611                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10612                }
10613            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10614                String[] newArgs;
10615                String name;
10616                if (opti >= args.length) {
10617                    name = null;
10618                    newArgs = EMPTY_STRING_ARRAY;
10619                } else {
10620                    name = args[opti];
10621                    opti++;
10622                    newArgs = new String[args.length - opti];
10623                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10624                            args.length - opti);
10625                }
10626                synchronized (this) {
10627                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10628                }
10629            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10630                synchronized (this) {
10631                    dumpOomLocked(fd, pw, args, opti, true);
10632                }
10633            } else if ("provider".equals(cmd)) {
10634                String[] newArgs;
10635                String name;
10636                if (opti >= args.length) {
10637                    name = null;
10638                    newArgs = EMPTY_STRING_ARRAY;
10639                } else {
10640                    name = args[opti];
10641                    opti++;
10642                    newArgs = new String[args.length - opti];
10643                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10644                }
10645                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10646                    pw.println("No providers match: " + name);
10647                    pw.println("Use -h for help.");
10648                }
10649            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10650                synchronized (this) {
10651                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10652                }
10653            } else if ("service".equals(cmd)) {
10654                String[] newArgs;
10655                String name;
10656                if (opti >= args.length) {
10657                    name = null;
10658                    newArgs = EMPTY_STRING_ARRAY;
10659                } else {
10660                    name = args[opti];
10661                    opti++;
10662                    newArgs = new String[args.length - opti];
10663                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10664                            args.length - opti);
10665                }
10666                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10667                    pw.println("No services match: " + name);
10668                    pw.println("Use -h for help.");
10669                }
10670            } else if ("package".equals(cmd)) {
10671                String[] newArgs;
10672                if (opti >= args.length) {
10673                    pw.println("package: no package name specified");
10674                    pw.println("Use -h for help.");
10675                } else {
10676                    dumpPackage = args[opti];
10677                    opti++;
10678                    newArgs = new String[args.length - opti];
10679                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10680                            args.length - opti);
10681                    args = newArgs;
10682                    opti = 0;
10683                    more = true;
10684                }
10685            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10686                synchronized (this) {
10687                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10688                }
10689            } else {
10690                // Dumping a single activity?
10691                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10692                    pw.println("Bad activity command, or no activities match: " + cmd);
10693                    pw.println("Use -h for help.");
10694                }
10695            }
10696            if (!more) {
10697                Binder.restoreCallingIdentity(origId);
10698                return;
10699            }
10700        }
10701
10702        // No piece of data specified, dump everything.
10703        synchronized (this) {
10704            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10705            pw.println();
10706            if (dumpAll) {
10707                pw.println("-------------------------------------------------------------------------------");
10708            }
10709            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10710            pw.println();
10711            if (dumpAll) {
10712                pw.println("-------------------------------------------------------------------------------");
10713            }
10714            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10715            pw.println();
10716            if (dumpAll) {
10717                pw.println("-------------------------------------------------------------------------------");
10718            }
10719            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10720            pw.println();
10721            if (dumpAll) {
10722                pw.println("-------------------------------------------------------------------------------");
10723            }
10724            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10725            pw.println();
10726            if (dumpAll) {
10727                pw.println("-------------------------------------------------------------------------------");
10728            }
10729            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10730        }
10731        Binder.restoreCallingIdentity(origId);
10732    }
10733
10734    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10735            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10736        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10737
10738        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10739                dumpPackage);
10740        boolean needSep = printedAnything;
10741
10742        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10743                dumpPackage, needSep, "  mFocusedActivity: ");
10744        if (printed) {
10745            printedAnything = true;
10746            needSep = false;
10747        }
10748
10749        if (dumpPackage == null) {
10750            if (needSep) {
10751                pw.println();
10752            }
10753            needSep = true;
10754            printedAnything = true;
10755            mStackSupervisor.dump(pw, "  ");
10756        }
10757
10758        if (mRecentTasks.size() > 0) {
10759            boolean printedHeader = false;
10760
10761            final int N = mRecentTasks.size();
10762            for (int i=0; i<N; i++) {
10763                TaskRecord tr = mRecentTasks.get(i);
10764                if (dumpPackage != null) {
10765                    if (tr.realActivity == null ||
10766                            !dumpPackage.equals(tr.realActivity)) {
10767                        continue;
10768                    }
10769                }
10770                if (!printedHeader) {
10771                    if (needSep) {
10772                        pw.println();
10773                    }
10774                    pw.println("  Recent tasks:");
10775                    printedHeader = true;
10776                    printedAnything = true;
10777                }
10778                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10779                        pw.println(tr);
10780                if (dumpAll) {
10781                    mRecentTasks.get(i).dump(pw, "    ");
10782                }
10783            }
10784        }
10785
10786        if (!printedAnything) {
10787            pw.println("  (nothing)");
10788        }
10789    }
10790
10791    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10792            int opti, boolean dumpAll, String dumpPackage) {
10793        boolean needSep = false;
10794        boolean printedAnything = false;
10795        int numPers = 0;
10796
10797        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10798
10799        if (dumpAll) {
10800            final int NP = mProcessNames.getMap().size();
10801            for (int ip=0; ip<NP; ip++) {
10802                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10803                final int NA = procs.size();
10804                for (int ia=0; ia<NA; ia++) {
10805                    ProcessRecord r = procs.valueAt(ia);
10806                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10807                        continue;
10808                    }
10809                    if (!needSep) {
10810                        pw.println("  All known processes:");
10811                        needSep = true;
10812                        printedAnything = true;
10813                    }
10814                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10815                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10816                        pw.print(" "); pw.println(r);
10817                    r.dump(pw, "    ");
10818                    if (r.persistent) {
10819                        numPers++;
10820                    }
10821                }
10822            }
10823        }
10824
10825        if (mIsolatedProcesses.size() > 0) {
10826            boolean printed = false;
10827            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10828                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10829                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10830                    continue;
10831                }
10832                if (!printed) {
10833                    if (needSep) {
10834                        pw.println();
10835                    }
10836                    pw.println("  Isolated process list (sorted by uid):");
10837                    printedAnything = true;
10838                    printed = true;
10839                    needSep = true;
10840                }
10841                pw.println(String.format("%sIsolated #%2d: %s",
10842                        "    ", i, r.toString()));
10843            }
10844        }
10845
10846        if (mLruProcesses.size() > 0) {
10847            if (needSep) {
10848                pw.println();
10849            }
10850            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10851                    pw.print(" total, non-act at ");
10852                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10853                    pw.print(", non-svc at ");
10854                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10855                    pw.println("):");
10856            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10857            needSep = true;
10858            printedAnything = true;
10859        }
10860
10861        if (dumpAll || dumpPackage != null) {
10862            synchronized (mPidsSelfLocked) {
10863                boolean printed = false;
10864                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10865                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10866                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10867                        continue;
10868                    }
10869                    if (!printed) {
10870                        if (needSep) pw.println();
10871                        needSep = true;
10872                        pw.println("  PID mappings:");
10873                        printed = true;
10874                        printedAnything = true;
10875                    }
10876                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10877                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10878                }
10879            }
10880        }
10881
10882        if (mForegroundProcesses.size() > 0) {
10883            synchronized (mPidsSelfLocked) {
10884                boolean printed = false;
10885                for (int i=0; i<mForegroundProcesses.size(); i++) {
10886                    ProcessRecord r = mPidsSelfLocked.get(
10887                            mForegroundProcesses.valueAt(i).pid);
10888                    if (dumpPackage != null && (r == null
10889                            || !r.pkgList.containsKey(dumpPackage))) {
10890                        continue;
10891                    }
10892                    if (!printed) {
10893                        if (needSep) pw.println();
10894                        needSep = true;
10895                        pw.println("  Foreground Processes:");
10896                        printed = true;
10897                        printedAnything = true;
10898                    }
10899                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10900                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10901                }
10902            }
10903        }
10904
10905        if (mPersistentStartingProcesses.size() > 0) {
10906            if (needSep) pw.println();
10907            needSep = true;
10908            printedAnything = true;
10909            pw.println("  Persisent processes that are starting:");
10910            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10911                    "Starting Norm", "Restarting PERS", dumpPackage);
10912        }
10913
10914        if (mRemovedProcesses.size() > 0) {
10915            if (needSep) pw.println();
10916            needSep = true;
10917            printedAnything = true;
10918            pw.println("  Processes that are being removed:");
10919            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10920                    "Removed Norm", "Removed PERS", dumpPackage);
10921        }
10922
10923        if (mProcessesOnHold.size() > 0) {
10924            if (needSep) pw.println();
10925            needSep = true;
10926            printedAnything = true;
10927            pw.println("  Processes that are on old until the system is ready:");
10928            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10929                    "OnHold Norm", "OnHold PERS", dumpPackage);
10930        }
10931
10932        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10933
10934        if (mProcessCrashTimes.getMap().size() > 0) {
10935            boolean printed = false;
10936            long now = SystemClock.uptimeMillis();
10937            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10938            final int NP = pmap.size();
10939            for (int ip=0; ip<NP; ip++) {
10940                String pname = pmap.keyAt(ip);
10941                SparseArray<Long> uids = pmap.valueAt(ip);
10942                final int N = uids.size();
10943                for (int i=0; i<N; i++) {
10944                    int puid = uids.keyAt(i);
10945                    ProcessRecord r = mProcessNames.get(pname, puid);
10946                    if (dumpPackage != null && (r == null
10947                            || !r.pkgList.containsKey(dumpPackage))) {
10948                        continue;
10949                    }
10950                    if (!printed) {
10951                        if (needSep) pw.println();
10952                        needSep = true;
10953                        pw.println("  Time since processes crashed:");
10954                        printed = true;
10955                        printedAnything = true;
10956                    }
10957                    pw.print("    Process "); pw.print(pname);
10958                            pw.print(" uid "); pw.print(puid);
10959                            pw.print(": last crashed ");
10960                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10961                            pw.println(" ago");
10962                }
10963            }
10964        }
10965
10966        if (mBadProcesses.getMap().size() > 0) {
10967            boolean printed = false;
10968            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10969            final int NP = pmap.size();
10970            for (int ip=0; ip<NP; ip++) {
10971                String pname = pmap.keyAt(ip);
10972                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10973                final int N = uids.size();
10974                for (int i=0; i<N; i++) {
10975                    int puid = uids.keyAt(i);
10976                    ProcessRecord r = mProcessNames.get(pname, puid);
10977                    if (dumpPackage != null && (r == null
10978                            || !r.pkgList.containsKey(dumpPackage))) {
10979                        continue;
10980                    }
10981                    if (!printed) {
10982                        if (needSep) pw.println();
10983                        needSep = true;
10984                        pw.println("  Bad processes:");
10985                        printedAnything = true;
10986                    }
10987                    BadProcessInfo info = uids.valueAt(i);
10988                    pw.print("    Bad process "); pw.print(pname);
10989                            pw.print(" uid "); pw.print(puid);
10990                            pw.print(": crashed at time "); pw.println(info.time);
10991                    if (info.shortMsg != null) {
10992                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10993                    }
10994                    if (info.longMsg != null) {
10995                        pw.print("      Long msg: "); pw.println(info.longMsg);
10996                    }
10997                    if (info.stack != null) {
10998                        pw.println("      Stack:");
10999                        int lastPos = 0;
11000                        for (int pos=0; pos<info.stack.length(); pos++) {
11001                            if (info.stack.charAt(pos) == '\n') {
11002                                pw.print("        ");
11003                                pw.write(info.stack, lastPos, pos-lastPos);
11004                                pw.println();
11005                                lastPos = pos+1;
11006                            }
11007                        }
11008                        if (lastPos < info.stack.length()) {
11009                            pw.print("        ");
11010                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11011                            pw.println();
11012                        }
11013                    }
11014                }
11015            }
11016        }
11017
11018        if (dumpPackage == null) {
11019            pw.println();
11020            needSep = false;
11021            pw.println("  mStartedUsers:");
11022            for (int i=0; i<mStartedUsers.size(); i++) {
11023                UserStartedState uss = mStartedUsers.valueAt(i);
11024                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11025                        pw.print(": "); uss.dump("", pw);
11026            }
11027            pw.print("  mStartedUserArray: [");
11028            for (int i=0; i<mStartedUserArray.length; i++) {
11029                if (i > 0) pw.print(", ");
11030                pw.print(mStartedUserArray[i]);
11031            }
11032            pw.println("]");
11033            pw.print("  mUserLru: [");
11034            for (int i=0; i<mUserLru.size(); i++) {
11035                if (i > 0) pw.print(", ");
11036                pw.print(mUserLru.get(i));
11037            }
11038            pw.println("]");
11039            if (dumpAll) {
11040                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11041            }
11042        }
11043        if (mHomeProcess != null && (dumpPackage == null
11044                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11045            if (needSep) {
11046                pw.println();
11047                needSep = false;
11048            }
11049            pw.println("  mHomeProcess: " + mHomeProcess);
11050        }
11051        if (mPreviousProcess != null && (dumpPackage == null
11052                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11053            if (needSep) {
11054                pw.println();
11055                needSep = false;
11056            }
11057            pw.println("  mPreviousProcess: " + mPreviousProcess);
11058        }
11059        if (dumpAll) {
11060            StringBuilder sb = new StringBuilder(128);
11061            sb.append("  mPreviousProcessVisibleTime: ");
11062            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11063            pw.println(sb);
11064        }
11065        if (mHeavyWeightProcess != null && (dumpPackage == null
11066                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11067            if (needSep) {
11068                pw.println();
11069                needSep = false;
11070            }
11071            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11072        }
11073        if (dumpPackage == null) {
11074            pw.println("  mConfiguration: " + mConfiguration);
11075        }
11076        if (dumpAll) {
11077            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11078            if (mCompatModePackages.getPackages().size() > 0) {
11079                boolean printed = false;
11080                for (Map.Entry<String, Integer> entry
11081                        : mCompatModePackages.getPackages().entrySet()) {
11082                    String pkg = entry.getKey();
11083                    int mode = entry.getValue();
11084                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11085                        continue;
11086                    }
11087                    if (!printed) {
11088                        pw.println("  mScreenCompatPackages:");
11089                        printed = true;
11090                    }
11091                    pw.print("    "); pw.print(pkg); pw.print(": ");
11092                            pw.print(mode); pw.println();
11093                }
11094            }
11095        }
11096        if (dumpPackage == null) {
11097            if (mSleeping || mWentToSleep || mLockScreenShown) {
11098                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11099                        + " mLockScreenShown " + mLockScreenShown);
11100            }
11101            if (mShuttingDown) {
11102                pw.println("  mShuttingDown=" + mShuttingDown);
11103            }
11104        }
11105        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11106                || mOrigWaitForDebugger) {
11107            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11108                    || dumpPackage.equals(mOrigDebugApp)) {
11109                if (needSep) {
11110                    pw.println();
11111                    needSep = false;
11112                }
11113                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11114                        + " mDebugTransient=" + mDebugTransient
11115                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11116            }
11117        }
11118        if (mOpenGlTraceApp != null) {
11119            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11120                if (needSep) {
11121                    pw.println();
11122                    needSep = false;
11123                }
11124                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11125            }
11126        }
11127        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11128                || mProfileFd != null) {
11129            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11130                if (needSep) {
11131                    pw.println();
11132                    needSep = false;
11133                }
11134                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11135                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11136                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11137                        + mAutoStopProfiler);
11138            }
11139        }
11140        if (dumpPackage == null) {
11141            if (mAlwaysFinishActivities || mController != null) {
11142                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11143                        + " mController=" + mController);
11144            }
11145            if (dumpAll) {
11146                pw.println("  Total persistent processes: " + numPers);
11147                pw.println("  mStartRunning=" + mStartRunning
11148                        + " mProcessesReady=" + mProcessesReady
11149                        + " mSystemReady=" + mSystemReady);
11150                pw.println("  mBooting=" + mBooting
11151                        + " mBooted=" + mBooted
11152                        + " mFactoryTest=" + mFactoryTest);
11153                pw.print("  mLastPowerCheckRealtime=");
11154                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11155                        pw.println("");
11156                pw.print("  mLastPowerCheckUptime=");
11157                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11158                        pw.println("");
11159                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11160                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11161                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11162                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11163                        + " (" + mLruProcesses.size() + " total)"
11164                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11165                        + " mNumServiceProcs=" + mNumServiceProcs
11166                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11167                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11168                        + " mLastMemoryLevel" + mLastMemoryLevel
11169                        + " mLastNumProcesses" + mLastNumProcesses);
11170                long now = SystemClock.uptimeMillis();
11171                pw.print("  mLastIdleTime=");
11172                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11173                        pw.print(" mLowRamSinceLastIdle=");
11174                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11175                        pw.println();
11176            }
11177        }
11178
11179        if (!printedAnything) {
11180            pw.println("  (nothing)");
11181        }
11182    }
11183
11184    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11185            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11186        if (mProcessesToGc.size() > 0) {
11187            boolean printed = false;
11188            long now = SystemClock.uptimeMillis();
11189            for (int i=0; i<mProcessesToGc.size(); i++) {
11190                ProcessRecord proc = mProcessesToGc.get(i);
11191                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11192                    continue;
11193                }
11194                if (!printed) {
11195                    if (needSep) pw.println();
11196                    needSep = true;
11197                    pw.println("  Processes that are waiting to GC:");
11198                    printed = true;
11199                }
11200                pw.print("    Process "); pw.println(proc);
11201                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11202                        pw.print(", last gced=");
11203                        pw.print(now-proc.lastRequestedGc);
11204                        pw.print(" ms ago, last lowMem=");
11205                        pw.print(now-proc.lastLowMemory);
11206                        pw.println(" ms ago");
11207
11208            }
11209        }
11210        return needSep;
11211    }
11212
11213    void printOomLevel(PrintWriter pw, String name, int adj) {
11214        pw.print("    ");
11215        if (adj >= 0) {
11216            pw.print(' ');
11217            if (adj < 10) pw.print(' ');
11218        } else {
11219            if (adj > -10) pw.print(' ');
11220        }
11221        pw.print(adj);
11222        pw.print(": ");
11223        pw.print(name);
11224        pw.print(" (");
11225        pw.print(mProcessList.getMemLevel(adj)/1024);
11226        pw.println(" kB)");
11227    }
11228
11229    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11230            int opti, boolean dumpAll) {
11231        boolean needSep = false;
11232
11233        if (mLruProcesses.size() > 0) {
11234            if (needSep) pw.println();
11235            needSep = true;
11236            pw.println("  OOM levels:");
11237            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11238            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11239            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11240            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11241            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11242            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11243            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11244            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11245            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11246            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11247            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11248            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11249            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11250
11251            if (needSep) pw.println();
11252            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11253                    pw.print(" total, non-act at ");
11254                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11255                    pw.print(", non-svc at ");
11256                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11257                    pw.println("):");
11258            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11259            needSep = true;
11260        }
11261
11262        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11263
11264        pw.println();
11265        pw.println("  mHomeProcess: " + mHomeProcess);
11266        pw.println("  mPreviousProcess: " + mPreviousProcess);
11267        if (mHeavyWeightProcess != null) {
11268            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11269        }
11270
11271        return true;
11272    }
11273
11274    /**
11275     * There are three ways to call this:
11276     *  - no provider specified: dump all the providers
11277     *  - a flattened component name that matched an existing provider was specified as the
11278     *    first arg: dump that one provider
11279     *  - the first arg isn't the flattened component name of an existing provider:
11280     *    dump all providers whose component contains the first arg as a substring
11281     */
11282    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11283            int opti, boolean dumpAll) {
11284        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11285    }
11286
11287    static class ItemMatcher {
11288        ArrayList<ComponentName> components;
11289        ArrayList<String> strings;
11290        ArrayList<Integer> objects;
11291        boolean all;
11292
11293        ItemMatcher() {
11294            all = true;
11295        }
11296
11297        void build(String name) {
11298            ComponentName componentName = ComponentName.unflattenFromString(name);
11299            if (componentName != null) {
11300                if (components == null) {
11301                    components = new ArrayList<ComponentName>();
11302                }
11303                components.add(componentName);
11304                all = false;
11305            } else {
11306                int objectId = 0;
11307                // Not a '/' separated full component name; maybe an object ID?
11308                try {
11309                    objectId = Integer.parseInt(name, 16);
11310                    if (objects == null) {
11311                        objects = new ArrayList<Integer>();
11312                    }
11313                    objects.add(objectId);
11314                    all = false;
11315                } catch (RuntimeException e) {
11316                    // Not an integer; just do string match.
11317                    if (strings == null) {
11318                        strings = new ArrayList<String>();
11319                    }
11320                    strings.add(name);
11321                    all = false;
11322                }
11323            }
11324        }
11325
11326        int build(String[] args, int opti) {
11327            for (; opti<args.length; opti++) {
11328                String name = args[opti];
11329                if ("--".equals(name)) {
11330                    return opti+1;
11331                }
11332                build(name);
11333            }
11334            return opti;
11335        }
11336
11337        boolean match(Object object, ComponentName comp) {
11338            if (all) {
11339                return true;
11340            }
11341            if (components != null) {
11342                for (int i=0; i<components.size(); i++) {
11343                    if (components.get(i).equals(comp)) {
11344                        return true;
11345                    }
11346                }
11347            }
11348            if (objects != null) {
11349                for (int i=0; i<objects.size(); i++) {
11350                    if (System.identityHashCode(object) == objects.get(i)) {
11351                        return true;
11352                    }
11353                }
11354            }
11355            if (strings != null) {
11356                String flat = comp.flattenToString();
11357                for (int i=0; i<strings.size(); i++) {
11358                    if (flat.contains(strings.get(i))) {
11359                        return true;
11360                    }
11361                }
11362            }
11363            return false;
11364        }
11365    }
11366
11367    /**
11368     * There are three things that cmd can be:
11369     *  - a flattened component name that matches an existing activity
11370     *  - the cmd arg isn't the flattened component name of an existing activity:
11371     *    dump all activity whose component contains the cmd as a substring
11372     *  - A hex number of the ActivityRecord object instance.
11373     */
11374    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11375            int opti, boolean dumpAll) {
11376        ArrayList<ActivityRecord> activities;
11377
11378        synchronized (this) {
11379            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11380        }
11381
11382        if (activities.size() <= 0) {
11383            return false;
11384        }
11385
11386        String[] newArgs = new String[args.length - opti];
11387        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11388
11389        TaskRecord lastTask = null;
11390        boolean needSep = false;
11391        for (int i=activities.size()-1; i>=0; i--) {
11392            ActivityRecord r = activities.get(i);
11393            if (needSep) {
11394                pw.println();
11395            }
11396            needSep = true;
11397            synchronized (this) {
11398                if (lastTask != r.task) {
11399                    lastTask = r.task;
11400                    pw.print("TASK "); pw.print(lastTask.affinity);
11401                            pw.print(" id="); pw.println(lastTask.taskId);
11402                    if (dumpAll) {
11403                        lastTask.dump(pw, "  ");
11404                    }
11405                }
11406            }
11407            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11408        }
11409        return true;
11410    }
11411
11412    /**
11413     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11414     * there is a thread associated with the activity.
11415     */
11416    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11417            final ActivityRecord r, String[] args, boolean dumpAll) {
11418        String innerPrefix = prefix + "  ";
11419        synchronized (this) {
11420            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11421                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11422                    pw.print(" pid=");
11423                    if (r.app != null) pw.println(r.app.pid);
11424                    else pw.println("(not running)");
11425            if (dumpAll) {
11426                r.dump(pw, innerPrefix);
11427            }
11428        }
11429        if (r.app != null && r.app.thread != null) {
11430            // flush anything that is already in the PrintWriter since the thread is going
11431            // to write to the file descriptor directly
11432            pw.flush();
11433            try {
11434                TransferPipe tp = new TransferPipe();
11435                try {
11436                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11437                            r.appToken, innerPrefix, args);
11438                    tp.go(fd);
11439                } finally {
11440                    tp.kill();
11441                }
11442            } catch (IOException e) {
11443                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11444            } catch (RemoteException e) {
11445                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11446            }
11447        }
11448    }
11449
11450    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11451            int opti, boolean dumpAll, String dumpPackage) {
11452        boolean needSep = false;
11453        boolean onlyHistory = false;
11454        boolean printedAnything = false;
11455
11456        if ("history".equals(dumpPackage)) {
11457            if (opti < args.length && "-s".equals(args[opti])) {
11458                dumpAll = false;
11459            }
11460            onlyHistory = true;
11461            dumpPackage = null;
11462        }
11463
11464        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11465        if (!onlyHistory && dumpAll) {
11466            if (mRegisteredReceivers.size() > 0) {
11467                boolean printed = false;
11468                Iterator it = mRegisteredReceivers.values().iterator();
11469                while (it.hasNext()) {
11470                    ReceiverList r = (ReceiverList)it.next();
11471                    if (dumpPackage != null && (r.app == null ||
11472                            !dumpPackage.equals(r.app.info.packageName))) {
11473                        continue;
11474                    }
11475                    if (!printed) {
11476                        pw.println("  Registered Receivers:");
11477                        needSep = true;
11478                        printed = true;
11479                        printedAnything = true;
11480                    }
11481                    pw.print("  * "); pw.println(r);
11482                    r.dump(pw, "    ");
11483                }
11484            }
11485
11486            if (mReceiverResolver.dump(pw, needSep ?
11487                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11488                    "    ", dumpPackage, false)) {
11489                needSep = true;
11490                printedAnything = true;
11491            }
11492        }
11493
11494        for (BroadcastQueue q : mBroadcastQueues) {
11495            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11496            printedAnything |= needSep;
11497        }
11498
11499        needSep = true;
11500
11501        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11502            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11503                if (needSep) {
11504                    pw.println();
11505                }
11506                needSep = true;
11507                printedAnything = true;
11508                pw.print("  Sticky broadcasts for user ");
11509                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11510                StringBuilder sb = new StringBuilder(128);
11511                for (Map.Entry<String, ArrayList<Intent>> ent
11512                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11513                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11514                    if (dumpAll) {
11515                        pw.println(":");
11516                        ArrayList<Intent> intents = ent.getValue();
11517                        final int N = intents.size();
11518                        for (int i=0; i<N; i++) {
11519                            sb.setLength(0);
11520                            sb.append("    Intent: ");
11521                            intents.get(i).toShortString(sb, false, true, false, false);
11522                            pw.println(sb.toString());
11523                            Bundle bundle = intents.get(i).getExtras();
11524                            if (bundle != null) {
11525                                pw.print("      ");
11526                                pw.println(bundle.toString());
11527                            }
11528                        }
11529                    } else {
11530                        pw.println("");
11531                    }
11532                }
11533            }
11534        }
11535
11536        if (!onlyHistory && dumpAll) {
11537            pw.println();
11538            for (BroadcastQueue queue : mBroadcastQueues) {
11539                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11540                        + queue.mBroadcastsScheduled);
11541            }
11542            pw.println("  mHandler:");
11543            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11544            needSep = true;
11545            printedAnything = true;
11546        }
11547
11548        if (!printedAnything) {
11549            pw.println("  (nothing)");
11550        }
11551    }
11552
11553    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11554            int opti, boolean dumpAll, String dumpPackage) {
11555        boolean needSep;
11556        boolean printedAnything = false;
11557
11558        ItemMatcher matcher = new ItemMatcher();
11559        matcher.build(args, opti);
11560
11561        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11562
11563        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11564        printedAnything |= needSep;
11565
11566        if (mLaunchingProviders.size() > 0) {
11567            boolean printed = false;
11568            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11569                ContentProviderRecord r = mLaunchingProviders.get(i);
11570                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11571                    continue;
11572                }
11573                if (!printed) {
11574                    if (needSep) pw.println();
11575                    needSep = true;
11576                    pw.println("  Launching content providers:");
11577                    printed = true;
11578                    printedAnything = true;
11579                }
11580                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11581                        pw.println(r);
11582            }
11583        }
11584
11585        if (mGrantedUriPermissions.size() > 0) {
11586            boolean printed = false;
11587            int dumpUid = -2;
11588            if (dumpPackage != null) {
11589                try {
11590                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11591                } catch (NameNotFoundException e) {
11592                    dumpUid = -1;
11593                }
11594            }
11595            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11596                int uid = mGrantedUriPermissions.keyAt(i);
11597                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11598                    continue;
11599                }
11600                ArrayMap<Uri, UriPermission> perms
11601                        = mGrantedUriPermissions.valueAt(i);
11602                if (!printed) {
11603                    if (needSep) pw.println();
11604                    needSep = true;
11605                    pw.println("  Granted Uri Permissions:");
11606                    printed = true;
11607                    printedAnything = true;
11608                }
11609                pw.print("  * UID "); pw.print(uid);
11610                        pw.println(" holds:");
11611                for (UriPermission perm : perms.values()) {
11612                    pw.print("    "); pw.println(perm);
11613                    if (dumpAll) {
11614                        perm.dump(pw, "      ");
11615                    }
11616                }
11617            }
11618        }
11619
11620        if (!printedAnything) {
11621            pw.println("  (nothing)");
11622        }
11623    }
11624
11625    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11626            int opti, boolean dumpAll, String dumpPackage) {
11627        boolean printed = false;
11628
11629        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11630
11631        if (mIntentSenderRecords.size() > 0) {
11632            Iterator<WeakReference<PendingIntentRecord>> it
11633                    = mIntentSenderRecords.values().iterator();
11634            while (it.hasNext()) {
11635                WeakReference<PendingIntentRecord> ref = it.next();
11636                PendingIntentRecord rec = ref != null ? ref.get(): null;
11637                if (dumpPackage != null && (rec == null
11638                        || !dumpPackage.equals(rec.key.packageName))) {
11639                    continue;
11640                }
11641                printed = true;
11642                if (rec != null) {
11643                    pw.print("  * "); pw.println(rec);
11644                    if (dumpAll) {
11645                        rec.dump(pw, "    ");
11646                    }
11647                } else {
11648                    pw.print("  * "); pw.println(ref);
11649                }
11650            }
11651        }
11652
11653        if (!printed) {
11654            pw.println("  (nothing)");
11655        }
11656    }
11657
11658    private static final int dumpProcessList(PrintWriter pw,
11659            ActivityManagerService service, List list,
11660            String prefix, String normalLabel, String persistentLabel,
11661            String dumpPackage) {
11662        int numPers = 0;
11663        final int N = list.size()-1;
11664        for (int i=N; i>=0; i--) {
11665            ProcessRecord r = (ProcessRecord)list.get(i);
11666            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11667                continue;
11668            }
11669            pw.println(String.format("%s%s #%2d: %s",
11670                    prefix, (r.persistent ? persistentLabel : normalLabel),
11671                    i, r.toString()));
11672            if (r.persistent) {
11673                numPers++;
11674            }
11675        }
11676        return numPers;
11677    }
11678
11679    private static final boolean dumpProcessOomList(PrintWriter pw,
11680            ActivityManagerService service, List<ProcessRecord> origList,
11681            String prefix, String normalLabel, String persistentLabel,
11682            boolean inclDetails, String dumpPackage) {
11683
11684        ArrayList<Pair<ProcessRecord, Integer>> list
11685                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11686        for (int i=0; i<origList.size(); i++) {
11687            ProcessRecord r = origList.get(i);
11688            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11689                continue;
11690            }
11691            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11692        }
11693
11694        if (list.size() <= 0) {
11695            return false;
11696        }
11697
11698        Comparator<Pair<ProcessRecord, Integer>> comparator
11699                = new Comparator<Pair<ProcessRecord, Integer>>() {
11700            @Override
11701            public int compare(Pair<ProcessRecord, Integer> object1,
11702                    Pair<ProcessRecord, Integer> object2) {
11703                if (object1.first.setAdj != object2.first.setAdj) {
11704                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11705                }
11706                if (object1.second.intValue() != object2.second.intValue()) {
11707                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11708                }
11709                return 0;
11710            }
11711        };
11712
11713        Collections.sort(list, comparator);
11714
11715        final long curRealtime = SystemClock.elapsedRealtime();
11716        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11717        final long curUptime = SystemClock.uptimeMillis();
11718        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11719
11720        for (int i=list.size()-1; i>=0; i--) {
11721            ProcessRecord r = list.get(i).first;
11722            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11723            char schedGroup;
11724            switch (r.setSchedGroup) {
11725                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11726                    schedGroup = 'B';
11727                    break;
11728                case Process.THREAD_GROUP_DEFAULT:
11729                    schedGroup = 'F';
11730                    break;
11731                default:
11732                    schedGroup = '?';
11733                    break;
11734            }
11735            char foreground;
11736            if (r.foregroundActivities) {
11737                foreground = 'A';
11738            } else if (r.foregroundServices) {
11739                foreground = 'S';
11740            } else {
11741                foreground = ' ';
11742            }
11743            String procState = ProcessList.makeProcStateString(r.curProcState);
11744            pw.print(prefix);
11745            pw.print(r.persistent ? persistentLabel : normalLabel);
11746            pw.print(" #");
11747            int num = (origList.size()-1)-list.get(i).second;
11748            if (num < 10) pw.print(' ');
11749            pw.print(num);
11750            pw.print(": ");
11751            pw.print(oomAdj);
11752            pw.print(' ');
11753            pw.print(schedGroup);
11754            pw.print('/');
11755            pw.print(foreground);
11756            pw.print('/');
11757            pw.print(procState);
11758            pw.print(" trm:");
11759            if (r.trimMemoryLevel < 10) pw.print(' ');
11760            pw.print(r.trimMemoryLevel);
11761            pw.print(' ');
11762            pw.print(r.toShortString());
11763            pw.print(" (");
11764            pw.print(r.adjType);
11765            pw.println(')');
11766            if (r.adjSource != null || r.adjTarget != null) {
11767                pw.print(prefix);
11768                pw.print("    ");
11769                if (r.adjTarget instanceof ComponentName) {
11770                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11771                } else if (r.adjTarget != null) {
11772                    pw.print(r.adjTarget.toString());
11773                } else {
11774                    pw.print("{null}");
11775                }
11776                pw.print("<=");
11777                if (r.adjSource instanceof ProcessRecord) {
11778                    pw.print("Proc{");
11779                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11780                    pw.println("}");
11781                } else if (r.adjSource != null) {
11782                    pw.println(r.adjSource.toString());
11783                } else {
11784                    pw.println("{null}");
11785                }
11786            }
11787            if (inclDetails) {
11788                pw.print(prefix);
11789                pw.print("    ");
11790                pw.print("oom: max="); pw.print(r.maxAdj);
11791                pw.print(" curRaw="); pw.print(r.curRawAdj);
11792                pw.print(" setRaw="); pw.print(r.setRawAdj);
11793                pw.print(" cur="); pw.print(r.curAdj);
11794                pw.print(" set="); pw.println(r.setAdj);
11795                pw.print(prefix);
11796                pw.print("    ");
11797                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11798                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11799                pw.print(" lastPss="); pw.print(r.lastPss);
11800                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11801                pw.print(prefix);
11802                pw.print("    ");
11803                pw.print("keeping="); pw.print(r.keeping);
11804                pw.print(" cached="); pw.print(r.cached);
11805                pw.print(" empty="); pw.print(r.empty);
11806                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11807
11808                if (!r.keeping) {
11809                    if (r.lastWakeTime != 0) {
11810                        long wtime;
11811                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11812                        synchronized (stats) {
11813                            wtime = stats.getProcessWakeTime(r.info.uid,
11814                                    r.pid, curRealtime);
11815                        }
11816                        long timeUsed = wtime - r.lastWakeTime;
11817                        pw.print(prefix);
11818                        pw.print("    ");
11819                        pw.print("keep awake over ");
11820                        TimeUtils.formatDuration(realtimeSince, pw);
11821                        pw.print(" used ");
11822                        TimeUtils.formatDuration(timeUsed, pw);
11823                        pw.print(" (");
11824                        pw.print((timeUsed*100)/realtimeSince);
11825                        pw.println("%)");
11826                    }
11827                    if (r.lastCpuTime != 0) {
11828                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11829                        pw.print(prefix);
11830                        pw.print("    ");
11831                        pw.print("run cpu over ");
11832                        TimeUtils.formatDuration(uptimeSince, pw);
11833                        pw.print(" used ");
11834                        TimeUtils.formatDuration(timeUsed, pw);
11835                        pw.print(" (");
11836                        pw.print((timeUsed*100)/uptimeSince);
11837                        pw.println("%)");
11838                    }
11839                }
11840            }
11841        }
11842        return true;
11843    }
11844
11845    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11846        ArrayList<ProcessRecord> procs;
11847        synchronized (this) {
11848            if (args != null && args.length > start
11849                    && args[start].charAt(0) != '-') {
11850                procs = new ArrayList<ProcessRecord>();
11851                int pid = -1;
11852                try {
11853                    pid = Integer.parseInt(args[start]);
11854                } catch (NumberFormatException e) {
11855                }
11856                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11857                    ProcessRecord proc = mLruProcesses.get(i);
11858                    if (proc.pid == pid) {
11859                        procs.add(proc);
11860                    } else if (proc.processName.equals(args[start])) {
11861                        procs.add(proc);
11862                    }
11863                }
11864                if (procs.size() <= 0) {
11865                    return null;
11866                }
11867            } else {
11868                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11869            }
11870        }
11871        return procs;
11872    }
11873
11874    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11875            PrintWriter pw, String[] args) {
11876        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11877        if (procs == null) {
11878            pw.println("No process found for: " + args[0]);
11879            return;
11880        }
11881
11882        long uptime = SystemClock.uptimeMillis();
11883        long realtime = SystemClock.elapsedRealtime();
11884        pw.println("Applications Graphics Acceleration Info:");
11885        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11886
11887        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11888            ProcessRecord r = procs.get(i);
11889            if (r.thread != null) {
11890                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11891                pw.flush();
11892                try {
11893                    TransferPipe tp = new TransferPipe();
11894                    try {
11895                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11896                        tp.go(fd);
11897                    } finally {
11898                        tp.kill();
11899                    }
11900                } catch (IOException e) {
11901                    pw.println("Failure while dumping the app: " + r);
11902                    pw.flush();
11903                } catch (RemoteException e) {
11904                    pw.println("Got a RemoteException while dumping the app " + r);
11905                    pw.flush();
11906                }
11907            }
11908        }
11909    }
11910
11911    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11912        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11913        if (procs == null) {
11914            pw.println("No process found for: " + args[0]);
11915            return;
11916        }
11917
11918        pw.println("Applications Database Info:");
11919
11920        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11921            ProcessRecord r = procs.get(i);
11922            if (r.thread != null) {
11923                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11924                pw.flush();
11925                try {
11926                    TransferPipe tp = new TransferPipe();
11927                    try {
11928                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11929                        tp.go(fd);
11930                    } finally {
11931                        tp.kill();
11932                    }
11933                } catch (IOException e) {
11934                    pw.println("Failure while dumping the app: " + r);
11935                    pw.flush();
11936                } catch (RemoteException e) {
11937                    pw.println("Got a RemoteException while dumping the app " + r);
11938                    pw.flush();
11939                }
11940            }
11941        }
11942    }
11943
11944    final static class MemItem {
11945        final boolean isProc;
11946        final String label;
11947        final String shortLabel;
11948        final long pss;
11949        final int id;
11950        final boolean hasActivities;
11951        ArrayList<MemItem> subitems;
11952
11953        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11954                boolean _hasActivities) {
11955            isProc = true;
11956            label = _label;
11957            shortLabel = _shortLabel;
11958            pss = _pss;
11959            id = _id;
11960            hasActivities = _hasActivities;
11961        }
11962
11963        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11964            isProc = false;
11965            label = _label;
11966            shortLabel = _shortLabel;
11967            pss = _pss;
11968            id = _id;
11969            hasActivities = false;
11970        }
11971    }
11972
11973    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11974            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11975        if (sort && !isCompact) {
11976            Collections.sort(items, new Comparator<MemItem>() {
11977                @Override
11978                public int compare(MemItem lhs, MemItem rhs) {
11979                    if (lhs.pss < rhs.pss) {
11980                        return 1;
11981                    } else if (lhs.pss > rhs.pss) {
11982                        return -1;
11983                    }
11984                    return 0;
11985                }
11986            });
11987        }
11988
11989        for (int i=0; i<items.size(); i++) {
11990            MemItem mi = items.get(i);
11991            if (!isCompact) {
11992                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11993            } else if (mi.isProc) {
11994                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11995                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11996                pw.println(mi.hasActivities ? ",a" : ",e");
11997            } else {
11998                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11999                pw.println(mi.pss);
12000            }
12001            if (mi.subitems != null) {
12002                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12003                        true, isCompact);
12004            }
12005        }
12006    }
12007
12008    // These are in KB.
12009    static final long[] DUMP_MEM_BUCKETS = new long[] {
12010        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12011        120*1024, 160*1024, 200*1024,
12012        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12013        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12014    };
12015
12016    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12017            boolean stackLike) {
12018        int start = label.lastIndexOf('.');
12019        if (start >= 0) start++;
12020        else start = 0;
12021        int end = label.length();
12022        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12023            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12024                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12025                out.append(bucket);
12026                out.append(stackLike ? "MB." : "MB ");
12027                out.append(label, start, end);
12028                return;
12029            }
12030        }
12031        out.append(memKB/1024);
12032        out.append(stackLike ? "MB." : "MB ");
12033        out.append(label, start, end);
12034    }
12035
12036    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12037            ProcessList.NATIVE_ADJ,
12038            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12039            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12040            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12041            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12042            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12043    };
12044    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12045            "Native",
12046            "System", "Persistent", "Foreground",
12047            "Visible", "Perceptible",
12048            "Heavy Weight", "Backup",
12049            "A Services", "Home",
12050            "Previous", "B Services", "Cached"
12051    };
12052    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12053            "native",
12054            "sys", "pers", "fore",
12055            "vis", "percept",
12056            "heavy", "backup",
12057            "servicea", "home",
12058            "prev", "serviceb", "cached"
12059    };
12060
12061    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12062            long realtime, boolean isCheckinRequest, boolean isCompact) {
12063        if (isCheckinRequest || isCompact) {
12064            // short checkin version
12065            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12066        } else {
12067            pw.println("Applications Memory Usage (kB):");
12068            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12069        }
12070    }
12071
12072    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12073            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12074        boolean dumpDetails = false;
12075        boolean dumpFullDetails = false;
12076        boolean dumpDalvik = false;
12077        boolean oomOnly = false;
12078        boolean isCompact = false;
12079        boolean localOnly = false;
12080
12081        int opti = 0;
12082        while (opti < args.length) {
12083            String opt = args[opti];
12084            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12085                break;
12086            }
12087            opti++;
12088            if ("-a".equals(opt)) {
12089                dumpDetails = true;
12090                dumpFullDetails = true;
12091                dumpDalvik = true;
12092            } else if ("-d".equals(opt)) {
12093                dumpDalvik = true;
12094            } else if ("-c".equals(opt)) {
12095                isCompact = true;
12096            } else if ("--oom".equals(opt)) {
12097                oomOnly = true;
12098            } else if ("--local".equals(opt)) {
12099                localOnly = true;
12100            } else if ("-h".equals(opt)) {
12101                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12102                pw.println("  -a: include all available information for each process.");
12103                pw.println("  -d: include dalvik details when dumping process details.");
12104                pw.println("  -c: dump in a compact machine-parseable representation.");
12105                pw.println("  --oom: only show processes organized by oom adj.");
12106                pw.println("  --local: only collect details locally, don't call process.");
12107                pw.println("If [process] is specified it can be the name or ");
12108                pw.println("pid of a specific process to dump.");
12109                return;
12110            } else {
12111                pw.println("Unknown argument: " + opt + "; use -h for help");
12112            }
12113        }
12114
12115        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12116        long uptime = SystemClock.uptimeMillis();
12117        long realtime = SystemClock.elapsedRealtime();
12118        final long[] tmpLong = new long[1];
12119
12120        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12121        if (procs == null) {
12122            // No Java processes.  Maybe they want to print a native process.
12123            if (args != null && args.length > opti
12124                    && args[opti].charAt(0) != '-') {
12125                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12126                        = new ArrayList<ProcessCpuTracker.Stats>();
12127                updateCpuStatsNow();
12128                int findPid = -1;
12129                try {
12130                    findPid = Integer.parseInt(args[opti]);
12131                } catch (NumberFormatException e) {
12132                }
12133                synchronized (mProcessCpuThread) {
12134                    final int N = mProcessCpuTracker.countStats();
12135                    for (int i=0; i<N; i++) {
12136                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12137                        if (st.pid == findPid || (st.baseName != null
12138                                && st.baseName.equals(args[opti]))) {
12139                            nativeProcs.add(st);
12140                        }
12141                    }
12142                }
12143                if (nativeProcs.size() > 0) {
12144                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12145                            isCompact);
12146                    Debug.MemoryInfo mi = null;
12147                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12148                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12149                        final int pid = r.pid;
12150                        if (!isCheckinRequest && dumpDetails) {
12151                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12152                        }
12153                        if (mi == null) {
12154                            mi = new Debug.MemoryInfo();
12155                        }
12156                        if (dumpDetails || (!brief && !oomOnly)) {
12157                            Debug.getMemoryInfo(pid, mi);
12158                        } else {
12159                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12160                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12161                        }
12162                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12163                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12164                        if (isCheckinRequest) {
12165                            pw.println();
12166                        }
12167                    }
12168                    return;
12169                }
12170            }
12171            pw.println("No process found for: " + args[opti]);
12172            return;
12173        }
12174
12175        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12176            dumpDetails = true;
12177        }
12178
12179        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12180
12181        String[] innerArgs = new String[args.length-opti];
12182        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12183
12184        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12185        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12186        long nativePss=0, dalvikPss=0, otherPss=0;
12187        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12188
12189        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12190        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12191                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12192
12193        long totalPss = 0;
12194        long cachedPss = 0;
12195
12196        Debug.MemoryInfo mi = null;
12197        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12198            final ProcessRecord r = procs.get(i);
12199            final IApplicationThread thread;
12200            final int pid;
12201            final int oomAdj;
12202            final boolean hasActivities;
12203            synchronized (this) {
12204                thread = r.thread;
12205                pid = r.pid;
12206                oomAdj = r.getSetAdjWithServices();
12207                hasActivities = r.activities.size() > 0;
12208            }
12209            if (thread != null) {
12210                if (!isCheckinRequest && dumpDetails) {
12211                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12212                }
12213                if (mi == null) {
12214                    mi = new Debug.MemoryInfo();
12215                }
12216                if (dumpDetails || (!brief && !oomOnly)) {
12217                    Debug.getMemoryInfo(pid, mi);
12218                } else {
12219                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12220                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12221                }
12222                if (dumpDetails) {
12223                    if (localOnly) {
12224                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12225                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12226                        if (isCheckinRequest) {
12227                            pw.println();
12228                        }
12229                    } else {
12230                        try {
12231                            pw.flush();
12232                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12233                                    dumpDalvik, innerArgs);
12234                        } catch (RemoteException e) {
12235                            if (!isCheckinRequest) {
12236                                pw.println("Got RemoteException!");
12237                                pw.flush();
12238                            }
12239                        }
12240                    }
12241                }
12242
12243                final long myTotalPss = mi.getTotalPss();
12244                final long myTotalUss = mi.getTotalUss();
12245
12246                synchronized (this) {
12247                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12248                        // Record this for posterity if the process has been stable.
12249                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12250                    }
12251                }
12252
12253                if (!isCheckinRequest && mi != null) {
12254                    totalPss += myTotalPss;
12255                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12256                            (hasActivities ? " / activities)" : ")"),
12257                            r.processName, myTotalPss, pid, hasActivities);
12258                    procMems.add(pssItem);
12259                    procMemsMap.put(pid, pssItem);
12260
12261                    nativePss += mi.nativePss;
12262                    dalvikPss += mi.dalvikPss;
12263                    otherPss += mi.otherPss;
12264                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12265                        long mem = mi.getOtherPss(j);
12266                        miscPss[j] += mem;
12267                        otherPss -= mem;
12268                    }
12269
12270                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12271                        cachedPss += myTotalPss;
12272                    }
12273
12274                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12275                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12276                                || oomIndex == (oomPss.length-1)) {
12277                            oomPss[oomIndex] += myTotalPss;
12278                            if (oomProcs[oomIndex] == null) {
12279                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12280                            }
12281                            oomProcs[oomIndex].add(pssItem);
12282                            break;
12283                        }
12284                    }
12285                }
12286            }
12287        }
12288
12289        if (!isCheckinRequest && procs.size() > 1) {
12290            // If we are showing aggregations, also look for native processes to
12291            // include so that our aggregations are more accurate.
12292            updateCpuStatsNow();
12293            synchronized (mProcessCpuThread) {
12294                final int N = mProcessCpuTracker.countStats();
12295                for (int i=0; i<N; i++) {
12296                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12297                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12298                        if (mi == null) {
12299                            mi = new Debug.MemoryInfo();
12300                        }
12301                        if (!brief && !oomOnly) {
12302                            Debug.getMemoryInfo(st.pid, mi);
12303                        } else {
12304                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12305                            mi.nativePrivateDirty = (int)tmpLong[0];
12306                        }
12307
12308                        final long myTotalPss = mi.getTotalPss();
12309                        totalPss += myTotalPss;
12310
12311                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12312                                st.name, myTotalPss, st.pid, false);
12313                        procMems.add(pssItem);
12314
12315                        nativePss += mi.nativePss;
12316                        dalvikPss += mi.dalvikPss;
12317                        otherPss += mi.otherPss;
12318                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12319                            long mem = mi.getOtherPss(j);
12320                            miscPss[j] += mem;
12321                            otherPss -= mem;
12322                        }
12323                        oomPss[0] += myTotalPss;
12324                        if (oomProcs[0] == null) {
12325                            oomProcs[0] = new ArrayList<MemItem>();
12326                        }
12327                        oomProcs[0].add(pssItem);
12328                    }
12329                }
12330            }
12331
12332            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12333
12334            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12335            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12336            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12337            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12338                String label = Debug.MemoryInfo.getOtherLabel(j);
12339                catMems.add(new MemItem(label, label, miscPss[j], j));
12340            }
12341
12342            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12343            for (int j=0; j<oomPss.length; j++) {
12344                if (oomPss[j] != 0) {
12345                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12346                            : DUMP_MEM_OOM_LABEL[j];
12347                    MemItem item = new MemItem(label, label, oomPss[j],
12348                            DUMP_MEM_OOM_ADJ[j]);
12349                    item.subitems = oomProcs[j];
12350                    oomMems.add(item);
12351                }
12352            }
12353
12354            if (!brief && !oomOnly && !isCompact) {
12355                pw.println();
12356                pw.println("Total PSS by process:");
12357                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12358                pw.println();
12359            }
12360            if (!isCompact) {
12361                pw.println("Total PSS by OOM adjustment:");
12362            }
12363            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12364            if (!brief && !oomOnly) {
12365                PrintWriter out = categoryPw != null ? categoryPw : pw;
12366                if (!isCompact) {
12367                    out.println();
12368                    out.println("Total PSS by category:");
12369                }
12370                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12371            }
12372            if (!isCompact) {
12373                pw.println();
12374            }
12375            MemInfoReader memInfo = new MemInfoReader();
12376            memInfo.readMemInfo();
12377            if (!brief) {
12378                if (!isCompact) {
12379                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12380                    pw.print(" kB (status ");
12381                    switch (mLastMemoryLevel) {
12382                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12383                            pw.println("normal)");
12384                            break;
12385                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12386                            pw.println("moderate)");
12387                            break;
12388                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12389                            pw.println("low)");
12390                            break;
12391                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12392                            pw.println("critical)");
12393                            break;
12394                        default:
12395                            pw.print(mLastMemoryLevel);
12396                            pw.println(")");
12397                            break;
12398                    }
12399                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12400                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12401                            pw.print(cachedPss); pw.print(" cached pss + ");
12402                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12403                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12404                } else {
12405                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12406                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12407                            + memInfo.getFreeSizeKb()); pw.print(",");
12408                    pw.println(totalPss - cachedPss);
12409                }
12410            }
12411            if (!isCompact) {
12412                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12413                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12414                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12415                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12416                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12417                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12418                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12419                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12420                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12421                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12422                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12423            }
12424            if (!brief) {
12425                if (memInfo.getZramTotalSizeKb() != 0) {
12426                    if (!isCompact) {
12427                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12428                                pw.print(" kB physical used for ");
12429                                pw.print(memInfo.getSwapTotalSizeKb()
12430                                        - memInfo.getSwapFreeSizeKb());
12431                                pw.print(" kB in swap (");
12432                                pw.print(memInfo.getSwapTotalSizeKb());
12433                                pw.println(" kB total swap)");
12434                    } else {
12435                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12436                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12437                                pw.println(memInfo.getSwapFreeSizeKb());
12438                    }
12439                }
12440                final int[] SINGLE_LONG_FORMAT = new int[] {
12441                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12442                };
12443                long[] longOut = new long[1];
12444                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12445                        SINGLE_LONG_FORMAT, null, longOut, null);
12446                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12447                longOut[0] = 0;
12448                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12449                        SINGLE_LONG_FORMAT, null, longOut, null);
12450                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12451                longOut[0] = 0;
12452                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12453                        SINGLE_LONG_FORMAT, null, longOut, null);
12454                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12455                longOut[0] = 0;
12456                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12457                        SINGLE_LONG_FORMAT, null, longOut, null);
12458                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12459                if (!isCompact) {
12460                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12461                        pw.print("      KSM: "); pw.print(sharing);
12462                                pw.print(" kB saved from shared ");
12463                                pw.print(shared); pw.println(" kB");
12464                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12465                                pw.print(voltile); pw.println(" kB volatile");
12466                    }
12467                    pw.print("   Tuning: ");
12468                    pw.print(ActivityManager.staticGetMemoryClass());
12469                    pw.print(" (large ");
12470                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12471                    pw.print("), oom ");
12472                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12473                    pw.print(" kB");
12474                    pw.print(", restore limit ");
12475                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12476                    pw.print(" kB");
12477                    if (ActivityManager.isLowRamDeviceStatic()) {
12478                        pw.print(" (low-ram)");
12479                    }
12480                    if (ActivityManager.isHighEndGfx()) {
12481                        pw.print(" (high-end-gfx)");
12482                    }
12483                    pw.println();
12484                } else {
12485                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12486                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12487                    pw.println(voltile);
12488                    pw.print("tuning,");
12489                    pw.print(ActivityManager.staticGetMemoryClass());
12490                    pw.print(',');
12491                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12492                    pw.print(',');
12493                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12494                    if (ActivityManager.isLowRamDeviceStatic()) {
12495                        pw.print(",low-ram");
12496                    }
12497                    if (ActivityManager.isHighEndGfx()) {
12498                        pw.print(",high-end-gfx");
12499                    }
12500                    pw.println();
12501                }
12502            }
12503        }
12504    }
12505
12506    /**
12507     * Searches array of arguments for the specified string
12508     * @param args array of argument strings
12509     * @param value value to search for
12510     * @return true if the value is contained in the array
12511     */
12512    private static boolean scanArgs(String[] args, String value) {
12513        if (args != null) {
12514            for (String arg : args) {
12515                if (value.equals(arg)) {
12516                    return true;
12517                }
12518            }
12519        }
12520        return false;
12521    }
12522
12523    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12524            ContentProviderRecord cpr, boolean always) {
12525        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12526
12527        if (!inLaunching || always) {
12528            synchronized (cpr) {
12529                cpr.launchingApp = null;
12530                cpr.notifyAll();
12531            }
12532            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12533            String names[] = cpr.info.authority.split(";");
12534            for (int j = 0; j < names.length; j++) {
12535                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12536            }
12537        }
12538
12539        for (int i=0; i<cpr.connections.size(); i++) {
12540            ContentProviderConnection conn = cpr.connections.get(i);
12541            if (conn.waiting) {
12542                // If this connection is waiting for the provider, then we don't
12543                // need to mess with its process unless we are always removing
12544                // or for some reason the provider is not currently launching.
12545                if (inLaunching && !always) {
12546                    continue;
12547                }
12548            }
12549            ProcessRecord capp = conn.client;
12550            conn.dead = true;
12551            if (conn.stableCount > 0) {
12552                if (!capp.persistent && capp.thread != null
12553                        && capp.pid != 0
12554                        && capp.pid != MY_PID) {
12555                    killUnneededProcessLocked(capp, "depends on provider "
12556                            + cpr.name.flattenToShortString()
12557                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12558                }
12559            } else if (capp.thread != null && conn.provider.provider != null) {
12560                try {
12561                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12562                } catch (RemoteException e) {
12563                }
12564                // In the protocol here, we don't expect the client to correctly
12565                // clean up this connection, we'll just remove it.
12566                cpr.connections.remove(i);
12567                conn.client.conProviders.remove(conn);
12568            }
12569        }
12570
12571        if (inLaunching && always) {
12572            mLaunchingProviders.remove(cpr);
12573        }
12574        return inLaunching;
12575    }
12576
12577    /**
12578     * Main code for cleaning up a process when it has gone away.  This is
12579     * called both as a result of the process dying, or directly when stopping
12580     * a process when running in single process mode.
12581     */
12582    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12583            boolean restarting, boolean allowRestart, int index) {
12584        if (index >= 0) {
12585            removeLruProcessLocked(app);
12586            ProcessList.remove(app.pid);
12587        }
12588
12589        mProcessesToGc.remove(app);
12590        mPendingPssProcesses.remove(app);
12591
12592        // Dismiss any open dialogs.
12593        if (app.crashDialog != null && !app.forceCrashReport) {
12594            app.crashDialog.dismiss();
12595            app.crashDialog = null;
12596        }
12597        if (app.anrDialog != null) {
12598            app.anrDialog.dismiss();
12599            app.anrDialog = null;
12600        }
12601        if (app.waitDialog != null) {
12602            app.waitDialog.dismiss();
12603            app.waitDialog = null;
12604        }
12605
12606        app.crashing = false;
12607        app.notResponding = false;
12608
12609        app.resetPackageList(mProcessStats);
12610        app.unlinkDeathRecipient();
12611        app.makeInactive(mProcessStats);
12612        app.forcingToForeground = null;
12613        updateProcessForegroundLocked(app, false, false);
12614        app.foregroundActivities = false;
12615        app.hasShownUi = false;
12616        app.treatLikeActivity = false;
12617        app.hasAboveClient = false;
12618        app.hasClientActivities = false;
12619
12620        mServices.killServicesLocked(app, allowRestart);
12621
12622        boolean restart = false;
12623
12624        // Remove published content providers.
12625        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12626            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12627            final boolean always = app.bad || !allowRestart;
12628            if (removeDyingProviderLocked(app, cpr, always) || always) {
12629                // We left the provider in the launching list, need to
12630                // restart it.
12631                restart = true;
12632            }
12633
12634            cpr.provider = null;
12635            cpr.proc = null;
12636        }
12637        app.pubProviders.clear();
12638
12639        // Take care of any launching providers waiting for this process.
12640        if (checkAppInLaunchingProvidersLocked(app, false)) {
12641            restart = true;
12642        }
12643
12644        // Unregister from connected content providers.
12645        if (!app.conProviders.isEmpty()) {
12646            for (int i=0; i<app.conProviders.size(); i++) {
12647                ContentProviderConnection conn = app.conProviders.get(i);
12648                conn.provider.connections.remove(conn);
12649            }
12650            app.conProviders.clear();
12651        }
12652
12653        // At this point there may be remaining entries in mLaunchingProviders
12654        // where we were the only one waiting, so they are no longer of use.
12655        // Look for these and clean up if found.
12656        // XXX Commented out for now.  Trying to figure out a way to reproduce
12657        // the actual situation to identify what is actually going on.
12658        if (false) {
12659            for (int i=0; i<mLaunchingProviders.size(); i++) {
12660                ContentProviderRecord cpr = (ContentProviderRecord)
12661                        mLaunchingProviders.get(i);
12662                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12663                    synchronized (cpr) {
12664                        cpr.launchingApp = null;
12665                        cpr.notifyAll();
12666                    }
12667                }
12668            }
12669        }
12670
12671        skipCurrentReceiverLocked(app);
12672
12673        // Unregister any receivers.
12674        for (int i=app.receivers.size()-1; i>=0; i--) {
12675            removeReceiverLocked(app.receivers.valueAt(i));
12676        }
12677        app.receivers.clear();
12678
12679        // If the app is undergoing backup, tell the backup manager about it
12680        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12681            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12682                    + mBackupTarget.appInfo + " died during backup");
12683            try {
12684                IBackupManager bm = IBackupManager.Stub.asInterface(
12685                        ServiceManager.getService(Context.BACKUP_SERVICE));
12686                bm.agentDisconnected(app.info.packageName);
12687            } catch (RemoteException e) {
12688                // can't happen; backup manager is local
12689            }
12690        }
12691
12692        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12693            ProcessChangeItem item = mPendingProcessChanges.get(i);
12694            if (item.pid == app.pid) {
12695                mPendingProcessChanges.remove(i);
12696                mAvailProcessChanges.add(item);
12697            }
12698        }
12699        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12700
12701        // If the caller is restarting this app, then leave it in its
12702        // current lists and let the caller take care of it.
12703        if (restarting) {
12704            return;
12705        }
12706
12707        if (!app.persistent || app.isolated) {
12708            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12709                    "Removing non-persistent process during cleanup: " + app);
12710            mProcessNames.remove(app.processName, app.uid);
12711            mIsolatedProcesses.remove(app.uid);
12712            if (mHeavyWeightProcess == app) {
12713                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12714                        mHeavyWeightProcess.userId, 0));
12715                mHeavyWeightProcess = null;
12716            }
12717        } else if (!app.removed) {
12718            // This app is persistent, so we need to keep its record around.
12719            // If it is not already on the pending app list, add it there
12720            // and start a new process for it.
12721            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12722                mPersistentStartingProcesses.add(app);
12723                restart = true;
12724            }
12725        }
12726        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12727                "Clean-up removing on hold: " + app);
12728        mProcessesOnHold.remove(app);
12729
12730        if (app == mHomeProcess) {
12731            mHomeProcess = null;
12732        }
12733        if (app == mPreviousProcess) {
12734            mPreviousProcess = null;
12735        }
12736
12737        if (restart && !app.isolated) {
12738            // We have components that still need to be running in the
12739            // process, so re-launch it.
12740            mProcessNames.put(app.processName, app.uid, app);
12741            startProcessLocked(app, "restart", app.processName);
12742        } else if (app.pid > 0 && app.pid != MY_PID) {
12743            // Goodbye!
12744            boolean removed;
12745            synchronized (mPidsSelfLocked) {
12746                mPidsSelfLocked.remove(app.pid);
12747                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12748            }
12749            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12750                    app.processName, app.info.uid);
12751            if (app.isolated) {
12752                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12753            }
12754            app.setPid(0);
12755        }
12756    }
12757
12758    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12759        // Look through the content providers we are waiting to have launched,
12760        // and if any run in this process then either schedule a restart of
12761        // the process or kill the client waiting for it if this process has
12762        // gone bad.
12763        int NL = mLaunchingProviders.size();
12764        boolean restart = false;
12765        for (int i=0; i<NL; i++) {
12766            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12767            if (cpr.launchingApp == app) {
12768                if (!alwaysBad && !app.bad) {
12769                    restart = true;
12770                } else {
12771                    removeDyingProviderLocked(app, cpr, true);
12772                    // cpr should have been removed from mLaunchingProviders
12773                    NL = mLaunchingProviders.size();
12774                    i--;
12775                }
12776            }
12777        }
12778        return restart;
12779    }
12780
12781    // =========================================================
12782    // SERVICES
12783    // =========================================================
12784
12785    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12786            int flags) {
12787        enforceNotIsolatedCaller("getServices");
12788        synchronized (this) {
12789            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12790        }
12791    }
12792
12793    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12794        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12795        synchronized (this) {
12796            return mServices.getRunningServiceControlPanelLocked(name);
12797        }
12798    }
12799
12800    public ComponentName startService(IApplicationThread caller, Intent service,
12801            String resolvedType, int userId) {
12802        enforceNotIsolatedCaller("startService");
12803        // Refuse possible leaked file descriptors
12804        if (service != null && service.hasFileDescriptors() == true) {
12805            throw new IllegalArgumentException("File descriptors passed in Intent");
12806        }
12807
12808        if (DEBUG_SERVICE)
12809            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12810        synchronized(this) {
12811            final int callingPid = Binder.getCallingPid();
12812            final int callingUid = Binder.getCallingUid();
12813            final long origId = Binder.clearCallingIdentity();
12814            ComponentName res = mServices.startServiceLocked(caller, service,
12815                    resolvedType, callingPid, callingUid, userId);
12816            Binder.restoreCallingIdentity(origId);
12817            return res;
12818        }
12819    }
12820
12821    ComponentName startServiceInPackage(int uid,
12822            Intent service, String resolvedType, int userId) {
12823        synchronized(this) {
12824            if (DEBUG_SERVICE)
12825                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12826            final long origId = Binder.clearCallingIdentity();
12827            ComponentName res = mServices.startServiceLocked(null, service,
12828                    resolvedType, -1, uid, userId);
12829            Binder.restoreCallingIdentity(origId);
12830            return res;
12831        }
12832    }
12833
12834    public int stopService(IApplicationThread caller, Intent service,
12835            String resolvedType, int userId) {
12836        enforceNotIsolatedCaller("stopService");
12837        // Refuse possible leaked file descriptors
12838        if (service != null && service.hasFileDescriptors() == true) {
12839            throw new IllegalArgumentException("File descriptors passed in Intent");
12840        }
12841
12842        synchronized(this) {
12843            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12844        }
12845    }
12846
12847    public IBinder peekService(Intent service, String resolvedType) {
12848        enforceNotIsolatedCaller("peekService");
12849        // Refuse possible leaked file descriptors
12850        if (service != null && service.hasFileDescriptors() == true) {
12851            throw new IllegalArgumentException("File descriptors passed in Intent");
12852        }
12853        synchronized(this) {
12854            return mServices.peekServiceLocked(service, resolvedType);
12855        }
12856    }
12857
12858    public boolean stopServiceToken(ComponentName className, IBinder token,
12859            int startId) {
12860        synchronized(this) {
12861            return mServices.stopServiceTokenLocked(className, token, startId);
12862        }
12863    }
12864
12865    public void setServiceForeground(ComponentName className, IBinder token,
12866            int id, Notification notification, boolean removeNotification) {
12867        synchronized(this) {
12868            mServices.setServiceForegroundLocked(className, token, id, notification,
12869                    removeNotification);
12870        }
12871    }
12872
12873    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12874            boolean requireFull, String name, String callerPackage) {
12875        final int callingUserId = UserHandle.getUserId(callingUid);
12876        if (callingUserId != userId) {
12877            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12878                if ((requireFull || checkComponentPermission(
12879                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12880                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12881                        && checkComponentPermission(
12882                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12883                                callingPid, callingUid, -1, true)
12884                                != PackageManager.PERMISSION_GRANTED) {
12885                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12886                        // In this case, they would like to just execute as their
12887                        // owner user instead of failing.
12888                        userId = callingUserId;
12889                    } else {
12890                        StringBuilder builder = new StringBuilder(128);
12891                        builder.append("Permission Denial: ");
12892                        builder.append(name);
12893                        if (callerPackage != null) {
12894                            builder.append(" from ");
12895                            builder.append(callerPackage);
12896                        }
12897                        builder.append(" asks to run as user ");
12898                        builder.append(userId);
12899                        builder.append(" but is calling from user ");
12900                        builder.append(UserHandle.getUserId(callingUid));
12901                        builder.append("; this requires ");
12902                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12903                        if (!requireFull) {
12904                            builder.append(" or ");
12905                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12906                        }
12907                        String msg = builder.toString();
12908                        Slog.w(TAG, msg);
12909                        throw new SecurityException(msg);
12910                    }
12911                }
12912            }
12913            if (userId == UserHandle.USER_CURRENT
12914                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12915                // Note that we may be accessing this outside of a lock...
12916                // shouldn't be a big deal, if this is being called outside
12917                // of a locked context there is intrinsically a race with
12918                // the value the caller will receive and someone else changing it.
12919                userId = mCurrentUserId;
12920            }
12921            if (!allowAll && userId < 0) {
12922                throw new IllegalArgumentException(
12923                        "Call does not support special user #" + userId);
12924            }
12925        }
12926        return userId;
12927    }
12928
12929    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12930            String className, int flags) {
12931        boolean result = false;
12932        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12933            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12934                if (ActivityManager.checkUidPermission(
12935                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12936                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12937                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12938                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12939                            + " requests FLAG_SINGLE_USER, but app does not hold "
12940                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12941                    Slog.w(TAG, msg);
12942                    throw new SecurityException(msg);
12943                }
12944                result = true;
12945            }
12946        } else if (componentProcessName == aInfo.packageName) {
12947            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12948        } else if ("system".equals(componentProcessName)) {
12949            result = true;
12950        }
12951        if (DEBUG_MU) {
12952            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12953                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12954        }
12955        return result;
12956    }
12957
12958    public int bindService(IApplicationThread caller, IBinder token,
12959            Intent service, String resolvedType,
12960            IServiceConnection connection, int flags, int userId) {
12961        enforceNotIsolatedCaller("bindService");
12962        // Refuse possible leaked file descriptors
12963        if (service != null && service.hasFileDescriptors() == true) {
12964            throw new IllegalArgumentException("File descriptors passed in Intent");
12965        }
12966
12967        synchronized(this) {
12968            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12969                    connection, flags, userId);
12970        }
12971    }
12972
12973    public boolean unbindService(IServiceConnection connection) {
12974        synchronized (this) {
12975            return mServices.unbindServiceLocked(connection);
12976        }
12977    }
12978
12979    public void publishService(IBinder token, Intent intent, IBinder service) {
12980        // Refuse possible leaked file descriptors
12981        if (intent != null && intent.hasFileDescriptors() == true) {
12982            throw new IllegalArgumentException("File descriptors passed in Intent");
12983        }
12984
12985        synchronized(this) {
12986            if (!(token instanceof ServiceRecord)) {
12987                throw new IllegalArgumentException("Invalid service token");
12988            }
12989            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12990        }
12991    }
12992
12993    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12994        // Refuse possible leaked file descriptors
12995        if (intent != null && intent.hasFileDescriptors() == true) {
12996            throw new IllegalArgumentException("File descriptors passed in Intent");
12997        }
12998
12999        synchronized(this) {
13000            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13001        }
13002    }
13003
13004    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13005        synchronized(this) {
13006            if (!(token instanceof ServiceRecord)) {
13007                throw new IllegalArgumentException("Invalid service token");
13008            }
13009            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13010        }
13011    }
13012
13013    // =========================================================
13014    // BACKUP AND RESTORE
13015    // =========================================================
13016
13017    // Cause the target app to be launched if necessary and its backup agent
13018    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13019    // activity manager to announce its creation.
13020    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13021        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13022        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13023
13024        synchronized(this) {
13025            // !!! TODO: currently no check here that we're already bound
13026            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13027            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13028            synchronized (stats) {
13029                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13030            }
13031
13032            // Backup agent is now in use, its package can't be stopped.
13033            try {
13034                AppGlobals.getPackageManager().setPackageStoppedState(
13035                        app.packageName, false, UserHandle.getUserId(app.uid));
13036            } catch (RemoteException e) {
13037            } catch (IllegalArgumentException e) {
13038                Slog.w(TAG, "Failed trying to unstop package "
13039                        + app.packageName + ": " + e);
13040            }
13041
13042            BackupRecord r = new BackupRecord(ss, app, backupMode);
13043            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13044                    ? new ComponentName(app.packageName, app.backupAgentName)
13045                    : new ComponentName("android", "FullBackupAgent");
13046            // startProcessLocked() returns existing proc's record if it's already running
13047            ProcessRecord proc = startProcessLocked(app.processName, app,
13048                    false, 0, "backup", hostingName, false, false, false);
13049            if (proc == null) {
13050                Slog.e(TAG, "Unable to start backup agent process " + r);
13051                return false;
13052            }
13053
13054            r.app = proc;
13055            mBackupTarget = r;
13056            mBackupAppName = app.packageName;
13057
13058            // Try not to kill the process during backup
13059            updateOomAdjLocked(proc);
13060
13061            // If the process is already attached, schedule the creation of the backup agent now.
13062            // If it is not yet live, this will be done when it attaches to the framework.
13063            if (proc.thread != null) {
13064                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13065                try {
13066                    proc.thread.scheduleCreateBackupAgent(app,
13067                            compatibilityInfoForPackageLocked(app), backupMode);
13068                } catch (RemoteException e) {
13069                    // Will time out on the backup manager side
13070                }
13071            } else {
13072                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13073            }
13074            // Invariants: at this point, the target app process exists and the application
13075            // is either already running or in the process of coming up.  mBackupTarget and
13076            // mBackupAppName describe the app, so that when it binds back to the AM we
13077            // know that it's scheduled for a backup-agent operation.
13078        }
13079
13080        return true;
13081    }
13082
13083    @Override
13084    public void clearPendingBackup() {
13085        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13086        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13087
13088        synchronized (this) {
13089            mBackupTarget = null;
13090            mBackupAppName = null;
13091        }
13092    }
13093
13094    // A backup agent has just come up
13095    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13096        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13097                + " = " + agent);
13098
13099        synchronized(this) {
13100            if (!agentPackageName.equals(mBackupAppName)) {
13101                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13102                return;
13103            }
13104        }
13105
13106        long oldIdent = Binder.clearCallingIdentity();
13107        try {
13108            IBackupManager bm = IBackupManager.Stub.asInterface(
13109                    ServiceManager.getService(Context.BACKUP_SERVICE));
13110            bm.agentConnected(agentPackageName, agent);
13111        } catch (RemoteException e) {
13112            // can't happen; the backup manager service is local
13113        } catch (Exception e) {
13114            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13115            e.printStackTrace();
13116        } finally {
13117            Binder.restoreCallingIdentity(oldIdent);
13118        }
13119    }
13120
13121    // done with this agent
13122    public void unbindBackupAgent(ApplicationInfo appInfo) {
13123        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13124        if (appInfo == null) {
13125            Slog.w(TAG, "unbind backup agent for null app");
13126            return;
13127        }
13128
13129        synchronized(this) {
13130            try {
13131                if (mBackupAppName == null) {
13132                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13133                    return;
13134                }
13135
13136                if (!mBackupAppName.equals(appInfo.packageName)) {
13137                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13138                    return;
13139                }
13140
13141                // Not backing this app up any more; reset its OOM adjustment
13142                final ProcessRecord proc = mBackupTarget.app;
13143                updateOomAdjLocked(proc);
13144
13145                // If the app crashed during backup, 'thread' will be null here
13146                if (proc.thread != null) {
13147                    try {
13148                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13149                                compatibilityInfoForPackageLocked(appInfo));
13150                    } catch (Exception e) {
13151                        Slog.e(TAG, "Exception when unbinding backup agent:");
13152                        e.printStackTrace();
13153                    }
13154                }
13155            } finally {
13156                mBackupTarget = null;
13157                mBackupAppName = null;
13158            }
13159        }
13160    }
13161    // =========================================================
13162    // BROADCASTS
13163    // =========================================================
13164
13165    private final List getStickiesLocked(String action, IntentFilter filter,
13166            List cur, int userId) {
13167        final ContentResolver resolver = mContext.getContentResolver();
13168        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13169        if (stickies == null) {
13170            return cur;
13171        }
13172        final ArrayList<Intent> list = stickies.get(action);
13173        if (list == null) {
13174            return cur;
13175        }
13176        int N = list.size();
13177        for (int i=0; i<N; i++) {
13178            Intent intent = list.get(i);
13179            if (filter.match(resolver, intent, true, TAG) >= 0) {
13180                if (cur == null) {
13181                    cur = new ArrayList<Intent>();
13182                }
13183                cur.add(intent);
13184            }
13185        }
13186        return cur;
13187    }
13188
13189    boolean isPendingBroadcastProcessLocked(int pid) {
13190        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13191                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13192    }
13193
13194    void skipPendingBroadcastLocked(int pid) {
13195            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13196            for (BroadcastQueue queue : mBroadcastQueues) {
13197                queue.skipPendingBroadcastLocked(pid);
13198            }
13199    }
13200
13201    // The app just attached; send any pending broadcasts that it should receive
13202    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13203        boolean didSomething = false;
13204        for (BroadcastQueue queue : mBroadcastQueues) {
13205            didSomething |= queue.sendPendingBroadcastsLocked(app);
13206        }
13207        return didSomething;
13208    }
13209
13210    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13211            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13212        enforceNotIsolatedCaller("registerReceiver");
13213        int callingUid;
13214        int callingPid;
13215        synchronized(this) {
13216            ProcessRecord callerApp = null;
13217            if (caller != null) {
13218                callerApp = getRecordForAppLocked(caller);
13219                if (callerApp == null) {
13220                    throw new SecurityException(
13221                            "Unable to find app for caller " + caller
13222                            + " (pid=" + Binder.getCallingPid()
13223                            + ") when registering receiver " + receiver);
13224                }
13225                if (callerApp.info.uid != Process.SYSTEM_UID &&
13226                        !callerApp.pkgList.containsKey(callerPackage) &&
13227                        !"android".equals(callerPackage)) {
13228                    throw new SecurityException("Given caller package " + callerPackage
13229                            + " is not running in process " + callerApp);
13230                }
13231                callingUid = callerApp.info.uid;
13232                callingPid = callerApp.pid;
13233            } else {
13234                callerPackage = null;
13235                callingUid = Binder.getCallingUid();
13236                callingPid = Binder.getCallingPid();
13237            }
13238
13239            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13240                    true, true, "registerReceiver", callerPackage);
13241
13242            List allSticky = null;
13243
13244            // Look for any matching sticky broadcasts...
13245            Iterator actions = filter.actionsIterator();
13246            if (actions != null) {
13247                while (actions.hasNext()) {
13248                    String action = (String)actions.next();
13249                    allSticky = getStickiesLocked(action, filter, allSticky,
13250                            UserHandle.USER_ALL);
13251                    allSticky = getStickiesLocked(action, filter, allSticky,
13252                            UserHandle.getUserId(callingUid));
13253                }
13254            } else {
13255                allSticky = getStickiesLocked(null, filter, allSticky,
13256                        UserHandle.USER_ALL);
13257                allSticky = getStickiesLocked(null, filter, allSticky,
13258                        UserHandle.getUserId(callingUid));
13259            }
13260
13261            // The first sticky in the list is returned directly back to
13262            // the client.
13263            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13264
13265            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13266                    + ": " + sticky);
13267
13268            if (receiver == null) {
13269                return sticky;
13270            }
13271
13272            ReceiverList rl
13273                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13274            if (rl == null) {
13275                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13276                        userId, receiver);
13277                if (rl.app != null) {
13278                    rl.app.receivers.add(rl);
13279                } else {
13280                    try {
13281                        receiver.asBinder().linkToDeath(rl, 0);
13282                    } catch (RemoteException e) {
13283                        return sticky;
13284                    }
13285                    rl.linkedToDeath = true;
13286                }
13287                mRegisteredReceivers.put(receiver.asBinder(), rl);
13288            } else if (rl.uid != callingUid) {
13289                throw new IllegalArgumentException(
13290                        "Receiver requested to register for uid " + callingUid
13291                        + " was previously registered for uid " + rl.uid);
13292            } else if (rl.pid != callingPid) {
13293                throw new IllegalArgumentException(
13294                        "Receiver requested to register for pid " + callingPid
13295                        + " was previously registered for pid " + rl.pid);
13296            } else if (rl.userId != userId) {
13297                throw new IllegalArgumentException(
13298                        "Receiver requested to register for user " + userId
13299                        + " was previously registered for user " + rl.userId);
13300            }
13301            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13302                    permission, callingUid, userId);
13303            rl.add(bf);
13304            if (!bf.debugCheck()) {
13305                Slog.w(TAG, "==> For Dynamic broadast");
13306            }
13307            mReceiverResolver.addFilter(bf);
13308
13309            // Enqueue broadcasts for all existing stickies that match
13310            // this filter.
13311            if (allSticky != null) {
13312                ArrayList receivers = new ArrayList();
13313                receivers.add(bf);
13314
13315                int N = allSticky.size();
13316                for (int i=0; i<N; i++) {
13317                    Intent intent = (Intent)allSticky.get(i);
13318                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13319                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13320                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13321                            null, null, false, true, true, -1);
13322                    queue.enqueueParallelBroadcastLocked(r);
13323                    queue.scheduleBroadcastsLocked();
13324                }
13325            }
13326
13327            return sticky;
13328        }
13329    }
13330
13331    public void unregisterReceiver(IIntentReceiver receiver) {
13332        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13333
13334        final long origId = Binder.clearCallingIdentity();
13335        try {
13336            boolean doTrim = false;
13337
13338            synchronized(this) {
13339                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13340                if (rl != null) {
13341                    if (rl.curBroadcast != null) {
13342                        BroadcastRecord r = rl.curBroadcast;
13343                        final boolean doNext = finishReceiverLocked(
13344                                receiver.asBinder(), r.resultCode, r.resultData,
13345                                r.resultExtras, r.resultAbort);
13346                        if (doNext) {
13347                            doTrim = true;
13348                            r.queue.processNextBroadcast(false);
13349                        }
13350                    }
13351
13352                    if (rl.app != null) {
13353                        rl.app.receivers.remove(rl);
13354                    }
13355                    removeReceiverLocked(rl);
13356                    if (rl.linkedToDeath) {
13357                        rl.linkedToDeath = false;
13358                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13359                    }
13360                }
13361            }
13362
13363            // If we actually concluded any broadcasts, we might now be able
13364            // to trim the recipients' apps from our working set
13365            if (doTrim) {
13366                trimApplications();
13367                return;
13368            }
13369
13370        } finally {
13371            Binder.restoreCallingIdentity(origId);
13372        }
13373    }
13374
13375    void removeReceiverLocked(ReceiverList rl) {
13376        mRegisteredReceivers.remove(rl.receiver.asBinder());
13377        int N = rl.size();
13378        for (int i=0; i<N; i++) {
13379            mReceiverResolver.removeFilter(rl.get(i));
13380        }
13381    }
13382
13383    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13384        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13385            ProcessRecord r = mLruProcesses.get(i);
13386            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13387                try {
13388                    r.thread.dispatchPackageBroadcast(cmd, packages);
13389                } catch (RemoteException ex) {
13390                }
13391            }
13392        }
13393    }
13394
13395    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13396            int[] users) {
13397        List<ResolveInfo> receivers = null;
13398        try {
13399            HashSet<ComponentName> singleUserReceivers = null;
13400            boolean scannedFirstReceivers = false;
13401            for (int user : users) {
13402                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13403                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13404                if (user != 0 && newReceivers != null) {
13405                    // If this is not the primary user, we need to check for
13406                    // any receivers that should be filtered out.
13407                    for (int i=0; i<newReceivers.size(); i++) {
13408                        ResolveInfo ri = newReceivers.get(i);
13409                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13410                            newReceivers.remove(i);
13411                            i--;
13412                        }
13413                    }
13414                }
13415                if (newReceivers != null && newReceivers.size() == 0) {
13416                    newReceivers = null;
13417                }
13418                if (receivers == null) {
13419                    receivers = newReceivers;
13420                } else if (newReceivers != null) {
13421                    // We need to concatenate the additional receivers
13422                    // found with what we have do far.  This would be easy,
13423                    // but we also need to de-dup any receivers that are
13424                    // singleUser.
13425                    if (!scannedFirstReceivers) {
13426                        // Collect any single user receivers we had already retrieved.
13427                        scannedFirstReceivers = true;
13428                        for (int i=0; i<receivers.size(); i++) {
13429                            ResolveInfo ri = receivers.get(i);
13430                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13431                                ComponentName cn = new ComponentName(
13432                                        ri.activityInfo.packageName, ri.activityInfo.name);
13433                                if (singleUserReceivers == null) {
13434                                    singleUserReceivers = new HashSet<ComponentName>();
13435                                }
13436                                singleUserReceivers.add(cn);
13437                            }
13438                        }
13439                    }
13440                    // Add the new results to the existing results, tracking
13441                    // and de-dupping single user receivers.
13442                    for (int i=0; i<newReceivers.size(); i++) {
13443                        ResolveInfo ri = newReceivers.get(i);
13444                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13445                            ComponentName cn = new ComponentName(
13446                                    ri.activityInfo.packageName, ri.activityInfo.name);
13447                            if (singleUserReceivers == null) {
13448                                singleUserReceivers = new HashSet<ComponentName>();
13449                            }
13450                            if (!singleUserReceivers.contains(cn)) {
13451                                singleUserReceivers.add(cn);
13452                                receivers.add(ri);
13453                            }
13454                        } else {
13455                            receivers.add(ri);
13456                        }
13457                    }
13458                }
13459            }
13460        } catch (RemoteException ex) {
13461            // pm is in same process, this will never happen.
13462        }
13463        return receivers;
13464    }
13465
13466    private final int broadcastIntentLocked(ProcessRecord callerApp,
13467            String callerPackage, Intent intent, String resolvedType,
13468            IIntentReceiver resultTo, int resultCode, String resultData,
13469            Bundle map, String requiredPermission, int appOp,
13470            boolean ordered, boolean sticky, int callingPid, int callingUid,
13471            int userId) {
13472        intent = new Intent(intent);
13473
13474        // By default broadcasts do not go to stopped apps.
13475        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13476
13477        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13478            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13479            + " ordered=" + ordered + " userid=" + userId);
13480        if ((resultTo != null) && !ordered) {
13481            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13482        }
13483
13484        userId = handleIncomingUser(callingPid, callingUid, userId,
13485                true, false, "broadcast", callerPackage);
13486
13487        // Make sure that the user who is receiving this broadcast is started.
13488        // If not, we will just skip it.
13489        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13490            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13491                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13492                Slog.w(TAG, "Skipping broadcast of " + intent
13493                        + ": user " + userId + " is stopped");
13494                return ActivityManager.BROADCAST_SUCCESS;
13495            }
13496        }
13497
13498        /*
13499         * Prevent non-system code (defined here to be non-persistent
13500         * processes) from sending protected broadcasts.
13501         */
13502        int callingAppId = UserHandle.getAppId(callingUid);
13503        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13504            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13505            callingUid == 0) {
13506            // Always okay.
13507        } else if (callerApp == null || !callerApp.persistent) {
13508            try {
13509                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13510                        intent.getAction())) {
13511                    String msg = "Permission Denial: not allowed to send broadcast "
13512                            + intent.getAction() + " from pid="
13513                            + callingPid + ", uid=" + callingUid;
13514                    Slog.w(TAG, msg);
13515                    throw new SecurityException(msg);
13516                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13517                    // Special case for compatibility: we don't want apps to send this,
13518                    // but historically it has not been protected and apps may be using it
13519                    // to poke their own app widget.  So, instead of making it protected,
13520                    // just limit it to the caller.
13521                    if (callerApp == null) {
13522                        String msg = "Permission Denial: not allowed to send broadcast "
13523                                + intent.getAction() + " from unknown caller.";
13524                        Slog.w(TAG, msg);
13525                        throw new SecurityException(msg);
13526                    } else if (intent.getComponent() != null) {
13527                        // They are good enough to send to an explicit component...  verify
13528                        // it is being sent to the calling app.
13529                        if (!intent.getComponent().getPackageName().equals(
13530                                callerApp.info.packageName)) {
13531                            String msg = "Permission Denial: not allowed to send broadcast "
13532                                    + intent.getAction() + " to "
13533                                    + intent.getComponent().getPackageName() + " from "
13534                                    + callerApp.info.packageName;
13535                            Slog.w(TAG, msg);
13536                            throw new SecurityException(msg);
13537                        }
13538                    } else {
13539                        // Limit broadcast to their own package.
13540                        intent.setPackage(callerApp.info.packageName);
13541                    }
13542                }
13543            } catch (RemoteException e) {
13544                Slog.w(TAG, "Remote exception", e);
13545                return ActivityManager.BROADCAST_SUCCESS;
13546            }
13547        }
13548
13549        // Handle special intents: if this broadcast is from the package
13550        // manager about a package being removed, we need to remove all of
13551        // its activities from the history stack.
13552        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13553                intent.getAction());
13554        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13555                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13556                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13557                || uidRemoved) {
13558            if (checkComponentPermission(
13559                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13560                    callingPid, callingUid, -1, true)
13561                    == PackageManager.PERMISSION_GRANTED) {
13562                if (uidRemoved) {
13563                    final Bundle intentExtras = intent.getExtras();
13564                    final int uid = intentExtras != null
13565                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13566                    if (uid >= 0) {
13567                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13568                        synchronized (bs) {
13569                            bs.removeUidStatsLocked(uid);
13570                        }
13571                        mAppOpsService.uidRemoved(uid);
13572                    }
13573                } else {
13574                    // If resources are unavailable just force stop all
13575                    // those packages and flush the attribute cache as well.
13576                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13577                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13578                        if (list != null && (list.length > 0)) {
13579                            for (String pkg : list) {
13580                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13581                                        "storage unmount");
13582                            }
13583                            sendPackageBroadcastLocked(
13584                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13585                        }
13586                    } else {
13587                        Uri data = intent.getData();
13588                        String ssp;
13589                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13590                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13591                                    intent.getAction());
13592                            boolean fullUninstall = removed &&
13593                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13594                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13595                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13596                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13597                                        false, fullUninstall, userId,
13598                                        removed ? "pkg removed" : "pkg changed");
13599                            }
13600                            if (removed) {
13601                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13602                                        new String[] {ssp}, userId);
13603                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13604                                    mAppOpsService.packageRemoved(
13605                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13606
13607                                    // Remove all permissions granted from/to this package
13608                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13609                                }
13610                            }
13611                        }
13612                    }
13613                }
13614            } else {
13615                String msg = "Permission Denial: " + intent.getAction()
13616                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13617                        + ", uid=" + callingUid + ")"
13618                        + " requires "
13619                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13620                Slog.w(TAG, msg);
13621                throw new SecurityException(msg);
13622            }
13623
13624        // Special case for adding a package: by default turn on compatibility
13625        // mode.
13626        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13627            Uri data = intent.getData();
13628            String ssp;
13629            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13630                mCompatModePackages.handlePackageAddedLocked(ssp,
13631                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13632            }
13633        }
13634
13635        /*
13636         * If this is the time zone changed action, queue up a message that will reset the timezone
13637         * of all currently running processes. This message will get queued up before the broadcast
13638         * happens.
13639         */
13640        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13641            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13642        }
13643
13644        /*
13645         * If the user set the time, let all running processes know.
13646         */
13647        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13648            final int is24Hour = intent.getBooleanExtra(
13649                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13650            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13651        }
13652
13653        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13654            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13655        }
13656
13657        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13658            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13659            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13660        }
13661
13662        // Add to the sticky list if requested.
13663        if (sticky) {
13664            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13665                    callingPid, callingUid)
13666                    != PackageManager.PERMISSION_GRANTED) {
13667                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13668                        + callingPid + ", uid=" + callingUid
13669                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13670                Slog.w(TAG, msg);
13671                throw new SecurityException(msg);
13672            }
13673            if (requiredPermission != null) {
13674                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13675                        + " and enforce permission " + requiredPermission);
13676                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13677            }
13678            if (intent.getComponent() != null) {
13679                throw new SecurityException(
13680                        "Sticky broadcasts can't target a specific component");
13681            }
13682            // We use userId directly here, since the "all" target is maintained
13683            // as a separate set of sticky broadcasts.
13684            if (userId != UserHandle.USER_ALL) {
13685                // But first, if this is not a broadcast to all users, then
13686                // make sure it doesn't conflict with an existing broadcast to
13687                // all users.
13688                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13689                        UserHandle.USER_ALL);
13690                if (stickies != null) {
13691                    ArrayList<Intent> list = stickies.get(intent.getAction());
13692                    if (list != null) {
13693                        int N = list.size();
13694                        int i;
13695                        for (i=0; i<N; i++) {
13696                            if (intent.filterEquals(list.get(i))) {
13697                                throw new IllegalArgumentException(
13698                                        "Sticky broadcast " + intent + " for user "
13699                                        + userId + " conflicts with existing global broadcast");
13700                            }
13701                        }
13702                    }
13703                }
13704            }
13705            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13706            if (stickies == null) {
13707                stickies = new ArrayMap<String, ArrayList<Intent>>();
13708                mStickyBroadcasts.put(userId, stickies);
13709            }
13710            ArrayList<Intent> list = stickies.get(intent.getAction());
13711            if (list == null) {
13712                list = new ArrayList<Intent>();
13713                stickies.put(intent.getAction(), list);
13714            }
13715            int N = list.size();
13716            int i;
13717            for (i=0; i<N; i++) {
13718                if (intent.filterEquals(list.get(i))) {
13719                    // This sticky already exists, replace it.
13720                    list.set(i, new Intent(intent));
13721                    break;
13722                }
13723            }
13724            if (i >= N) {
13725                list.add(new Intent(intent));
13726            }
13727        }
13728
13729        int[] users;
13730        if (userId == UserHandle.USER_ALL) {
13731            // Caller wants broadcast to go to all started users.
13732            users = mStartedUserArray;
13733        } else {
13734            // Caller wants broadcast to go to one specific user.
13735            users = new int[] {userId};
13736        }
13737
13738        // Figure out who all will receive this broadcast.
13739        List receivers = null;
13740        List<BroadcastFilter> registeredReceivers = null;
13741        // Need to resolve the intent to interested receivers...
13742        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13743                 == 0) {
13744            receivers = collectReceiverComponents(intent, resolvedType, users);
13745        }
13746        if (intent.getComponent() == null) {
13747            registeredReceivers = mReceiverResolver.queryIntent(intent,
13748                    resolvedType, false, userId);
13749        }
13750
13751        final boolean replacePending =
13752                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13753
13754        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13755                + " replacePending=" + replacePending);
13756
13757        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13758        if (!ordered && NR > 0) {
13759            // If we are not serializing this broadcast, then send the
13760            // registered receivers separately so they don't wait for the
13761            // components to be launched.
13762            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13763            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13764                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13765                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13766                    ordered, sticky, false, userId);
13767            if (DEBUG_BROADCAST) Slog.v(
13768                    TAG, "Enqueueing parallel broadcast " + r);
13769            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13770            if (!replaced) {
13771                queue.enqueueParallelBroadcastLocked(r);
13772                queue.scheduleBroadcastsLocked();
13773            }
13774            registeredReceivers = null;
13775            NR = 0;
13776        }
13777
13778        // Merge into one list.
13779        int ir = 0;
13780        if (receivers != null) {
13781            // A special case for PACKAGE_ADDED: do not allow the package
13782            // being added to see this broadcast.  This prevents them from
13783            // using this as a back door to get run as soon as they are
13784            // installed.  Maybe in the future we want to have a special install
13785            // broadcast or such for apps, but we'd like to deliberately make
13786            // this decision.
13787            String skipPackages[] = null;
13788            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13789                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13790                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13791                Uri data = intent.getData();
13792                if (data != null) {
13793                    String pkgName = data.getSchemeSpecificPart();
13794                    if (pkgName != null) {
13795                        skipPackages = new String[] { pkgName };
13796                    }
13797                }
13798            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13799                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13800            }
13801            if (skipPackages != null && (skipPackages.length > 0)) {
13802                for (String skipPackage : skipPackages) {
13803                    if (skipPackage != null) {
13804                        int NT = receivers.size();
13805                        for (int it=0; it<NT; it++) {
13806                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13807                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13808                                receivers.remove(it);
13809                                it--;
13810                                NT--;
13811                            }
13812                        }
13813                    }
13814                }
13815            }
13816
13817            int NT = receivers != null ? receivers.size() : 0;
13818            int it = 0;
13819            ResolveInfo curt = null;
13820            BroadcastFilter curr = null;
13821            while (it < NT && ir < NR) {
13822                if (curt == null) {
13823                    curt = (ResolveInfo)receivers.get(it);
13824                }
13825                if (curr == null) {
13826                    curr = registeredReceivers.get(ir);
13827                }
13828                if (curr.getPriority() >= curt.priority) {
13829                    // Insert this broadcast record into the final list.
13830                    receivers.add(it, curr);
13831                    ir++;
13832                    curr = null;
13833                    it++;
13834                    NT++;
13835                } else {
13836                    // Skip to the next ResolveInfo in the final list.
13837                    it++;
13838                    curt = null;
13839                }
13840            }
13841        }
13842        while (ir < NR) {
13843            if (receivers == null) {
13844                receivers = new ArrayList();
13845            }
13846            receivers.add(registeredReceivers.get(ir));
13847            ir++;
13848        }
13849
13850        if ((receivers != null && receivers.size() > 0)
13851                || resultTo != null) {
13852            BroadcastQueue queue = broadcastQueueForIntent(intent);
13853            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13854                    callerPackage, callingPid, callingUid, resolvedType,
13855                    requiredPermission, appOp, receivers, resultTo, resultCode,
13856                    resultData, map, ordered, sticky, false, userId);
13857            if (DEBUG_BROADCAST) Slog.v(
13858                    TAG, "Enqueueing ordered broadcast " + r
13859                    + ": prev had " + queue.mOrderedBroadcasts.size());
13860            if (DEBUG_BROADCAST) {
13861                int seq = r.intent.getIntExtra("seq", -1);
13862                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13863            }
13864            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13865            if (!replaced) {
13866                queue.enqueueOrderedBroadcastLocked(r);
13867                queue.scheduleBroadcastsLocked();
13868            }
13869        }
13870
13871        return ActivityManager.BROADCAST_SUCCESS;
13872    }
13873
13874    final Intent verifyBroadcastLocked(Intent intent) {
13875        // Refuse possible leaked file descriptors
13876        if (intent != null && intent.hasFileDescriptors() == true) {
13877            throw new IllegalArgumentException("File descriptors passed in Intent");
13878        }
13879
13880        int flags = intent.getFlags();
13881
13882        if (!mProcessesReady) {
13883            // if the caller really truly claims to know what they're doing, go
13884            // ahead and allow the broadcast without launching any receivers
13885            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13886                intent = new Intent(intent);
13887                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13888            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13889                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13890                        + " before boot completion");
13891                throw new IllegalStateException("Cannot broadcast before boot completed");
13892            }
13893        }
13894
13895        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13896            throw new IllegalArgumentException(
13897                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13898        }
13899
13900        return intent;
13901    }
13902
13903    public final int broadcastIntent(IApplicationThread caller,
13904            Intent intent, String resolvedType, IIntentReceiver resultTo,
13905            int resultCode, String resultData, Bundle map,
13906            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13907        enforceNotIsolatedCaller("broadcastIntent");
13908        synchronized(this) {
13909            intent = verifyBroadcastLocked(intent);
13910
13911            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13912            final int callingPid = Binder.getCallingPid();
13913            final int callingUid = Binder.getCallingUid();
13914            final long origId = Binder.clearCallingIdentity();
13915            int res = broadcastIntentLocked(callerApp,
13916                    callerApp != null ? callerApp.info.packageName : null,
13917                    intent, resolvedType, resultTo,
13918                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13919                    callingPid, callingUid, userId);
13920            Binder.restoreCallingIdentity(origId);
13921            return res;
13922        }
13923    }
13924
13925    int broadcastIntentInPackage(String packageName, int uid,
13926            Intent intent, String resolvedType, IIntentReceiver resultTo,
13927            int resultCode, String resultData, Bundle map,
13928            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13929        synchronized(this) {
13930            intent = verifyBroadcastLocked(intent);
13931
13932            final long origId = Binder.clearCallingIdentity();
13933            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13934                    resultTo, resultCode, resultData, map, requiredPermission,
13935                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13936            Binder.restoreCallingIdentity(origId);
13937            return res;
13938        }
13939    }
13940
13941    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13942        // Refuse possible leaked file descriptors
13943        if (intent != null && intent.hasFileDescriptors() == true) {
13944            throw new IllegalArgumentException("File descriptors passed in Intent");
13945        }
13946
13947        userId = handleIncomingUser(Binder.getCallingPid(),
13948                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13949
13950        synchronized(this) {
13951            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13952                    != PackageManager.PERMISSION_GRANTED) {
13953                String msg = "Permission Denial: unbroadcastIntent() from pid="
13954                        + Binder.getCallingPid()
13955                        + ", uid=" + Binder.getCallingUid()
13956                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13957                Slog.w(TAG, msg);
13958                throw new SecurityException(msg);
13959            }
13960            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13961            if (stickies != null) {
13962                ArrayList<Intent> list = stickies.get(intent.getAction());
13963                if (list != null) {
13964                    int N = list.size();
13965                    int i;
13966                    for (i=0; i<N; i++) {
13967                        if (intent.filterEquals(list.get(i))) {
13968                            list.remove(i);
13969                            break;
13970                        }
13971                    }
13972                    if (list.size() <= 0) {
13973                        stickies.remove(intent.getAction());
13974                    }
13975                }
13976                if (stickies.size() <= 0) {
13977                    mStickyBroadcasts.remove(userId);
13978                }
13979            }
13980        }
13981    }
13982
13983    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13984            String resultData, Bundle resultExtras, boolean resultAbort) {
13985        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13986        if (r == null) {
13987            Slog.w(TAG, "finishReceiver called but not found on queue");
13988            return false;
13989        }
13990
13991        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13992    }
13993
13994    void backgroundServicesFinishedLocked(int userId) {
13995        for (BroadcastQueue queue : mBroadcastQueues) {
13996            queue.backgroundServicesFinishedLocked(userId);
13997        }
13998    }
13999
14000    public void finishReceiver(IBinder who, int resultCode, String resultData,
14001            Bundle resultExtras, boolean resultAbort) {
14002        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14003
14004        // Refuse possible leaked file descriptors
14005        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14006            throw new IllegalArgumentException("File descriptors passed in Bundle");
14007        }
14008
14009        final long origId = Binder.clearCallingIdentity();
14010        try {
14011            boolean doNext = false;
14012            BroadcastRecord r;
14013
14014            synchronized(this) {
14015                r = broadcastRecordForReceiverLocked(who);
14016                if (r != null) {
14017                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14018                        resultData, resultExtras, resultAbort, true);
14019                }
14020            }
14021
14022            if (doNext) {
14023                r.queue.processNextBroadcast(false);
14024            }
14025            trimApplications();
14026        } finally {
14027            Binder.restoreCallingIdentity(origId);
14028        }
14029    }
14030
14031    // =========================================================
14032    // INSTRUMENTATION
14033    // =========================================================
14034
14035    public boolean startInstrumentation(ComponentName className,
14036            String profileFile, int flags, Bundle arguments,
14037            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14038            int userId) {
14039        enforceNotIsolatedCaller("startInstrumentation");
14040        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14041                userId, false, true, "startInstrumentation", null);
14042        // Refuse possible leaked file descriptors
14043        if (arguments != null && arguments.hasFileDescriptors()) {
14044            throw new IllegalArgumentException("File descriptors passed in Bundle");
14045        }
14046
14047        synchronized(this) {
14048            InstrumentationInfo ii = null;
14049            ApplicationInfo ai = null;
14050            try {
14051                ii = mContext.getPackageManager().getInstrumentationInfo(
14052                    className, STOCK_PM_FLAGS);
14053                ai = AppGlobals.getPackageManager().getApplicationInfo(
14054                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14055            } catch (PackageManager.NameNotFoundException e) {
14056            } catch (RemoteException e) {
14057            }
14058            if (ii == null) {
14059                reportStartInstrumentationFailure(watcher, className,
14060                        "Unable to find instrumentation info for: " + className);
14061                return false;
14062            }
14063            if (ai == null) {
14064                reportStartInstrumentationFailure(watcher, className,
14065                        "Unable to find instrumentation target package: " + ii.targetPackage);
14066                return false;
14067            }
14068
14069            int match = mContext.getPackageManager().checkSignatures(
14070                    ii.targetPackage, ii.packageName);
14071            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14072                String msg = "Permission Denial: starting instrumentation "
14073                        + className + " from pid="
14074                        + Binder.getCallingPid()
14075                        + ", uid=" + Binder.getCallingPid()
14076                        + " not allowed because package " + ii.packageName
14077                        + " does not have a signature matching the target "
14078                        + ii.targetPackage;
14079                reportStartInstrumentationFailure(watcher, className, msg);
14080                throw new SecurityException(msg);
14081            }
14082
14083            final long origId = Binder.clearCallingIdentity();
14084            // Instrumentation can kill and relaunch even persistent processes
14085            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14086                    "start instr");
14087            ProcessRecord app = addAppLocked(ai, false);
14088            app.instrumentationClass = className;
14089            app.instrumentationInfo = ai;
14090            app.instrumentationProfileFile = profileFile;
14091            app.instrumentationArguments = arguments;
14092            app.instrumentationWatcher = watcher;
14093            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14094            app.instrumentationResultClass = className;
14095            Binder.restoreCallingIdentity(origId);
14096        }
14097
14098        return true;
14099    }
14100
14101    /**
14102     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14103     * error to the logs, but if somebody is watching, send the report there too.  This enables
14104     * the "am" command to report errors with more information.
14105     *
14106     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14107     * @param cn The component name of the instrumentation.
14108     * @param report The error report.
14109     */
14110    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14111            ComponentName cn, String report) {
14112        Slog.w(TAG, report);
14113        try {
14114            if (watcher != null) {
14115                Bundle results = new Bundle();
14116                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14117                results.putString("Error", report);
14118                watcher.instrumentationStatus(cn, -1, results);
14119            }
14120        } catch (RemoteException e) {
14121            Slog.w(TAG, e);
14122        }
14123    }
14124
14125    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14126        if (app.instrumentationWatcher != null) {
14127            try {
14128                // NOTE:  IInstrumentationWatcher *must* be oneway here
14129                app.instrumentationWatcher.instrumentationFinished(
14130                    app.instrumentationClass,
14131                    resultCode,
14132                    results);
14133            } catch (RemoteException e) {
14134            }
14135        }
14136        if (app.instrumentationUiAutomationConnection != null) {
14137            try {
14138                app.instrumentationUiAutomationConnection.shutdown();
14139            } catch (RemoteException re) {
14140                /* ignore */
14141            }
14142            // Only a UiAutomation can set this flag and now that
14143            // it is finished we make sure it is reset to its default.
14144            mUserIsMonkey = false;
14145        }
14146        app.instrumentationWatcher = null;
14147        app.instrumentationUiAutomationConnection = null;
14148        app.instrumentationClass = null;
14149        app.instrumentationInfo = null;
14150        app.instrumentationProfileFile = null;
14151        app.instrumentationArguments = null;
14152
14153        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14154                "finished inst");
14155    }
14156
14157    public void finishInstrumentation(IApplicationThread target,
14158            int resultCode, Bundle results) {
14159        int userId = UserHandle.getCallingUserId();
14160        // Refuse possible leaked file descriptors
14161        if (results != null && results.hasFileDescriptors()) {
14162            throw new IllegalArgumentException("File descriptors passed in Intent");
14163        }
14164
14165        synchronized(this) {
14166            ProcessRecord app = getRecordForAppLocked(target);
14167            if (app == null) {
14168                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14169                return;
14170            }
14171            final long origId = Binder.clearCallingIdentity();
14172            finishInstrumentationLocked(app, resultCode, results);
14173            Binder.restoreCallingIdentity(origId);
14174        }
14175    }
14176
14177    // =========================================================
14178    // CONFIGURATION
14179    // =========================================================
14180
14181    public ConfigurationInfo getDeviceConfigurationInfo() {
14182        ConfigurationInfo config = new ConfigurationInfo();
14183        synchronized (this) {
14184            config.reqTouchScreen = mConfiguration.touchscreen;
14185            config.reqKeyboardType = mConfiguration.keyboard;
14186            config.reqNavigation = mConfiguration.navigation;
14187            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14188                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14189                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14190            }
14191            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14192                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14193                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14194            }
14195            config.reqGlEsVersion = GL_ES_VERSION;
14196        }
14197        return config;
14198    }
14199
14200    ActivityStack getFocusedStack() {
14201        return mStackSupervisor.getFocusedStack();
14202    }
14203
14204    public Configuration getConfiguration() {
14205        Configuration ci;
14206        synchronized(this) {
14207            ci = new Configuration(mConfiguration);
14208        }
14209        return ci;
14210    }
14211
14212    public void updatePersistentConfiguration(Configuration values) {
14213        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14214                "updateConfiguration()");
14215        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14216                "updateConfiguration()");
14217        if (values == null) {
14218            throw new NullPointerException("Configuration must not be null");
14219        }
14220
14221        synchronized(this) {
14222            final long origId = Binder.clearCallingIdentity();
14223            updateConfigurationLocked(values, null, true, false);
14224            Binder.restoreCallingIdentity(origId);
14225        }
14226    }
14227
14228    public void updateConfiguration(Configuration values) {
14229        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14230                "updateConfiguration()");
14231
14232        synchronized(this) {
14233            if (values == null && mWindowManager != null) {
14234                // sentinel: fetch the current configuration from the window manager
14235                values = mWindowManager.computeNewConfiguration();
14236            }
14237
14238            if (mWindowManager != null) {
14239                mProcessList.applyDisplaySize(mWindowManager);
14240            }
14241
14242            final long origId = Binder.clearCallingIdentity();
14243            if (values != null) {
14244                Settings.System.clearConfiguration(values);
14245            }
14246            updateConfigurationLocked(values, null, false, false);
14247            Binder.restoreCallingIdentity(origId);
14248        }
14249    }
14250
14251    /**
14252     * Do either or both things: (1) change the current configuration, and (2)
14253     * make sure the given activity is running with the (now) current
14254     * configuration.  Returns true if the activity has been left running, or
14255     * false if <var>starting</var> is being destroyed to match the new
14256     * configuration.
14257     * @param persistent TODO
14258     */
14259    boolean updateConfigurationLocked(Configuration values,
14260            ActivityRecord starting, boolean persistent, boolean initLocale) {
14261        int changes = 0;
14262
14263        if (values != null) {
14264            Configuration newConfig = new Configuration(mConfiguration);
14265            changes = newConfig.updateFrom(values);
14266            if (changes != 0) {
14267                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14268                    Slog.i(TAG, "Updating configuration to: " + values);
14269                }
14270
14271                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14272
14273                if (values.locale != null && !initLocale) {
14274                    saveLocaleLocked(values.locale,
14275                                     !values.locale.equals(mConfiguration.locale),
14276                                     values.userSetLocale);
14277                }
14278
14279                mConfigurationSeq++;
14280                if (mConfigurationSeq <= 0) {
14281                    mConfigurationSeq = 1;
14282                }
14283                newConfig.seq = mConfigurationSeq;
14284                mConfiguration = newConfig;
14285                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14286
14287                final Configuration configCopy = new Configuration(mConfiguration);
14288
14289                // TODO: If our config changes, should we auto dismiss any currently
14290                // showing dialogs?
14291                mShowDialogs = shouldShowDialogs(newConfig);
14292
14293                AttributeCache ac = AttributeCache.instance();
14294                if (ac != null) {
14295                    ac.updateConfiguration(configCopy);
14296                }
14297
14298                // Make sure all resources in our process are updated
14299                // right now, so that anyone who is going to retrieve
14300                // resource values after we return will be sure to get
14301                // the new ones.  This is especially important during
14302                // boot, where the first config change needs to guarantee
14303                // all resources have that config before following boot
14304                // code is executed.
14305                mSystemThread.applyConfigurationToResources(configCopy);
14306
14307                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14308                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14309                    msg.obj = new Configuration(configCopy);
14310                    mHandler.sendMessage(msg);
14311                }
14312
14313                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14314                    ProcessRecord app = mLruProcesses.get(i);
14315                    try {
14316                        if (app.thread != null) {
14317                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14318                                    + app.processName + " new config " + mConfiguration);
14319                            app.thread.scheduleConfigurationChanged(configCopy);
14320                        }
14321                    } catch (Exception e) {
14322                    }
14323                }
14324                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14325                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14326                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14327                        | Intent.FLAG_RECEIVER_FOREGROUND);
14328                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14329                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14330                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14331                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14332                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14333                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14334                    broadcastIntentLocked(null, null, intent,
14335                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14336                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14337                }
14338            }
14339        }
14340
14341        boolean kept = true;
14342        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14343        // mainStack is null during startup.
14344        if (mainStack != null) {
14345            if (changes != 0 && starting == null) {
14346                // If the configuration changed, and the caller is not already
14347                // in the process of starting an activity, then find the top
14348                // activity to check if its configuration needs to change.
14349                starting = mainStack.topRunningActivityLocked(null);
14350            }
14351
14352            if (starting != null) {
14353                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14354                // And we need to make sure at this point that all other activities
14355                // are made visible with the correct configuration.
14356                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14357            }
14358        }
14359
14360        if (values != null && mWindowManager != null) {
14361            mWindowManager.setNewConfiguration(mConfiguration);
14362        }
14363
14364        return kept;
14365    }
14366
14367    /**
14368     * Decide based on the configuration whether we should shouw the ANR,
14369     * crash, etc dialogs.  The idea is that if there is no affordnace to
14370     * press the on-screen buttons, we shouldn't show the dialog.
14371     *
14372     * A thought: SystemUI might also want to get told about this, the Power
14373     * dialog / global actions also might want different behaviors.
14374     */
14375    private static final boolean shouldShowDialogs(Configuration config) {
14376        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14377                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14378    }
14379
14380    /**
14381     * Save the locale.  You must be inside a synchronized (this) block.
14382     */
14383    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14384        if(isDiff) {
14385            SystemProperties.set("user.language", l.getLanguage());
14386            SystemProperties.set("user.region", l.getCountry());
14387        }
14388
14389        if(isPersist) {
14390            SystemProperties.set("persist.sys.language", l.getLanguage());
14391            SystemProperties.set("persist.sys.country", l.getCountry());
14392            SystemProperties.set("persist.sys.localevar", l.getVariant());
14393        }
14394    }
14395
14396    @Override
14397    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14398        ActivityRecord srec = ActivityRecord.forToken(token);
14399        return srec != null && srec.task.affinity != null &&
14400                srec.task.affinity.equals(destAffinity);
14401    }
14402
14403    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14404            Intent resultData) {
14405
14406        synchronized (this) {
14407            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14408            if (stack != null) {
14409                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14410            }
14411            return false;
14412        }
14413    }
14414
14415    public int getLaunchedFromUid(IBinder activityToken) {
14416        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14417        if (srec == null) {
14418            return -1;
14419        }
14420        return srec.launchedFromUid;
14421    }
14422
14423    public String getLaunchedFromPackage(IBinder activityToken) {
14424        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14425        if (srec == null) {
14426            return null;
14427        }
14428        return srec.launchedFromPackage;
14429    }
14430
14431    // =========================================================
14432    // LIFETIME MANAGEMENT
14433    // =========================================================
14434
14435    // Returns which broadcast queue the app is the current [or imminent] receiver
14436    // on, or 'null' if the app is not an active broadcast recipient.
14437    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14438        BroadcastRecord r = app.curReceiver;
14439        if (r != null) {
14440            return r.queue;
14441        }
14442
14443        // It's not the current receiver, but it might be starting up to become one
14444        synchronized (this) {
14445            for (BroadcastQueue queue : mBroadcastQueues) {
14446                r = queue.mPendingBroadcast;
14447                if (r != null && r.curApp == app) {
14448                    // found it; report which queue it's in
14449                    return queue;
14450                }
14451            }
14452        }
14453
14454        return null;
14455    }
14456
14457    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14458            boolean doingAll, long now) {
14459        if (mAdjSeq == app.adjSeq) {
14460            // This adjustment has already been computed.
14461            return app.curRawAdj;
14462        }
14463
14464        if (app.thread == null) {
14465            app.adjSeq = mAdjSeq;
14466            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14467            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14468            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14469        }
14470
14471        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14472        app.adjSource = null;
14473        app.adjTarget = null;
14474        app.empty = false;
14475        app.cached = false;
14476
14477        final int activitiesSize = app.activities.size();
14478
14479        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14480            // The max adjustment doesn't allow this app to be anything
14481            // below foreground, so it is not worth doing work for it.
14482            app.adjType = "fixed";
14483            app.adjSeq = mAdjSeq;
14484            app.curRawAdj = app.maxAdj;
14485            app.foregroundActivities = false;
14486            app.keeping = true;
14487            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14488            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14489            // System process can do UI, and when they do we want to have
14490            // them trim their memory after the user leaves the UI.  To
14491            // facilitate this, here we need to determine whether or not it
14492            // is currently showing UI.
14493            app.systemNoUi = true;
14494            if (app == TOP_APP) {
14495                app.systemNoUi = false;
14496            } else if (activitiesSize > 0) {
14497                for (int j = 0; j < activitiesSize; j++) {
14498                    final ActivityRecord r = app.activities.get(j);
14499                    if (r.visible) {
14500                        app.systemNoUi = false;
14501                    }
14502                }
14503            }
14504            if (!app.systemNoUi) {
14505                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14506            }
14507            return (app.curAdj=app.maxAdj);
14508        }
14509
14510        app.keeping = false;
14511        app.systemNoUi = false;
14512
14513        // Determine the importance of the process, starting with most
14514        // important to least, and assign an appropriate OOM adjustment.
14515        int adj;
14516        int schedGroup;
14517        int procState;
14518        boolean foregroundActivities = false;
14519        boolean interesting = false;
14520        BroadcastQueue queue;
14521        if (app == TOP_APP) {
14522            // The last app on the list is the foreground app.
14523            adj = ProcessList.FOREGROUND_APP_ADJ;
14524            schedGroup = Process.THREAD_GROUP_DEFAULT;
14525            app.adjType = "top-activity";
14526            foregroundActivities = true;
14527            interesting = true;
14528            procState = ActivityManager.PROCESS_STATE_TOP;
14529        } else if (app.instrumentationClass != null) {
14530            // Don't want to kill running instrumentation.
14531            adj = ProcessList.FOREGROUND_APP_ADJ;
14532            schedGroup = Process.THREAD_GROUP_DEFAULT;
14533            app.adjType = "instrumentation";
14534            interesting = true;
14535            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14536        } else if ((queue = isReceivingBroadcast(app)) != null) {
14537            // An app that is currently receiving a broadcast also
14538            // counts as being in the foreground for OOM killer purposes.
14539            // It's placed in a sched group based on the nature of the
14540            // broadcast as reflected by which queue it's active in.
14541            adj = ProcessList.FOREGROUND_APP_ADJ;
14542            schedGroup = (queue == mFgBroadcastQueue)
14543                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14544            app.adjType = "broadcast";
14545            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14546        } else if (app.executingServices.size() > 0) {
14547            // An app that is currently executing a service callback also
14548            // counts as being in the foreground.
14549            adj = ProcessList.FOREGROUND_APP_ADJ;
14550            schedGroup = app.execServicesFg ?
14551                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14552            app.adjType = "exec-service";
14553            procState = ActivityManager.PROCESS_STATE_SERVICE;
14554            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14555        } else {
14556            // As far as we know the process is empty.  We may change our mind later.
14557            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14558            // At this point we don't actually know the adjustment.  Use the cached adj
14559            // value that the caller wants us to.
14560            adj = cachedAdj;
14561            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14562            app.cached = true;
14563            app.empty = true;
14564            app.adjType = "cch-empty";
14565        }
14566
14567        // Examine all activities if not already foreground.
14568        if (!foregroundActivities && activitiesSize > 0) {
14569            for (int j = 0; j < activitiesSize; j++) {
14570                final ActivityRecord r = app.activities.get(j);
14571                if (r.app != app) {
14572                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14573                            + app + "?!?");
14574                    continue;
14575                }
14576                if (r.visible) {
14577                    // App has a visible activity; only upgrade adjustment.
14578                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14579                        adj = ProcessList.VISIBLE_APP_ADJ;
14580                        app.adjType = "visible";
14581                    }
14582                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14583                        procState = ActivityManager.PROCESS_STATE_TOP;
14584                    }
14585                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14586                    app.cached = false;
14587                    app.empty = false;
14588                    foregroundActivities = true;
14589                    break;
14590                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14591                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14592                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14593                        app.adjType = "pausing";
14594                    }
14595                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14596                        procState = ActivityManager.PROCESS_STATE_TOP;
14597                    }
14598                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14599                    app.cached = false;
14600                    app.empty = false;
14601                    foregroundActivities = true;
14602                } else if (r.state == ActivityState.STOPPING) {
14603                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14604                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14605                        app.adjType = "stopping";
14606                    }
14607                    // For the process state, we will at this point consider the
14608                    // process to be cached.  It will be cached either as an activity
14609                    // or empty depending on whether the activity is finishing.  We do
14610                    // this so that we can treat the process as cached for purposes of
14611                    // memory trimming (determing current memory level, trim command to
14612                    // send to process) since there can be an arbitrary number of stopping
14613                    // processes and they should soon all go into the cached state.
14614                    if (!r.finishing) {
14615                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14616                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14617                        }
14618                    }
14619                    app.cached = false;
14620                    app.empty = false;
14621                    foregroundActivities = true;
14622                } else {
14623                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14624                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14625                        app.adjType = "cch-act";
14626                    }
14627                }
14628            }
14629        }
14630
14631        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14632            if (app.foregroundServices) {
14633                // The user is aware of this app, so make it visible.
14634                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14635                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14636                app.cached = false;
14637                app.adjType = "fg-service";
14638                schedGroup = Process.THREAD_GROUP_DEFAULT;
14639            } else if (app.forcingToForeground != null) {
14640                // The user is aware of this app, so make it visible.
14641                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14642                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14643                app.cached = false;
14644                app.adjType = "force-fg";
14645                app.adjSource = app.forcingToForeground;
14646                schedGroup = Process.THREAD_GROUP_DEFAULT;
14647            }
14648        }
14649
14650        if (app.foregroundServices) {
14651            interesting = true;
14652        }
14653
14654        if (app == mHeavyWeightProcess) {
14655            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14656                // We don't want to kill the current heavy-weight process.
14657                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14658                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14659                app.cached = false;
14660                app.adjType = "heavy";
14661            }
14662            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14663                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14664            }
14665        }
14666
14667        if (app == mHomeProcess) {
14668            if (adj > ProcessList.HOME_APP_ADJ) {
14669                // This process is hosting what we currently consider to be the
14670                // home app, so we don't want to let it go into the background.
14671                adj = ProcessList.HOME_APP_ADJ;
14672                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14673                app.cached = false;
14674                app.adjType = "home";
14675            }
14676            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14677                procState = ActivityManager.PROCESS_STATE_HOME;
14678            }
14679        }
14680
14681        if (app == mPreviousProcess && app.activities.size() > 0) {
14682            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14683                // This was the previous process that showed UI to the user.
14684                // We want to try to keep it around more aggressively, to give
14685                // a good experience around switching between two apps.
14686                adj = ProcessList.PREVIOUS_APP_ADJ;
14687                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14688                app.cached = false;
14689                app.adjType = "previous";
14690            }
14691            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14692                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14693            }
14694        }
14695
14696        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14697                + " reason=" + app.adjType);
14698
14699        // By default, we use the computed adjustment.  It may be changed if
14700        // there are applications dependent on our services or providers, but
14701        // this gives us a baseline and makes sure we don't get into an
14702        // infinite recursion.
14703        app.adjSeq = mAdjSeq;
14704        app.curRawAdj = adj;
14705        app.hasStartedServices = false;
14706
14707        if (mBackupTarget != null && app == mBackupTarget.app) {
14708            // If possible we want to avoid killing apps while they're being backed up
14709            if (adj > ProcessList.BACKUP_APP_ADJ) {
14710                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14711                adj = ProcessList.BACKUP_APP_ADJ;
14712                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14713                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14714                }
14715                app.adjType = "backup";
14716                app.cached = false;
14717            }
14718            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14719                procState = ActivityManager.PROCESS_STATE_BACKUP;
14720            }
14721        }
14722
14723        boolean mayBeTop = false;
14724
14725        for (int is = app.services.size()-1;
14726                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14727                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14728                        || procState > ActivityManager.PROCESS_STATE_TOP);
14729                is--) {
14730            ServiceRecord s = app.services.valueAt(is);
14731            if (s.startRequested) {
14732                app.hasStartedServices = true;
14733                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14734                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14735                }
14736                if (app.hasShownUi && app != mHomeProcess) {
14737                    // If this process has shown some UI, let it immediately
14738                    // go to the LRU list because it may be pretty heavy with
14739                    // UI stuff.  We'll tag it with a label just to help
14740                    // debug and understand what is going on.
14741                    if (adj > ProcessList.SERVICE_ADJ) {
14742                        app.adjType = "cch-started-ui-services";
14743                    }
14744                } else {
14745                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14746                        // This service has seen some activity within
14747                        // recent memory, so we will keep its process ahead
14748                        // of the background processes.
14749                        if (adj > ProcessList.SERVICE_ADJ) {
14750                            adj = ProcessList.SERVICE_ADJ;
14751                            app.adjType = "started-services";
14752                            app.cached = false;
14753                        }
14754                    }
14755                    // If we have let the service slide into the background
14756                    // state, still have some text describing what it is doing
14757                    // even though the service no longer has an impact.
14758                    if (adj > ProcessList.SERVICE_ADJ) {
14759                        app.adjType = "cch-started-services";
14760                    }
14761                }
14762                // Don't kill this process because it is doing work; it
14763                // has said it is doing work.
14764                app.keeping = true;
14765            }
14766            for (int conni = s.connections.size()-1;
14767                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14768                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14769                            || procState > ActivityManager.PROCESS_STATE_TOP);
14770                    conni--) {
14771                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14772                for (int i = 0;
14773                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14774                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14775                                || procState > ActivityManager.PROCESS_STATE_TOP);
14776                        i++) {
14777                    // XXX should compute this based on the max of
14778                    // all connected clients.
14779                    ConnectionRecord cr = clist.get(i);
14780                    if (cr.binding.client == app) {
14781                        // Binding to ourself is not interesting.
14782                        continue;
14783                    }
14784                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14785                        ProcessRecord client = cr.binding.client;
14786                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14787                                TOP_APP, doingAll, now);
14788                        int clientProcState = client.curProcState;
14789                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14790                            // If the other app is cached for any reason, for purposes here
14791                            // we are going to consider it empty.  The specific cached state
14792                            // doesn't propagate except under certain conditions.
14793                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14794                        }
14795                        String adjType = null;
14796                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14797                            // Not doing bind OOM management, so treat
14798                            // this guy more like a started service.
14799                            if (app.hasShownUi && app != mHomeProcess) {
14800                                // If this process has shown some UI, let it immediately
14801                                // go to the LRU list because it may be pretty heavy with
14802                                // UI stuff.  We'll tag it with a label just to help
14803                                // debug and understand what is going on.
14804                                if (adj > clientAdj) {
14805                                    adjType = "cch-bound-ui-services";
14806                                }
14807                                app.cached = false;
14808                                clientAdj = adj;
14809                                clientProcState = procState;
14810                            } else {
14811                                if (now >= (s.lastActivity
14812                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14813                                    // This service has not seen activity within
14814                                    // recent memory, so allow it to drop to the
14815                                    // LRU list if there is no other reason to keep
14816                                    // it around.  We'll also tag it with a label just
14817                                    // to help debug and undertand what is going on.
14818                                    if (adj > clientAdj) {
14819                                        adjType = "cch-bound-services";
14820                                    }
14821                                    clientAdj = adj;
14822                                }
14823                            }
14824                        }
14825                        if (adj > clientAdj) {
14826                            // If this process has recently shown UI, and
14827                            // the process that is binding to it is less
14828                            // important than being visible, then we don't
14829                            // care about the binding as much as we care
14830                            // about letting this process get into the LRU
14831                            // list to be killed and restarted if needed for
14832                            // memory.
14833                            if (app.hasShownUi && app != mHomeProcess
14834                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14835                                adjType = "cch-bound-ui-services";
14836                            } else {
14837                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14838                                        |Context.BIND_IMPORTANT)) != 0) {
14839                                    adj = clientAdj;
14840                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14841                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14842                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14843                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14844                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14845                                    adj = clientAdj;
14846                                } else {
14847                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14848                                        adj = ProcessList.VISIBLE_APP_ADJ;
14849                                    }
14850                                }
14851                                if (!client.cached) {
14852                                    app.cached = false;
14853                                }
14854                                if (client.keeping) {
14855                                    app.keeping = true;
14856                                }
14857                                adjType = "service";
14858                            }
14859                        }
14860                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14861                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14862                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14863                            }
14864                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14865                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14866                                    // Special handling of clients who are in the top state.
14867                                    // We *may* want to consider this process to be in the
14868                                    // top state as well, but only if there is not another
14869                                    // reason for it to be running.  Being on the top is a
14870                                    // special state, meaning you are specifically running
14871                                    // for the current top app.  If the process is already
14872                                    // running in the background for some other reason, it
14873                                    // is more important to continue considering it to be
14874                                    // in the background state.
14875                                    mayBeTop = true;
14876                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14877                                } else {
14878                                    // Special handling for above-top states (persistent
14879                                    // processes).  These should not bring the current process
14880                                    // into the top state, since they are not on top.  Instead
14881                                    // give them the best state after that.
14882                                    clientProcState =
14883                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14884                                }
14885                            }
14886                        } else {
14887                            if (clientProcState <
14888                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14889                                clientProcState =
14890                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14891                            }
14892                        }
14893                        if (procState > clientProcState) {
14894                            procState = clientProcState;
14895                        }
14896                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14897                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14898                            app.pendingUiClean = true;
14899                        }
14900                        if (adjType != null) {
14901                            app.adjType = adjType;
14902                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14903                                    .REASON_SERVICE_IN_USE;
14904                            app.adjSource = cr.binding.client;
14905                            app.adjSourceOom = clientAdj;
14906                            app.adjTarget = s.name;
14907                        }
14908                    }
14909                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14910                        app.treatLikeActivity = true;
14911                    }
14912                    final ActivityRecord a = cr.activity;
14913                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14914                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14915                                (a.visible || a.state == ActivityState.RESUMED
14916                                 || a.state == ActivityState.PAUSING)) {
14917                            adj = ProcessList.FOREGROUND_APP_ADJ;
14918                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14919                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14920                            }
14921                            app.cached = false;
14922                            app.adjType = "service";
14923                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14924                                    .REASON_SERVICE_IN_USE;
14925                            app.adjSource = a;
14926                            app.adjSourceOom = adj;
14927                            app.adjTarget = s.name;
14928                        }
14929                    }
14930                }
14931            }
14932        }
14933
14934        for (int provi = app.pubProviders.size()-1;
14935                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14936                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14937                        || procState > ActivityManager.PROCESS_STATE_TOP);
14938                provi--) {
14939            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14940            for (int i = cpr.connections.size()-1;
14941                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14942                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14943                            || procState > ActivityManager.PROCESS_STATE_TOP);
14944                    i--) {
14945                ContentProviderConnection conn = cpr.connections.get(i);
14946                ProcessRecord client = conn.client;
14947                if (client == app) {
14948                    // Being our own client is not interesting.
14949                    continue;
14950                }
14951                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14952                int clientProcState = client.curProcState;
14953                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14954                    // If the other app is cached for any reason, for purposes here
14955                    // we are going to consider it empty.
14956                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14957                }
14958                if (adj > clientAdj) {
14959                    if (app.hasShownUi && app != mHomeProcess
14960                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14961                        app.adjType = "cch-ui-provider";
14962                    } else {
14963                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14964                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14965                        app.adjType = "provider";
14966                    }
14967                    app.cached &= client.cached;
14968                    app.keeping |= client.keeping;
14969                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14970                            .REASON_PROVIDER_IN_USE;
14971                    app.adjSource = client;
14972                    app.adjSourceOom = clientAdj;
14973                    app.adjTarget = cpr.name;
14974                }
14975                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14976                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14977                        // Special handling of clients who are in the top state.
14978                        // We *may* want to consider this process to be in the
14979                        // top state as well, but only if there is not another
14980                        // reason for it to be running.  Being on the top is a
14981                        // special state, meaning you are specifically running
14982                        // for the current top app.  If the process is already
14983                        // running in the background for some other reason, it
14984                        // is more important to continue considering it to be
14985                        // in the background state.
14986                        mayBeTop = true;
14987                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14988                    } else {
14989                        // Special handling for above-top states (persistent
14990                        // processes).  These should not bring the current process
14991                        // into the top state, since they are not on top.  Instead
14992                        // give them the best state after that.
14993                        clientProcState =
14994                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14995                    }
14996                }
14997                if (procState > clientProcState) {
14998                    procState = clientProcState;
14999                }
15000                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15001                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15002                }
15003            }
15004            // If the provider has external (non-framework) process
15005            // dependencies, ensure that its adjustment is at least
15006            // FOREGROUND_APP_ADJ.
15007            if (cpr.hasExternalProcessHandles()) {
15008                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15009                    adj = ProcessList.FOREGROUND_APP_ADJ;
15010                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15011                    app.cached = false;
15012                    app.keeping = true;
15013                    app.adjType = "provider";
15014                    app.adjTarget = cpr.name;
15015                }
15016                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15017                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15018                }
15019            }
15020        }
15021
15022        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15023            // A client of one of our services or providers is in the top state.  We
15024            // *may* want to be in the top state, but not if we are already running in
15025            // the background for some other reason.  For the decision here, we are going
15026            // to pick out a few specific states that we want to remain in when a client
15027            // is top (states that tend to be longer-term) and otherwise allow it to go
15028            // to the top state.
15029            switch (procState) {
15030                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15031                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15032                case ActivityManager.PROCESS_STATE_SERVICE:
15033                    // These all are longer-term states, so pull them up to the top
15034                    // of the background states, but not all the way to the top state.
15035                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15036                    break;
15037                default:
15038                    // Otherwise, top is a better choice, so take it.
15039                    procState = ActivityManager.PROCESS_STATE_TOP;
15040                    break;
15041            }
15042        }
15043
15044        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15045            if (app.hasClientActivities) {
15046                // This is a cached process, but with client activities.  Mark it so.
15047                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15048                app.adjType = "cch-client-act";
15049            } else if (app.treatLikeActivity) {
15050                // This is a cached process, but somebody wants us to treat it like it has
15051                // an activity, okay!
15052                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15053                app.adjType = "cch-as-act";
15054            }
15055        }
15056
15057        if (adj == ProcessList.SERVICE_ADJ) {
15058            if (doingAll) {
15059                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15060                mNewNumServiceProcs++;
15061                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15062                if (!app.serviceb) {
15063                    // This service isn't far enough down on the LRU list to
15064                    // normally be a B service, but if we are low on RAM and it
15065                    // is large we want to force it down since we would prefer to
15066                    // keep launcher over it.
15067                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15068                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15069                        app.serviceHighRam = true;
15070                        app.serviceb = true;
15071                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15072                    } else {
15073                        mNewNumAServiceProcs++;
15074                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15075                    }
15076                } else {
15077                    app.serviceHighRam = false;
15078                }
15079            }
15080            if (app.serviceb) {
15081                adj = ProcessList.SERVICE_B_ADJ;
15082            }
15083        }
15084
15085        app.curRawAdj = adj;
15086
15087        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15088        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15089        if (adj > app.maxAdj) {
15090            adj = app.maxAdj;
15091            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15092                schedGroup = Process.THREAD_GROUP_DEFAULT;
15093            }
15094        }
15095        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15096            app.keeping = true;
15097        }
15098
15099        // Do final modification to adj.  Everything we do between here and applying
15100        // the final setAdj must be done in this function, because we will also use
15101        // it when computing the final cached adj later.  Note that we don't need to
15102        // worry about this for max adj above, since max adj will always be used to
15103        // keep it out of the cached vaues.
15104        adj = app.modifyRawOomAdj(adj);
15105
15106        app.curProcState = procState;
15107
15108        int importance = app.memImportance;
15109        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15110            app.curAdj = adj;
15111            app.curSchedGroup = schedGroup;
15112            if (!interesting) {
15113                // For this reporting, if there is not something explicitly
15114                // interesting in this process then we will push it to the
15115                // background importance.
15116                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15117            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15118                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15119            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15120                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15121            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15122                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15123            } else if (adj >= ProcessList.SERVICE_ADJ) {
15124                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15125            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15126                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15127            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15128                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15129            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15130                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15131            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15132                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15133            } else {
15134                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15135            }
15136        }
15137
15138        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15139        if (foregroundActivities != app.foregroundActivities) {
15140            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15141        }
15142        if (changes != 0) {
15143            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15144            app.memImportance = importance;
15145            app.foregroundActivities = foregroundActivities;
15146            int i = mPendingProcessChanges.size()-1;
15147            ProcessChangeItem item = null;
15148            while (i >= 0) {
15149                item = mPendingProcessChanges.get(i);
15150                if (item.pid == app.pid) {
15151                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15152                    break;
15153                }
15154                i--;
15155            }
15156            if (i < 0) {
15157                // No existing item in pending changes; need a new one.
15158                final int NA = mAvailProcessChanges.size();
15159                if (NA > 0) {
15160                    item = mAvailProcessChanges.remove(NA-1);
15161                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15162                } else {
15163                    item = new ProcessChangeItem();
15164                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15165                }
15166                item.changes = 0;
15167                item.pid = app.pid;
15168                item.uid = app.info.uid;
15169                if (mPendingProcessChanges.size() == 0) {
15170                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15171                            "*** Enqueueing dispatch processes changed!");
15172                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15173                }
15174                mPendingProcessChanges.add(item);
15175            }
15176            item.changes |= changes;
15177            item.importance = importance;
15178            item.foregroundActivities = foregroundActivities;
15179            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15180                    + Integer.toHexString(System.identityHashCode(item))
15181                    + " " + app.toShortString() + ": changes=" + item.changes
15182                    + " importance=" + item.importance
15183                    + " foreground=" + item.foregroundActivities
15184                    + " type=" + app.adjType + " source=" + app.adjSource
15185                    + " target=" + app.adjTarget);
15186        }
15187
15188        return app.curRawAdj;
15189    }
15190
15191    /**
15192     * Schedule PSS collection of a process.
15193     */
15194    void requestPssLocked(ProcessRecord proc, int procState) {
15195        if (mPendingPssProcesses.contains(proc)) {
15196            return;
15197        }
15198        if (mPendingPssProcesses.size() == 0) {
15199            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15200        }
15201        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15202        proc.pssProcState = procState;
15203        mPendingPssProcesses.add(proc);
15204    }
15205
15206    /**
15207     * Schedule PSS collection of all processes.
15208     */
15209    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15210        if (!always) {
15211            if (now < (mLastFullPssTime +
15212                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15213                return;
15214            }
15215        }
15216        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15217        mLastFullPssTime = now;
15218        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15219        mPendingPssProcesses.clear();
15220        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15221            ProcessRecord app = mLruProcesses.get(i);
15222            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15223                app.pssProcState = app.setProcState;
15224                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15225                        mSleeping, now);
15226                mPendingPssProcesses.add(app);
15227            }
15228        }
15229        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15230    }
15231
15232    /**
15233     * Ask a given process to GC right now.
15234     */
15235    final void performAppGcLocked(ProcessRecord app) {
15236        try {
15237            app.lastRequestedGc = SystemClock.uptimeMillis();
15238            if (app.thread != null) {
15239                if (app.reportLowMemory) {
15240                    app.reportLowMemory = false;
15241                    app.thread.scheduleLowMemory();
15242                } else {
15243                    app.thread.processInBackground();
15244                }
15245            }
15246        } catch (Exception e) {
15247            // whatever.
15248        }
15249    }
15250
15251    /**
15252     * Returns true if things are idle enough to perform GCs.
15253     */
15254    private final boolean canGcNowLocked() {
15255        boolean processingBroadcasts = false;
15256        for (BroadcastQueue q : mBroadcastQueues) {
15257            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15258                processingBroadcasts = true;
15259            }
15260        }
15261        return !processingBroadcasts
15262                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15263    }
15264
15265    /**
15266     * Perform GCs on all processes that are waiting for it, but only
15267     * if things are idle.
15268     */
15269    final void performAppGcsLocked() {
15270        final int N = mProcessesToGc.size();
15271        if (N <= 0) {
15272            return;
15273        }
15274        if (canGcNowLocked()) {
15275            while (mProcessesToGc.size() > 0) {
15276                ProcessRecord proc = mProcessesToGc.remove(0);
15277                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15278                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15279                            <= SystemClock.uptimeMillis()) {
15280                        // To avoid spamming the system, we will GC processes one
15281                        // at a time, waiting a few seconds between each.
15282                        performAppGcLocked(proc);
15283                        scheduleAppGcsLocked();
15284                        return;
15285                    } else {
15286                        // It hasn't been long enough since we last GCed this
15287                        // process...  put it in the list to wait for its time.
15288                        addProcessToGcListLocked(proc);
15289                        break;
15290                    }
15291                }
15292            }
15293
15294            scheduleAppGcsLocked();
15295        }
15296    }
15297
15298    /**
15299     * If all looks good, perform GCs on all processes waiting for them.
15300     */
15301    final void performAppGcsIfAppropriateLocked() {
15302        if (canGcNowLocked()) {
15303            performAppGcsLocked();
15304            return;
15305        }
15306        // Still not idle, wait some more.
15307        scheduleAppGcsLocked();
15308    }
15309
15310    /**
15311     * Schedule the execution of all pending app GCs.
15312     */
15313    final void scheduleAppGcsLocked() {
15314        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15315
15316        if (mProcessesToGc.size() > 0) {
15317            // Schedule a GC for the time to the next process.
15318            ProcessRecord proc = mProcessesToGc.get(0);
15319            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15320
15321            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15322            long now = SystemClock.uptimeMillis();
15323            if (when < (now+GC_TIMEOUT)) {
15324                when = now + GC_TIMEOUT;
15325            }
15326            mHandler.sendMessageAtTime(msg, when);
15327        }
15328    }
15329
15330    /**
15331     * Add a process to the array of processes waiting to be GCed.  Keeps the
15332     * list in sorted order by the last GC time.  The process can't already be
15333     * on the list.
15334     */
15335    final void addProcessToGcListLocked(ProcessRecord proc) {
15336        boolean added = false;
15337        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15338            if (mProcessesToGc.get(i).lastRequestedGc <
15339                    proc.lastRequestedGc) {
15340                added = true;
15341                mProcessesToGc.add(i+1, proc);
15342                break;
15343            }
15344        }
15345        if (!added) {
15346            mProcessesToGc.add(0, proc);
15347        }
15348    }
15349
15350    /**
15351     * Set up to ask a process to GC itself.  This will either do it
15352     * immediately, or put it on the list of processes to gc the next
15353     * time things are idle.
15354     */
15355    final void scheduleAppGcLocked(ProcessRecord app) {
15356        long now = SystemClock.uptimeMillis();
15357        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15358            return;
15359        }
15360        if (!mProcessesToGc.contains(app)) {
15361            addProcessToGcListLocked(app);
15362            scheduleAppGcsLocked();
15363        }
15364    }
15365
15366    final void checkExcessivePowerUsageLocked(boolean doKills) {
15367        updateCpuStatsNow();
15368
15369        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15370        boolean doWakeKills = doKills;
15371        boolean doCpuKills = doKills;
15372        if (mLastPowerCheckRealtime == 0) {
15373            doWakeKills = false;
15374        }
15375        if (mLastPowerCheckUptime == 0) {
15376            doCpuKills = false;
15377        }
15378        if (stats.isScreenOn()) {
15379            doWakeKills = false;
15380        }
15381        final long curRealtime = SystemClock.elapsedRealtime();
15382        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15383        final long curUptime = SystemClock.uptimeMillis();
15384        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15385        mLastPowerCheckRealtime = curRealtime;
15386        mLastPowerCheckUptime = curUptime;
15387        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15388            doWakeKills = false;
15389        }
15390        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15391            doCpuKills = false;
15392        }
15393        int i = mLruProcesses.size();
15394        while (i > 0) {
15395            i--;
15396            ProcessRecord app = mLruProcesses.get(i);
15397            if (!app.keeping) {
15398                long wtime;
15399                synchronized (stats) {
15400                    wtime = stats.getProcessWakeTime(app.info.uid,
15401                            app.pid, curRealtime);
15402                }
15403                long wtimeUsed = wtime - app.lastWakeTime;
15404                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15405                if (DEBUG_POWER) {
15406                    StringBuilder sb = new StringBuilder(128);
15407                    sb.append("Wake for ");
15408                    app.toShortString(sb);
15409                    sb.append(": over ");
15410                    TimeUtils.formatDuration(realtimeSince, sb);
15411                    sb.append(" used ");
15412                    TimeUtils.formatDuration(wtimeUsed, sb);
15413                    sb.append(" (");
15414                    sb.append((wtimeUsed*100)/realtimeSince);
15415                    sb.append("%)");
15416                    Slog.i(TAG, sb.toString());
15417                    sb.setLength(0);
15418                    sb.append("CPU for ");
15419                    app.toShortString(sb);
15420                    sb.append(": over ");
15421                    TimeUtils.formatDuration(uptimeSince, sb);
15422                    sb.append(" used ");
15423                    TimeUtils.formatDuration(cputimeUsed, sb);
15424                    sb.append(" (");
15425                    sb.append((cputimeUsed*100)/uptimeSince);
15426                    sb.append("%)");
15427                    Slog.i(TAG, sb.toString());
15428                }
15429                // If a process has held a wake lock for more
15430                // than 50% of the time during this period,
15431                // that sounds bad.  Kill!
15432                if (doWakeKills && realtimeSince > 0
15433                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15434                    synchronized (stats) {
15435                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15436                                realtimeSince, wtimeUsed);
15437                    }
15438                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15439                            + " during " + realtimeSince);
15440                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15441                } else if (doCpuKills && uptimeSince > 0
15442                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15443                    synchronized (stats) {
15444                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15445                                uptimeSince, cputimeUsed);
15446                    }
15447                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15448                            + " during " + uptimeSince);
15449                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15450                } else {
15451                    app.lastWakeTime = wtime;
15452                    app.lastCpuTime = app.curCpuTime;
15453                }
15454            }
15455        }
15456    }
15457
15458    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15459            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15460        boolean success = true;
15461
15462        if (app.curRawAdj != app.setRawAdj) {
15463            if (wasKeeping && !app.keeping) {
15464                // This app is no longer something we want to keep.  Note
15465                // its current wake lock time to later know to kill it if
15466                // it is not behaving well.
15467                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15468                synchronized (stats) {
15469                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15470                            app.pid, SystemClock.elapsedRealtime());
15471                }
15472                app.lastCpuTime = app.curCpuTime;
15473            }
15474
15475            app.setRawAdj = app.curRawAdj;
15476        }
15477
15478        if (app.curAdj != app.setAdj) {
15479            ProcessList.setOomAdj(app.pid, app.curAdj);
15480            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15481                TAG, "Set " + app.pid + " " + app.processName +
15482                " adj " + app.curAdj + ": " + app.adjType);
15483            app.setAdj = app.curAdj;
15484        }
15485
15486        if (app.setSchedGroup != app.curSchedGroup) {
15487            app.setSchedGroup = app.curSchedGroup;
15488            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15489                    "Setting process group of " + app.processName
15490                    + " to " + app.curSchedGroup);
15491            if (app.waitingToKill != null &&
15492                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15493                killUnneededProcessLocked(app, app.waitingToKill);
15494                success = false;
15495            } else {
15496                if (true) {
15497                    long oldId = Binder.clearCallingIdentity();
15498                    try {
15499                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15500                    } catch (Exception e) {
15501                        Slog.w(TAG, "Failed setting process group of " + app.pid
15502                                + " to " + app.curSchedGroup);
15503                        e.printStackTrace();
15504                    } finally {
15505                        Binder.restoreCallingIdentity(oldId);
15506                    }
15507                } else {
15508                    if (app.thread != null) {
15509                        try {
15510                            app.thread.setSchedulingGroup(app.curSchedGroup);
15511                        } catch (RemoteException e) {
15512                        }
15513                    }
15514                }
15515                Process.setSwappiness(app.pid,
15516                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15517            }
15518        }
15519        if (app.repProcState != app.curProcState) {
15520            app.repProcState = app.curProcState;
15521            if (!reportingProcessState && app.thread != null) {
15522                try {
15523                    if (false) {
15524                        //RuntimeException h = new RuntimeException("here");
15525                        Slog.i(TAG, "Sending new process state " + app.repProcState
15526                                + " to " + app /*, h*/);
15527                    }
15528                    app.thread.setProcessState(app.repProcState);
15529                } catch (RemoteException e) {
15530                }
15531            }
15532        }
15533        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15534                app.setProcState)) {
15535            app.lastStateTime = now;
15536            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15537                    mSleeping, now);
15538            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15539                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15540                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15541                    + (app.nextPssTime-now) + ": " + app);
15542        } else {
15543            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15544                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15545                requestPssLocked(app, app.setProcState);
15546                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15547                        mSleeping, now);
15548            } else if (false && DEBUG_PSS) {
15549                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15550            }
15551        }
15552        if (app.setProcState != app.curProcState) {
15553            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15554                    "Proc state change of " + app.processName
15555                    + " to " + app.curProcState);
15556            app.setProcState = app.curProcState;
15557            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15558                app.notCachedSinceIdle = false;
15559            }
15560            if (!doingAll) {
15561                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15562            } else {
15563                app.procStateChanged = true;
15564            }
15565        }
15566        return success;
15567    }
15568
15569    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15570        if (proc.thread != null && proc.baseProcessTracker != null) {
15571            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15572        }
15573    }
15574
15575    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15576            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15577        if (app.thread == null) {
15578            return false;
15579        }
15580
15581        final boolean wasKeeping = app.keeping;
15582
15583        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15584
15585        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15586                reportingProcessState, now);
15587    }
15588
15589    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15590            boolean oomAdj) {
15591        if (isForeground != proc.foregroundServices) {
15592            proc.foregroundServices = isForeground;
15593            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15594                    proc.info.uid);
15595            if (isForeground) {
15596                if (curProcs == null) {
15597                    curProcs = new ArrayList<ProcessRecord>();
15598                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15599                }
15600                if (!curProcs.contains(proc)) {
15601                    curProcs.add(proc);
15602                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15603                            proc.info.packageName, proc.info.uid);
15604                }
15605            } else {
15606                if (curProcs != null) {
15607                    if (curProcs.remove(proc)) {
15608                        mBatteryStatsService.noteEvent(
15609                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15610                                proc.info.packageName, proc.info.uid);
15611                        if (curProcs.size() <= 0) {
15612                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15613                        }
15614                    }
15615                }
15616            }
15617            if (oomAdj) {
15618                updateOomAdjLocked();
15619            }
15620        }
15621    }
15622
15623    private final ActivityRecord resumedAppLocked() {
15624        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15625        String pkg;
15626        int uid;
15627        if (act != null && !act.sleeping) {
15628            pkg = act.packageName;
15629            uid = act.info.applicationInfo.uid;
15630        } else {
15631            pkg = null;
15632            uid = -1;
15633        }
15634        // Has the UID or resumed package name changed?
15635        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15636                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15637            if (mCurResumedPackage != null) {
15638                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15639                        mCurResumedPackage, mCurResumedUid);
15640            }
15641            mCurResumedPackage = pkg;
15642            mCurResumedUid = uid;
15643            if (mCurResumedPackage != null) {
15644                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15645                        mCurResumedPackage, mCurResumedUid);
15646            }
15647        }
15648        return act;
15649    }
15650
15651    final boolean updateOomAdjLocked(ProcessRecord app) {
15652        return updateOomAdjLocked(app, false);
15653    }
15654
15655    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15656        final ActivityRecord TOP_ACT = resumedAppLocked();
15657        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15658        final boolean wasCached = app.cached;
15659
15660        mAdjSeq++;
15661
15662        // This is the desired cached adjusment we want to tell it to use.
15663        // If our app is currently cached, we know it, and that is it.  Otherwise,
15664        // we don't know it yet, and it needs to now be cached we will then
15665        // need to do a complete oom adj.
15666        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15667                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15668        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15669                SystemClock.uptimeMillis());
15670        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15671            // Changed to/from cached state, so apps after it in the LRU
15672            // list may also be changed.
15673            updateOomAdjLocked();
15674        }
15675        return success;
15676    }
15677
15678    final void updateOomAdjLocked() {
15679        final ActivityRecord TOP_ACT = resumedAppLocked();
15680        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15681        final long now = SystemClock.uptimeMillis();
15682        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15683        final int N = mLruProcesses.size();
15684
15685        if (false) {
15686            RuntimeException e = new RuntimeException();
15687            e.fillInStackTrace();
15688            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15689        }
15690
15691        mAdjSeq++;
15692        mNewNumServiceProcs = 0;
15693        mNewNumAServiceProcs = 0;
15694
15695        final int emptyProcessLimit;
15696        final int cachedProcessLimit;
15697        if (mProcessLimit <= 0) {
15698            emptyProcessLimit = cachedProcessLimit = 0;
15699        } else if (mProcessLimit == 1) {
15700            emptyProcessLimit = 1;
15701            cachedProcessLimit = 0;
15702        } else {
15703            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15704            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15705        }
15706
15707        // Let's determine how many processes we have running vs.
15708        // how many slots we have for background processes; we may want
15709        // to put multiple processes in a slot of there are enough of
15710        // them.
15711        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15712                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15713        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15714        if (numEmptyProcs > cachedProcessLimit) {
15715            // If there are more empty processes than our limit on cached
15716            // processes, then use the cached process limit for the factor.
15717            // This ensures that the really old empty processes get pushed
15718            // down to the bottom, so if we are running low on memory we will
15719            // have a better chance at keeping around more cached processes
15720            // instead of a gazillion empty processes.
15721            numEmptyProcs = cachedProcessLimit;
15722        }
15723        int emptyFactor = numEmptyProcs/numSlots;
15724        if (emptyFactor < 1) emptyFactor = 1;
15725        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15726        if (cachedFactor < 1) cachedFactor = 1;
15727        int stepCached = 0;
15728        int stepEmpty = 0;
15729        int numCached = 0;
15730        int numEmpty = 0;
15731        int numTrimming = 0;
15732
15733        mNumNonCachedProcs = 0;
15734        mNumCachedHiddenProcs = 0;
15735
15736        // First update the OOM adjustment for each of the
15737        // application processes based on their current state.
15738        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15739        int nextCachedAdj = curCachedAdj+1;
15740        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15741        int nextEmptyAdj = curEmptyAdj+2;
15742        for (int i=N-1; i>=0; i--) {
15743            ProcessRecord app = mLruProcesses.get(i);
15744            if (!app.killedByAm && app.thread != null) {
15745                app.procStateChanged = false;
15746                final boolean wasKeeping = app.keeping;
15747                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15748
15749                // If we haven't yet assigned the final cached adj
15750                // to the process, do that now.
15751                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15752                    switch (app.curProcState) {
15753                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15754                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15755                            // This process is a cached process holding activities...
15756                            // assign it the next cached value for that type, and then
15757                            // step that cached level.
15758                            app.curRawAdj = curCachedAdj;
15759                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15760                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15761                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15762                                    + ")");
15763                            if (curCachedAdj != nextCachedAdj) {
15764                                stepCached++;
15765                                if (stepCached >= cachedFactor) {
15766                                    stepCached = 0;
15767                                    curCachedAdj = nextCachedAdj;
15768                                    nextCachedAdj += 2;
15769                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15770                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15771                                    }
15772                                }
15773                            }
15774                            break;
15775                        default:
15776                            // For everything else, assign next empty cached process
15777                            // level and bump that up.  Note that this means that
15778                            // long-running services that have dropped down to the
15779                            // cached level will be treated as empty (since their process
15780                            // state is still as a service), which is what we want.
15781                            app.curRawAdj = curEmptyAdj;
15782                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15783                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15784                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15785                                    + ")");
15786                            if (curEmptyAdj != nextEmptyAdj) {
15787                                stepEmpty++;
15788                                if (stepEmpty >= emptyFactor) {
15789                                    stepEmpty = 0;
15790                                    curEmptyAdj = nextEmptyAdj;
15791                                    nextEmptyAdj += 2;
15792                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15793                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15794                                    }
15795                                }
15796                            }
15797                            break;
15798                    }
15799                }
15800
15801                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15802
15803                // Count the number of process types.
15804                switch (app.curProcState) {
15805                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15806                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15807                        mNumCachedHiddenProcs++;
15808                        numCached++;
15809                        if (numCached > cachedProcessLimit) {
15810                            killUnneededProcessLocked(app, "cached #" + numCached);
15811                        }
15812                        break;
15813                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15814                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15815                                && app.lastActivityTime < oldTime) {
15816                            killUnneededProcessLocked(app, "empty for "
15817                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15818                                    / 1000) + "s");
15819                        } else {
15820                            numEmpty++;
15821                            if (numEmpty > emptyProcessLimit) {
15822                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15823                            }
15824                        }
15825                        break;
15826                    default:
15827                        mNumNonCachedProcs++;
15828                        break;
15829                }
15830
15831                if (app.isolated && app.services.size() <= 0) {
15832                    // If this is an isolated process, and there are no
15833                    // services running in it, then the process is no longer
15834                    // needed.  We agressively kill these because we can by
15835                    // definition not re-use the same process again, and it is
15836                    // good to avoid having whatever code was running in them
15837                    // left sitting around after no longer needed.
15838                    killUnneededProcessLocked(app, "isolated not needed");
15839                }
15840
15841                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15842                        && !app.killedByAm) {
15843                    numTrimming++;
15844                }
15845            }
15846        }
15847
15848        mNumServiceProcs = mNewNumServiceProcs;
15849
15850        // Now determine the memory trimming level of background processes.
15851        // Unfortunately we need to start at the back of the list to do this
15852        // properly.  We only do this if the number of background apps we
15853        // are managing to keep around is less than half the maximum we desire;
15854        // if we are keeping a good number around, we'll let them use whatever
15855        // memory they want.
15856        final int numCachedAndEmpty = numCached + numEmpty;
15857        int memFactor;
15858        if (numCached <= ProcessList.TRIM_CACHED_APPS
15859                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15860            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15861                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15862            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15863                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15864            } else {
15865                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15866            }
15867        } else {
15868            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15869        }
15870        // We always allow the memory level to go up (better).  We only allow it to go
15871        // down if we are in a state where that is allowed, *and* the total number of processes
15872        // has gone down since last time.
15873        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15874                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15875                + " last=" + mLastNumProcesses);
15876        if (memFactor > mLastMemoryLevel) {
15877            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15878                memFactor = mLastMemoryLevel;
15879                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15880            }
15881        }
15882        mLastMemoryLevel = memFactor;
15883        mLastNumProcesses = mLruProcesses.size();
15884        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15885        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15886        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15887            if (mLowRamStartTime == 0) {
15888                mLowRamStartTime = now;
15889            }
15890            int step = 0;
15891            int fgTrimLevel;
15892            switch (memFactor) {
15893                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15894                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15895                    break;
15896                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15897                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15898                    break;
15899                default:
15900                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15901                    break;
15902            }
15903            int factor = numTrimming/3;
15904            int minFactor = 2;
15905            if (mHomeProcess != null) minFactor++;
15906            if (mPreviousProcess != null) minFactor++;
15907            if (factor < minFactor) factor = minFactor;
15908            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15909            for (int i=N-1; i>=0; i--) {
15910                ProcessRecord app = mLruProcesses.get(i);
15911                if (allChanged || app.procStateChanged) {
15912                    setProcessTrackerState(app, trackerMemFactor, now);
15913                    app.procStateChanged = false;
15914                }
15915                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15916                        && !app.killedByAm) {
15917                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15918                        try {
15919                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15920                                    "Trimming memory of " + app.processName
15921                                    + " to " + curLevel);
15922                            app.thread.scheduleTrimMemory(curLevel);
15923                        } catch (RemoteException e) {
15924                        }
15925                        if (false) {
15926                            // For now we won't do this; our memory trimming seems
15927                            // to be good enough at this point that destroying
15928                            // activities causes more harm than good.
15929                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15930                                    && app != mHomeProcess && app != mPreviousProcess) {
15931                                // Need to do this on its own message because the stack may not
15932                                // be in a consistent state at this point.
15933                                // For these apps we will also finish their activities
15934                                // to help them free memory.
15935                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15936                            }
15937                        }
15938                    }
15939                    app.trimMemoryLevel = curLevel;
15940                    step++;
15941                    if (step >= factor) {
15942                        step = 0;
15943                        switch (curLevel) {
15944                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15945                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15946                                break;
15947                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15948                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15949                                break;
15950                        }
15951                    }
15952                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15953                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15954                            && app.thread != null) {
15955                        try {
15956                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15957                                    "Trimming memory of heavy-weight " + app.processName
15958                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15959                            app.thread.scheduleTrimMemory(
15960                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15961                        } catch (RemoteException e) {
15962                        }
15963                    }
15964                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15965                } else {
15966                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15967                            || app.systemNoUi) && app.pendingUiClean) {
15968                        // If this application is now in the background and it
15969                        // had done UI, then give it the special trim level to
15970                        // have it free UI resources.
15971                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15972                        if (app.trimMemoryLevel < level && app.thread != null) {
15973                            try {
15974                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15975                                        "Trimming memory of bg-ui " + app.processName
15976                                        + " to " + level);
15977                                app.thread.scheduleTrimMemory(level);
15978                            } catch (RemoteException e) {
15979                            }
15980                        }
15981                        app.pendingUiClean = false;
15982                    }
15983                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15984                        try {
15985                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15986                                    "Trimming memory of fg " + app.processName
15987                                    + " to " + fgTrimLevel);
15988                            app.thread.scheduleTrimMemory(fgTrimLevel);
15989                        } catch (RemoteException e) {
15990                        }
15991                    }
15992                    app.trimMemoryLevel = fgTrimLevel;
15993                }
15994            }
15995        } else {
15996            if (mLowRamStartTime != 0) {
15997                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15998                mLowRamStartTime = 0;
15999            }
16000            for (int i=N-1; i>=0; i--) {
16001                ProcessRecord app = mLruProcesses.get(i);
16002                if (allChanged || app.procStateChanged) {
16003                    setProcessTrackerState(app, trackerMemFactor, now);
16004                    app.procStateChanged = false;
16005                }
16006                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16007                        || app.systemNoUi) && app.pendingUiClean) {
16008                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16009                            && app.thread != null) {
16010                        try {
16011                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16012                                    "Trimming memory of ui hidden " + app.processName
16013                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16014                            app.thread.scheduleTrimMemory(
16015                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16016                        } catch (RemoteException e) {
16017                        }
16018                    }
16019                    app.pendingUiClean = false;
16020                }
16021                app.trimMemoryLevel = 0;
16022            }
16023        }
16024
16025        if (mAlwaysFinishActivities) {
16026            // Need to do this on its own message because the stack may not
16027            // be in a consistent state at this point.
16028            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16029        }
16030
16031        if (allChanged) {
16032            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16033        }
16034
16035        if (mProcessStats.shouldWriteNowLocked(now)) {
16036            mHandler.post(new Runnable() {
16037                @Override public void run() {
16038                    synchronized (ActivityManagerService.this) {
16039                        mProcessStats.writeStateAsyncLocked();
16040                    }
16041                }
16042            });
16043        }
16044
16045        if (DEBUG_OOM_ADJ) {
16046            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16047        }
16048    }
16049
16050    final void trimApplications() {
16051        synchronized (this) {
16052            int i;
16053
16054            // First remove any unused application processes whose package
16055            // has been removed.
16056            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16057                final ProcessRecord app = mRemovedProcesses.get(i);
16058                if (app.activities.size() == 0
16059                        && app.curReceiver == null && app.services.size() == 0) {
16060                    Slog.i(
16061                        TAG, "Exiting empty application process "
16062                        + app.processName + " ("
16063                        + (app.thread != null ? app.thread.asBinder() : null)
16064                        + ")\n");
16065                    if (app.pid > 0 && app.pid != MY_PID) {
16066                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16067                                app.processName, app.setAdj, "empty");
16068                        app.killedByAm = true;
16069                        Process.killProcessQuiet(app.pid);
16070                    } else {
16071                        try {
16072                            app.thread.scheduleExit();
16073                        } catch (Exception e) {
16074                            // Ignore exceptions.
16075                        }
16076                    }
16077                    cleanUpApplicationRecordLocked(app, false, true, -1);
16078                    mRemovedProcesses.remove(i);
16079
16080                    if (app.persistent) {
16081                        if (app.persistent) {
16082                            addAppLocked(app.info, false);
16083                        }
16084                    }
16085                }
16086            }
16087
16088            // Now update the oom adj for all processes.
16089            updateOomAdjLocked();
16090        }
16091    }
16092
16093    /** This method sends the specified signal to each of the persistent apps */
16094    public void signalPersistentProcesses(int sig) throws RemoteException {
16095        if (sig != Process.SIGNAL_USR1) {
16096            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16097        }
16098
16099        synchronized (this) {
16100            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16101                    != PackageManager.PERMISSION_GRANTED) {
16102                throw new SecurityException("Requires permission "
16103                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16104            }
16105
16106            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16107                ProcessRecord r = mLruProcesses.get(i);
16108                if (r.thread != null && r.persistent) {
16109                    Process.sendSignal(r.pid, sig);
16110                }
16111            }
16112        }
16113    }
16114
16115    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16116        if (proc == null || proc == mProfileProc) {
16117            proc = mProfileProc;
16118            path = mProfileFile;
16119            profileType = mProfileType;
16120            clearProfilerLocked();
16121        }
16122        if (proc == null) {
16123            return;
16124        }
16125        try {
16126            proc.thread.profilerControl(false, path, null, profileType);
16127        } catch (RemoteException e) {
16128            throw new IllegalStateException("Process disappeared");
16129        }
16130    }
16131
16132    private void clearProfilerLocked() {
16133        if (mProfileFd != null) {
16134            try {
16135                mProfileFd.close();
16136            } catch (IOException e) {
16137            }
16138        }
16139        mProfileApp = null;
16140        mProfileProc = null;
16141        mProfileFile = null;
16142        mProfileType = 0;
16143        mAutoStopProfiler = false;
16144    }
16145
16146    public boolean profileControl(String process, int userId, boolean start,
16147            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16148
16149        try {
16150            synchronized (this) {
16151                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16152                // its own permission.
16153                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16154                        != PackageManager.PERMISSION_GRANTED) {
16155                    throw new SecurityException("Requires permission "
16156                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16157                }
16158
16159                if (start && fd == null) {
16160                    throw new IllegalArgumentException("null fd");
16161                }
16162
16163                ProcessRecord proc = null;
16164                if (process != null) {
16165                    proc = findProcessLocked(process, userId, "profileControl");
16166                }
16167
16168                if (start && (proc == null || proc.thread == null)) {
16169                    throw new IllegalArgumentException("Unknown process: " + process);
16170                }
16171
16172                if (start) {
16173                    stopProfilerLocked(null, null, 0);
16174                    setProfileApp(proc.info, proc.processName, path, fd, false);
16175                    mProfileProc = proc;
16176                    mProfileType = profileType;
16177                    try {
16178                        fd = fd.dup();
16179                    } catch (IOException e) {
16180                        fd = null;
16181                    }
16182                    proc.thread.profilerControl(start, path, fd, profileType);
16183                    fd = null;
16184                    mProfileFd = null;
16185                } else {
16186                    stopProfilerLocked(proc, path, profileType);
16187                    if (fd != null) {
16188                        try {
16189                            fd.close();
16190                        } catch (IOException e) {
16191                        }
16192                    }
16193                }
16194
16195                return true;
16196            }
16197        } catch (RemoteException e) {
16198            throw new IllegalStateException("Process disappeared");
16199        } finally {
16200            if (fd != null) {
16201                try {
16202                    fd.close();
16203                } catch (IOException e) {
16204                }
16205            }
16206        }
16207    }
16208
16209    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16210        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16211                userId, true, true, callName, null);
16212        ProcessRecord proc = null;
16213        try {
16214            int pid = Integer.parseInt(process);
16215            synchronized (mPidsSelfLocked) {
16216                proc = mPidsSelfLocked.get(pid);
16217            }
16218        } catch (NumberFormatException e) {
16219        }
16220
16221        if (proc == null) {
16222            ArrayMap<String, SparseArray<ProcessRecord>> all
16223                    = mProcessNames.getMap();
16224            SparseArray<ProcessRecord> procs = all.get(process);
16225            if (procs != null && procs.size() > 0) {
16226                proc = procs.valueAt(0);
16227                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16228                    for (int i=1; i<procs.size(); i++) {
16229                        ProcessRecord thisProc = procs.valueAt(i);
16230                        if (thisProc.userId == userId) {
16231                            proc = thisProc;
16232                            break;
16233                        }
16234                    }
16235                }
16236            }
16237        }
16238
16239        return proc;
16240    }
16241
16242    public boolean dumpHeap(String process, int userId, boolean managed,
16243            String path, ParcelFileDescriptor fd) throws RemoteException {
16244
16245        try {
16246            synchronized (this) {
16247                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16248                // its own permission (same as profileControl).
16249                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16250                        != PackageManager.PERMISSION_GRANTED) {
16251                    throw new SecurityException("Requires permission "
16252                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16253                }
16254
16255                if (fd == null) {
16256                    throw new IllegalArgumentException("null fd");
16257                }
16258
16259                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16260                if (proc == null || proc.thread == null) {
16261                    throw new IllegalArgumentException("Unknown process: " + process);
16262                }
16263
16264                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16265                if (!isDebuggable) {
16266                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16267                        throw new SecurityException("Process not debuggable: " + proc);
16268                    }
16269                }
16270
16271                proc.thread.dumpHeap(managed, path, fd);
16272                fd = null;
16273                return true;
16274            }
16275        } catch (RemoteException e) {
16276            throw new IllegalStateException("Process disappeared");
16277        } finally {
16278            if (fd != null) {
16279                try {
16280                    fd.close();
16281                } catch (IOException e) {
16282                }
16283            }
16284        }
16285    }
16286
16287    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16288    public void monitor() {
16289        synchronized (this) { }
16290    }
16291
16292    void onCoreSettingsChange(Bundle settings) {
16293        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16294            ProcessRecord processRecord = mLruProcesses.get(i);
16295            try {
16296                if (processRecord.thread != null) {
16297                    processRecord.thread.setCoreSettings(settings);
16298                }
16299            } catch (RemoteException re) {
16300                /* ignore */
16301            }
16302        }
16303    }
16304
16305    // Multi-user methods
16306
16307    /**
16308     * Start user, if its not already running, but don't bring it to foreground.
16309     */
16310    @Override
16311    public boolean startUserInBackground(final int userId) {
16312        return startUser(userId, /* foreground */ false);
16313    }
16314
16315    /**
16316     * Refreshes the list of users related to the current user when either a
16317     * user switch happens or when a new related user is started in the
16318     * background.
16319     */
16320    private void updateCurrentProfileIdsLocked() {
16321        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16322        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16323        for (int i = 0; i < currentProfileIds.length; i++) {
16324            currentProfileIds[i] = profiles.get(i).id;
16325        }
16326        mCurrentProfileIds = currentProfileIds;
16327    }
16328
16329    private Set getProfileIdsLocked(int userId) {
16330        Set userIds = new HashSet<Integer>();
16331        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId);
16332        for (UserInfo user : profiles) {
16333            userIds.add(Integer.valueOf(user.id));
16334        }
16335        return userIds;
16336    }
16337
16338    @Override
16339    public boolean switchUser(final int userId) {
16340        return startUser(userId, /* foregound */ true);
16341    }
16342
16343    private boolean startUser(final int userId, boolean foreground) {
16344        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16345                != PackageManager.PERMISSION_GRANTED) {
16346            String msg = "Permission Denial: switchUser() from pid="
16347                    + Binder.getCallingPid()
16348                    + ", uid=" + Binder.getCallingUid()
16349                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16350            Slog.w(TAG, msg);
16351            throw new SecurityException(msg);
16352        }
16353
16354        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16355
16356        final long ident = Binder.clearCallingIdentity();
16357        try {
16358            synchronized (this) {
16359                final int oldUserId = mCurrentUserId;
16360                if (oldUserId == userId) {
16361                    return true;
16362                }
16363
16364                mStackSupervisor.setLockTaskModeLocked(null);
16365
16366                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16367                if (userInfo == null) {
16368                    Slog.w(TAG, "No user info for user #" + userId);
16369                    return false;
16370                }
16371
16372                if (foreground) {
16373                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16374                            R.anim.screen_user_enter);
16375                }
16376
16377                boolean needStart = false;
16378
16379                // If the user we are switching to is not currently started, then
16380                // we need to start it now.
16381                if (mStartedUsers.get(userId) == null) {
16382                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16383                    updateStartedUserArrayLocked();
16384                    needStart = true;
16385                }
16386
16387                final Integer userIdInt = Integer.valueOf(userId);
16388                mUserLru.remove(userIdInt);
16389                mUserLru.add(userIdInt);
16390
16391                if (foreground) {
16392                    mCurrentUserId = userId;
16393                    updateCurrentProfileIdsLocked();
16394                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16395                    // Once the internal notion of the active user has switched, we lock the device
16396                    // with the option to show the user switcher on the keyguard.
16397                    mWindowManager.lockNow(null);
16398                } else {
16399                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16400                    updateCurrentProfileIdsLocked();
16401                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16402                    mUserLru.remove(currentUserIdInt);
16403                    mUserLru.add(currentUserIdInt);
16404                }
16405
16406                final UserStartedState uss = mStartedUsers.get(userId);
16407
16408                // Make sure user is in the started state.  If it is currently
16409                // stopping, we need to knock that off.
16410                if (uss.mState == UserStartedState.STATE_STOPPING) {
16411                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16412                    // so we can just fairly silently bring the user back from
16413                    // the almost-dead.
16414                    uss.mState = UserStartedState.STATE_RUNNING;
16415                    updateStartedUserArrayLocked();
16416                    needStart = true;
16417                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16418                    // This means ACTION_SHUTDOWN has been sent, so we will
16419                    // need to treat this as a new boot of the user.
16420                    uss.mState = UserStartedState.STATE_BOOTING;
16421                    updateStartedUserArrayLocked();
16422                    needStart = true;
16423                }
16424
16425                if (foreground) {
16426                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16427                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16428                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16429                            oldUserId, userId, uss));
16430                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16431                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16432                }
16433
16434                if (needStart) {
16435                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16436                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16437                            | Intent.FLAG_RECEIVER_FOREGROUND);
16438                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16439                    broadcastIntentLocked(null, null, intent,
16440                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16441                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16442                }
16443
16444                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16445                    if (userId != 0) {
16446                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16447                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16448                        broadcastIntentLocked(null, null, intent, null,
16449                                new IIntentReceiver.Stub() {
16450                                    public void performReceive(Intent intent, int resultCode,
16451                                            String data, Bundle extras, boolean ordered,
16452                                            boolean sticky, int sendingUser) {
16453                                        userInitialized(uss, userId);
16454                                    }
16455                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16456                                true, false, MY_PID, Process.SYSTEM_UID,
16457                                userId);
16458                        uss.initializing = true;
16459                    } else {
16460                        getUserManagerLocked().makeInitialized(userInfo.id);
16461                    }
16462                }
16463
16464                if (foreground) {
16465                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16466                    if (homeInFront) {
16467                        startHomeActivityLocked(userId);
16468                    } else {
16469                        mStackSupervisor.resumeTopActivitiesLocked();
16470                    }
16471                    EventLogTags.writeAmSwitchUser(userId);
16472                    getUserManagerLocked().userForeground(userId);
16473                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16474                }
16475
16476                if (needStart) {
16477                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16478                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16479                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16480                    broadcastIntentLocked(null, null, intent,
16481                            null, new IIntentReceiver.Stub() {
16482                                @Override
16483                                public void performReceive(Intent intent, int resultCode, String data,
16484                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16485                                        throws RemoteException {
16486                                }
16487                            }, 0, null, null,
16488                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16489                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16490                }
16491            }
16492        } finally {
16493            Binder.restoreCallingIdentity(ident);
16494        }
16495
16496        return true;
16497    }
16498
16499    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16500        long ident = Binder.clearCallingIdentity();
16501        try {
16502            Intent intent;
16503            if (oldUserId >= 0) {
16504                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16505                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16506                        | Intent.FLAG_RECEIVER_FOREGROUND);
16507                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16508                broadcastIntentLocked(null, null, intent,
16509                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16510                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16511            }
16512            if (newUserId >= 0) {
16513                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16514                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16515                        | Intent.FLAG_RECEIVER_FOREGROUND);
16516                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16517                broadcastIntentLocked(null, null, intent,
16518                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16519                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16520                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16521                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16522                        | Intent.FLAG_RECEIVER_FOREGROUND);
16523                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16524                broadcastIntentLocked(null, null, intent,
16525                        null, null, 0, null, null,
16526                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16527                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16528            }
16529        } finally {
16530            Binder.restoreCallingIdentity(ident);
16531        }
16532    }
16533
16534    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16535            final int newUserId) {
16536        final int N = mUserSwitchObservers.beginBroadcast();
16537        if (N > 0) {
16538            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16539                int mCount = 0;
16540                @Override
16541                public void sendResult(Bundle data) throws RemoteException {
16542                    synchronized (ActivityManagerService.this) {
16543                        if (mCurUserSwitchCallback == this) {
16544                            mCount++;
16545                            if (mCount == N) {
16546                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16547                            }
16548                        }
16549                    }
16550                }
16551            };
16552            synchronized (this) {
16553                uss.switching = true;
16554                mCurUserSwitchCallback = callback;
16555            }
16556            for (int i=0; i<N; i++) {
16557                try {
16558                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16559                            newUserId, callback);
16560                } catch (RemoteException e) {
16561                }
16562            }
16563        } else {
16564            synchronized (this) {
16565                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16566            }
16567        }
16568        mUserSwitchObservers.finishBroadcast();
16569    }
16570
16571    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16572        synchronized (this) {
16573            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16574            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16575        }
16576    }
16577
16578    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16579        mCurUserSwitchCallback = null;
16580        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16581        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16582                oldUserId, newUserId, uss));
16583    }
16584
16585    void userInitialized(UserStartedState uss, int newUserId) {
16586        completeSwitchAndInitalize(uss, newUserId, true, false);
16587    }
16588
16589    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16590        completeSwitchAndInitalize(uss, newUserId, false, true);
16591    }
16592
16593    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16594            boolean clearInitializing, boolean clearSwitching) {
16595        boolean unfrozen = false;
16596        synchronized (this) {
16597            if (clearInitializing) {
16598                uss.initializing = false;
16599                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16600            }
16601            if (clearSwitching) {
16602                uss.switching = false;
16603            }
16604            if (!uss.switching && !uss.initializing) {
16605                mWindowManager.stopFreezingScreen();
16606                unfrozen = true;
16607            }
16608        }
16609        if (unfrozen) {
16610            final int N = mUserSwitchObservers.beginBroadcast();
16611            for (int i=0; i<N; i++) {
16612                try {
16613                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16614                } catch (RemoteException e) {
16615                }
16616            }
16617            mUserSwitchObservers.finishBroadcast();
16618        }
16619    }
16620
16621    void scheduleStartProfilesLocked() {
16622        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16623            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16624                    DateUtils.SECOND_IN_MILLIS);
16625        }
16626    }
16627
16628    void startProfilesLocked() {
16629        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16630        List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
16631        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16632        for (UserInfo user : profiles) {
16633            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16634                    && user.id != mCurrentUserId) {
16635                toStart.add(user);
16636            }
16637        }
16638        final int n = toStart.size();
16639        int i = 0;
16640        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16641            startUserInBackground(toStart.get(i).id);
16642        }
16643        if (i < n) {
16644            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16645        }
16646    }
16647
16648    void finishUserSwitch(UserStartedState uss) {
16649        synchronized (this) {
16650            if (uss.mState == UserStartedState.STATE_BOOTING
16651                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16652                uss.mState = UserStartedState.STATE_RUNNING;
16653                final int userId = uss.mHandle.getIdentifier();
16654                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16655                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16656                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16657                broadcastIntentLocked(null, null, intent,
16658                        null, null, 0, null, null,
16659                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16660                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16661            }
16662
16663            startProfilesLocked();
16664
16665            int num = mUserLru.size();
16666            int i = 0;
16667            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16668                Integer oldUserId = mUserLru.get(i);
16669                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16670                if (oldUss == null) {
16671                    // Shouldn't happen, but be sane if it does.
16672                    mUserLru.remove(i);
16673                    num--;
16674                    continue;
16675                }
16676                if (oldUss.mState == UserStartedState.STATE_STOPPING
16677                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16678                    // This user is already stopping, doesn't count.
16679                    num--;
16680                    i++;
16681                    continue;
16682                }
16683                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16684                    // Owner and current can't be stopped, but count as running.
16685                    i++;
16686                    continue;
16687                }
16688                // This is a user to be stopped.
16689                stopUserLocked(oldUserId, null);
16690                num--;
16691                i++;
16692            }
16693        }
16694    }
16695
16696    @Override
16697    public int stopUser(final int userId, final IStopUserCallback callback) {
16698        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16699                != PackageManager.PERMISSION_GRANTED) {
16700            String msg = "Permission Denial: switchUser() from pid="
16701                    + Binder.getCallingPid()
16702                    + ", uid=" + Binder.getCallingUid()
16703                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16704            Slog.w(TAG, msg);
16705            throw new SecurityException(msg);
16706        }
16707        if (userId <= 0) {
16708            throw new IllegalArgumentException("Can't stop primary user " + userId);
16709        }
16710        synchronized (this) {
16711            return stopUserLocked(userId, callback);
16712        }
16713    }
16714
16715    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16716        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16717        if (mCurrentUserId == userId) {
16718            return ActivityManager.USER_OP_IS_CURRENT;
16719        }
16720
16721        final UserStartedState uss = mStartedUsers.get(userId);
16722        if (uss == null) {
16723            // User is not started, nothing to do...  but we do need to
16724            // callback if requested.
16725            if (callback != null) {
16726                mHandler.post(new Runnable() {
16727                    @Override
16728                    public void run() {
16729                        try {
16730                            callback.userStopped(userId);
16731                        } catch (RemoteException e) {
16732                        }
16733                    }
16734                });
16735            }
16736            return ActivityManager.USER_OP_SUCCESS;
16737        }
16738
16739        if (callback != null) {
16740            uss.mStopCallbacks.add(callback);
16741        }
16742
16743        if (uss.mState != UserStartedState.STATE_STOPPING
16744                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16745            uss.mState = UserStartedState.STATE_STOPPING;
16746            updateStartedUserArrayLocked();
16747
16748            long ident = Binder.clearCallingIdentity();
16749            try {
16750                // We are going to broadcast ACTION_USER_STOPPING and then
16751                // once that is done send a final ACTION_SHUTDOWN and then
16752                // stop the user.
16753                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16754                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16755                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16756                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16757                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16758                // This is the result receiver for the final shutdown broadcast.
16759                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16760                    @Override
16761                    public void performReceive(Intent intent, int resultCode, String data,
16762                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16763                        finishUserStop(uss);
16764                    }
16765                };
16766                // This is the result receiver for the initial stopping broadcast.
16767                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16768                    @Override
16769                    public void performReceive(Intent intent, int resultCode, String data,
16770                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16771                        // On to the next.
16772                        synchronized (ActivityManagerService.this) {
16773                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16774                                // Whoops, we are being started back up.  Abort, abort!
16775                                return;
16776                            }
16777                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16778                        }
16779                        broadcastIntentLocked(null, null, shutdownIntent,
16780                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16781                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16782                    }
16783                };
16784                // Kick things off.
16785                broadcastIntentLocked(null, null, stoppingIntent,
16786                        null, stoppingReceiver, 0, null, null,
16787                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16788                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16789            } finally {
16790                Binder.restoreCallingIdentity(ident);
16791            }
16792        }
16793
16794        return ActivityManager.USER_OP_SUCCESS;
16795    }
16796
16797    void finishUserStop(UserStartedState uss) {
16798        final int userId = uss.mHandle.getIdentifier();
16799        boolean stopped;
16800        ArrayList<IStopUserCallback> callbacks;
16801        synchronized (this) {
16802            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16803            if (mStartedUsers.get(userId) != uss) {
16804                stopped = false;
16805            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16806                stopped = false;
16807            } else {
16808                stopped = true;
16809                // User can no longer run.
16810                mStartedUsers.remove(userId);
16811                mUserLru.remove(Integer.valueOf(userId));
16812                updateStartedUserArrayLocked();
16813
16814                // Clean up all state and processes associated with the user.
16815                // Kill all the processes for the user.
16816                forceStopUserLocked(userId, "finish user");
16817            }
16818        }
16819
16820        for (int i=0; i<callbacks.size(); i++) {
16821            try {
16822                if (stopped) callbacks.get(i).userStopped(userId);
16823                else callbacks.get(i).userStopAborted(userId);
16824            } catch (RemoteException e) {
16825            }
16826        }
16827
16828        mStackSupervisor.removeUserLocked(userId);
16829    }
16830
16831    @Override
16832    public UserInfo getCurrentUser() {
16833        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16834                != PackageManager.PERMISSION_GRANTED) && (
16835                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16836                != PackageManager.PERMISSION_GRANTED)) {
16837            String msg = "Permission Denial: getCurrentUser() from pid="
16838                    + Binder.getCallingPid()
16839                    + ", uid=" + Binder.getCallingUid()
16840                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16841            Slog.w(TAG, msg);
16842            throw new SecurityException(msg);
16843        }
16844        synchronized (this) {
16845            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16846        }
16847    }
16848
16849    int getCurrentUserIdLocked() {
16850        return mCurrentUserId;
16851    }
16852
16853    @Override
16854    public boolean isUserRunning(int userId, boolean orStopped) {
16855        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16856                != PackageManager.PERMISSION_GRANTED) {
16857            String msg = "Permission Denial: isUserRunning() from pid="
16858                    + Binder.getCallingPid()
16859                    + ", uid=" + Binder.getCallingUid()
16860                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16861            Slog.w(TAG, msg);
16862            throw new SecurityException(msg);
16863        }
16864        synchronized (this) {
16865            return isUserRunningLocked(userId, orStopped);
16866        }
16867    }
16868
16869    boolean isUserRunningLocked(int userId, boolean orStopped) {
16870        UserStartedState state = mStartedUsers.get(userId);
16871        if (state == null) {
16872            return false;
16873        }
16874        if (orStopped) {
16875            return true;
16876        }
16877        return state.mState != UserStartedState.STATE_STOPPING
16878                && state.mState != UserStartedState.STATE_SHUTDOWN;
16879    }
16880
16881    @Override
16882    public int[] getRunningUserIds() {
16883        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16884                != PackageManager.PERMISSION_GRANTED) {
16885            String msg = "Permission Denial: isUserRunning() from pid="
16886                    + Binder.getCallingPid()
16887                    + ", uid=" + Binder.getCallingUid()
16888                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16889            Slog.w(TAG, msg);
16890            throw new SecurityException(msg);
16891        }
16892        synchronized (this) {
16893            return mStartedUserArray;
16894        }
16895    }
16896
16897    private void updateStartedUserArrayLocked() {
16898        int num = 0;
16899        for (int i=0; i<mStartedUsers.size();  i++) {
16900            UserStartedState uss = mStartedUsers.valueAt(i);
16901            // This list does not include stopping users.
16902            if (uss.mState != UserStartedState.STATE_STOPPING
16903                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16904                num++;
16905            }
16906        }
16907        mStartedUserArray = new int[num];
16908        num = 0;
16909        for (int i=0; i<mStartedUsers.size();  i++) {
16910            UserStartedState uss = mStartedUsers.valueAt(i);
16911            if (uss.mState != UserStartedState.STATE_STOPPING
16912                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16913                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16914                num++;
16915            }
16916        }
16917    }
16918
16919    @Override
16920    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16921        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16922                != PackageManager.PERMISSION_GRANTED) {
16923            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16924                    + Binder.getCallingPid()
16925                    + ", uid=" + Binder.getCallingUid()
16926                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16927            Slog.w(TAG, msg);
16928            throw new SecurityException(msg);
16929        }
16930
16931        mUserSwitchObservers.register(observer);
16932    }
16933
16934    @Override
16935    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16936        mUserSwitchObservers.unregister(observer);
16937    }
16938
16939    private boolean userExists(int userId) {
16940        if (userId == 0) {
16941            return true;
16942        }
16943        UserManagerService ums = getUserManagerLocked();
16944        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16945    }
16946
16947    int[] getUsersLocked() {
16948        UserManagerService ums = getUserManagerLocked();
16949        return ums != null ? ums.getUserIds() : new int[] { 0 };
16950    }
16951
16952    UserManagerService getUserManagerLocked() {
16953        if (mUserManager == null) {
16954            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16955            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16956        }
16957        return mUserManager;
16958    }
16959
16960    private int applyUserId(int uid, int userId) {
16961        return UserHandle.getUid(userId, uid);
16962    }
16963
16964    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16965        if (info == null) return null;
16966        ApplicationInfo newInfo = new ApplicationInfo(info);
16967        newInfo.uid = applyUserId(info.uid, userId);
16968        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16969                + info.packageName;
16970        return newInfo;
16971    }
16972
16973    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16974        if (aInfo == null
16975                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16976            return aInfo;
16977        }
16978
16979        ActivityInfo info = new ActivityInfo(aInfo);
16980        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16981        return info;
16982    }
16983}
16984