ActivityManagerService.java revision 84984faf530e525b066e28710d0f9beb32142ec5
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.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.content.DialogInterface.OnClickListener;
40import android.content.res.Resources;
41import android.graphics.BitmapFactory;
42import android.graphics.Rect;
43import android.os.BatteryStats;
44import android.os.PersistableBundle;
45import android.service.voice.IVoiceInteractionSession;
46import android.util.ArrayMap;
47
48import com.android.internal.R;
49import com.android.internal.annotations.GuardedBy;
50import com.android.internal.app.IAppOpsService;
51import com.android.internal.app.IVoiceInteractor;
52import com.android.internal.app.ProcessMap;
53import com.android.internal.app.ProcessStats;
54import com.android.internal.content.PackageMonitor;
55import com.android.internal.os.BackgroundThread;
56import com.android.internal.os.BatteryStatsImpl;
57import com.android.internal.os.ProcessCpuTracker;
58import com.android.internal.os.TransferPipe;
59import com.android.internal.os.Zygote;
60import com.android.internal.util.FastPrintWriter;
61import com.android.internal.util.FastXmlSerializer;
62import com.android.internal.util.MemInfoReader;
63import com.android.internal.util.Preconditions;
64import com.android.server.AppOpsService;
65import com.android.server.AttributeCache;
66import com.android.server.IntentResolver;
67import com.android.server.LocalServices;
68import com.android.server.ServiceThread;
69import com.android.server.SystemService;
70import com.android.server.SystemServiceManager;
71import com.android.server.Watchdog;
72import com.android.server.am.ActivityStack.ActivityState;
73import com.android.server.firewall.IntentFirewall;
74import com.android.server.pm.UserManagerService;
75import com.android.server.wm.AppTransition;
76import com.android.server.wm.WindowManagerService;
77import com.google.android.collect.Lists;
78import com.google.android.collect.Maps;
79
80import libcore.io.IoUtils;
81
82import org.xmlpull.v1.XmlPullParser;
83import org.xmlpull.v1.XmlPullParserException;
84import org.xmlpull.v1.XmlSerializer;
85
86import android.app.Activity;
87import android.app.ActivityManager;
88import android.app.ActivityManager.RunningTaskInfo;
89import android.app.ActivityManager.StackInfo;
90import android.app.ActivityManagerInternal;
91import android.app.ActivityManagerNative;
92import android.app.ActivityOptions;
93import android.app.ActivityThread;
94import android.app.AlertDialog;
95import android.app.AppGlobals;
96import android.app.ApplicationErrorReport;
97import android.app.Dialog;
98import android.app.IActivityController;
99import android.app.IApplicationThread;
100import android.app.IInstrumentationWatcher;
101import android.app.INotificationManager;
102import android.app.IProcessObserver;
103import android.app.IServiceConnection;
104import android.app.IStopUserCallback;
105import android.app.IUiAutomationConnection;
106import android.app.IUserSwitchObserver;
107import android.app.Instrumentation;
108import android.app.Notification;
109import android.app.NotificationManager;
110import android.app.PendingIntent;
111import android.app.backup.IBackupManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.ParceledListSlice;
136import android.content.pm.UserInfo;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PathPermission;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.res.CompatibilityInfo;
143import android.content.res.Configuration;
144import android.graphics.Bitmap;
145import android.net.Proxy;
146import android.net.ProxyInfo;
147import android.net.Uri;
148import android.os.Binder;
149import android.os.Build;
150import android.os.Bundle;
151import android.os.Debug;
152import android.os.DropBoxManager;
153import android.os.Environment;
154import android.os.FactoryTest;
155import android.os.FileObserver;
156import android.os.FileUtils;
157import android.os.Handler;
158import android.os.IBinder;
159import android.os.IPermissionController;
160import android.os.IRemoteCallback;
161import android.os.IUserManager;
162import android.os.Looper;
163import android.os.Message;
164import android.os.Parcel;
165import android.os.ParcelFileDescriptor;
166import android.os.Process;
167import android.os.RemoteCallbackList;
168import android.os.RemoteException;
169import android.os.SELinux;
170import android.os.ServiceManager;
171import android.os.StrictMode;
172import android.os.SystemClock;
173import android.os.SystemProperties;
174import android.os.UpdateLock;
175import android.os.UserHandle;
176import android.provider.Settings;
177import android.text.Spannable;
178import android.text.SpannableString;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.text.style.DynamicDrawableSpan;
182import android.text.style.ImageSpan;
183import android.util.AtomicFile;
184import android.util.EventLog;
185import android.util.Log;
186import android.util.Pair;
187import android.util.PrintWriterPrinter;
188import android.util.Slog;
189import android.util.SparseArray;
190import android.util.TimeUtils;
191import android.util.Xml;
192import android.view.Gravity;
193import android.view.LayoutInflater;
194import android.view.View;
195import android.view.WindowManager;
196import android.widget.TextView;
197
198import java.io.BufferedInputStream;
199import java.io.BufferedOutputStream;
200import java.io.DataInputStream;
201import java.io.DataOutputStream;
202import java.io.File;
203import java.io.FileDescriptor;
204import java.io.FileInputStream;
205import java.io.FileNotFoundException;
206import java.io.FileOutputStream;
207import java.io.IOException;
208import java.io.InputStreamReader;
209import java.io.PrintWriter;
210import java.io.StringWriter;
211import java.lang.ref.WeakReference;
212import java.util.ArrayList;
213import java.util.Arrays;
214import java.util.Collections;
215import java.util.Comparator;
216import java.util.HashMap;
217import java.util.HashSet;
218import java.util.Iterator;
219import java.util.List;
220import java.util.Locale;
221import java.util.Map;
222import java.util.Set;
223import java.util.concurrent.atomic.AtomicBoolean;
224import java.util.concurrent.atomic.AtomicLong;
225
226public final class ActivityManagerService extends ActivityManagerNative
227        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
228    private static final String USER_DATA_DIR = "/data/user/";
229    static final String TAG = "ActivityManager";
230    static final String TAG_MU = "ActivityManagerServiceMU";
231    static final boolean DEBUG = false;
232    static final boolean localLOGV = DEBUG;
233    static final boolean DEBUG_BACKUP = localLOGV || false;
234    static final boolean DEBUG_BROADCAST = localLOGV || false;
235    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
236    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_CLEANUP = localLOGV || false;
238    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
239    static final boolean DEBUG_FOCUS = false;
240    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
241    static final boolean DEBUG_MU = localLOGV || false;
242    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
243    static final boolean DEBUG_LRU = localLOGV || false;
244    static final boolean DEBUG_PAUSE = localLOGV || false;
245    static final boolean DEBUG_POWER = localLOGV || false;
246    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
247    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
248    static final boolean DEBUG_PROCESSES = localLOGV || false;
249    static final boolean DEBUG_PROVIDER = localLOGV || false;
250    static final boolean DEBUG_RESULTS = localLOGV || false;
251    static final boolean DEBUG_SERVICE = localLOGV || false;
252    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
253    static final boolean DEBUG_STACK = localLOGV || false;
254    static final boolean DEBUG_SWITCH = localLOGV || false;
255    static final boolean DEBUG_TASKS = localLOGV || false;
256    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
257    static final boolean DEBUG_TRANSITION = localLOGV || false;
258    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
259    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
260    static final boolean DEBUG_VISBILITY = localLOGV || false;
261    static final boolean DEBUG_PSS = localLOGV || false;
262    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
263    static final boolean VALIDATE_TOKENS = false;
264    static final boolean SHOW_ACTIVITY_START_TIME = true;
265
266    // Control over CPU and battery monitoring.
267    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
268    static final boolean MONITOR_CPU_USAGE = true;
269    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
270    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
271    static final boolean MONITOR_THREAD_CPU_USAGE = false;
272
273    // The flags that are set for all calls we make to the package manager.
274    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
275
276    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
277
278    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
279
280    // Maximum number of recent tasks that we can remember.
281    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
282
283    // Amount of time after a call to stopAppSwitches() during which we will
284    // prevent further untrusted switches from happening.
285    static final long APP_SWITCH_DELAY_TIME = 5*1000;
286
287    // How long we wait for a launched process to attach to the activity manager
288    // before we decide it's never going to come up for real.
289    static final int PROC_START_TIMEOUT = 10*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real, when the process was
293    // started with a wrapper for instrumentation (such as Valgrind) because it
294    // could take much longer than usual.
295    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
296
297    // How long to wait after going idle before forcing apps to GC.
298    static final int GC_TIMEOUT = 5*1000;
299
300    // The minimum amount of time between successive GC requests for a process.
301    static final int GC_MIN_INTERVAL = 60*1000;
302
303    // The minimum amount of time between successive PSS requests for a process.
304    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
305
306    // The minimum amount of time between successive PSS requests for a process
307    // when the request is due to the memory state being lowered.
308    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
309
310    // The rate at which we check for apps using excessive power -- 15 mins.
311    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
312
313    // The minimum sample duration we will allow before deciding we have
314    // enough data on wake locks to start killing things.
315    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on CPU usage to start killing things.
319    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // How long we allow a receiver to run before giving up on it.
322    static final int BROADCAST_FG_TIMEOUT = 10*1000;
323    static final int BROADCAST_BG_TIMEOUT = 60*1000;
324
325    // How long we wait until we timeout on key dispatching.
326    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
327
328    // How long we wait until we timeout on key dispatching during instrumentation.
329    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
330
331    // Amount of time we wait for observers to handle a user switch before
332    // giving up on them and unfreezing the screen.
333    static final int USER_SWITCH_TIMEOUT = 2*1000;
334
335    // Maximum number of users we allow to be running at a time.
336    static final int MAX_RUNNING_USERS = 3;
337
338    // How long to wait in getAssistContextExtras for the activity and foreground services
339    // to respond with the result.
340    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
341
342    // Maximum number of persisted Uri grants a package is allowed
343    static final int MAX_PERSISTED_URI_GRANTS = 128;
344
345    static final int MY_PID = Process.myPid();
346
347    static final String[] EMPTY_STRING_ARRAY = new String[0];
348
349    // How many bytes to write into the dropbox log before truncating
350    static final int DROPBOX_MAX_SIZE = 256 * 1024;
351
352    /** All system services */
353    SystemServiceManager mSystemServiceManager;
354
355    /** Run all ActivityStacks through this */
356    ActivityStackSupervisor mStackSupervisor;
357
358    public IntentFirewall mIntentFirewall;
359
360    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
361    // default actuion automatically.  Important for devices without direct input
362    // devices.
363    private boolean mShowDialogs = true;
364
365    /**
366     * Description of a request to start a new activity, which has been held
367     * due to app switches being disabled.
368     */
369    static class PendingActivityLaunch {
370        final ActivityRecord r;
371        final ActivityRecord sourceRecord;
372        final int startFlags;
373        final ActivityStack stack;
374
375        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
376                int _startFlags, ActivityStack _stack) {
377            r = _r;
378            sourceRecord = _sourceRecord;
379            startFlags = _startFlags;
380            stack = _stack;
381        }
382    }
383
384    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
385            = new ArrayList<PendingActivityLaunch>();
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422
423    public class PendingAssistExtras extends Binder implements Runnable {
424        public final ActivityRecord activity;
425        public boolean haveResult = false;
426        public Bundle result = null;
427        public PendingAssistExtras(ActivityRecord _activity) {
428            activity = _activity;
429        }
430        @Override
431        public void run() {
432            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
433            synchronized (this) {
434                haveResult = true;
435                notifyAll();
436            }
437        }
438    }
439
440    final ArrayList<PendingAssistExtras> mPendingAssistExtras
441            = new ArrayList<PendingAssistExtras>();
442
443    /**
444     * Process management.
445     */
446    final ProcessList mProcessList = new ProcessList();
447
448    /**
449     * All of the applications we currently have running organized by name.
450     * The keys are strings of the application package name (as
451     * returned by the package manager), and the keys are ApplicationRecord
452     * objects.
453     */
454    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
455
456    /**
457     * Tracking long-term execution of processes to look for abuse and other
458     * bad app behavior.
459     */
460    final ProcessStatsService mProcessStats;
461
462    /**
463     * The currently running isolated processes.
464     */
465    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
466
467    /**
468     * Counter for assigning isolated process uids, to avoid frequently reusing the
469     * same ones.
470     */
471    int mNextIsolatedProcessUid = 0;
472
473    /**
474     * The currently running heavy-weight process, if any.
475     */
476    ProcessRecord mHeavyWeightProcess = null;
477
478    /**
479     * The last time that various processes have crashed.
480     */
481    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
482
483    /**
484     * Information about a process that is currently marked as bad.
485     */
486    static final class BadProcessInfo {
487        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
488            this.time = time;
489            this.shortMsg = shortMsg;
490            this.longMsg = longMsg;
491            this.stack = stack;
492        }
493
494        final long time;
495        final String shortMsg;
496        final String longMsg;
497        final String stack;
498    }
499
500    /**
501     * Set of applications that we consider to be bad, and will reject
502     * incoming broadcasts from (which the user has no control over).
503     * Processes are added to this set when they have crashed twice within
504     * a minimum amount of time; they are removed from it when they are
505     * later restarted (hopefully due to some user action).  The value is the
506     * time it was added to the list.
507     */
508    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
509
510    /**
511     * All of the processes we currently have running organized by pid.
512     * The keys are the pid running the application.
513     *
514     * <p>NOTE: This object is protected by its own lock, NOT the global
515     * activity manager lock!
516     */
517    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
518
519    /**
520     * All of the processes that have been forced to be foreground.  The key
521     * is the pid of the caller who requested it (we hold a death
522     * link on it).
523     */
524    abstract class ForegroundToken implements IBinder.DeathRecipient {
525        int pid;
526        IBinder token;
527    }
528    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
529
530    /**
531     * List of records for processes that someone had tried to start before the
532     * system was ready.  We don't start them at that point, but ensure they
533     * are started by the time booting is complete.
534     */
535    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
536
537    /**
538     * List of persistent applications that are in the process
539     * of being started.
540     */
541    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * Processes that are being forcibly torn down.
545     */
546    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
547
548    /**
549     * List of running applications, sorted by recent usage.
550     * The first entry in the list is the least recently used.
551     */
552    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
553
554    /**
555     * Where in mLruProcesses that the processes hosting activities start.
556     */
557    int mLruProcessActivityStart = 0;
558
559    /**
560     * Where in mLruProcesses that the processes hosting services start.
561     * This is after (lower index) than mLruProcessesActivityStart.
562     */
563    int mLruProcessServiceStart = 0;
564
565    /**
566     * List of processes that should gc as soon as things are idle.
567     */
568    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
569
570    /**
571     * Processes we want to collect PSS data from.
572     */
573    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Last time we requested PSS data of all processes.
577     */
578    long mLastFullPssTime = SystemClock.uptimeMillis();
579
580    /**
581     * If set, the next time we collect PSS data we should do a full collection
582     * with data from native processes and the kernel.
583     */
584    boolean mFullPssPending = false;
585
586    /**
587     * This is the process holding what we currently consider to be
588     * the "home" activity.
589     */
590    ProcessRecord mHomeProcess;
591
592    /**
593     * This is the process holding the activity the user last visited that
594     * is in a different process from the one they are currently in.
595     */
596    ProcessRecord mPreviousProcess;
597
598    /**
599     * The time at which the previous process was last visible.
600     */
601    long mPreviousProcessVisibleTime;
602
603    /**
604     * Which uses have been started, so are allowed to run code.
605     */
606    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
607
608    /**
609     * LRU list of history of current users.  Most recently current is at the end.
610     */
611    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
612
613    /**
614     * Constant array of the users that are currently started.
615     */
616    int[] mStartedUserArray = new int[] { 0 };
617
618    /**
619     * Registered observers of the user switching mechanics.
620     */
621    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
622            = new RemoteCallbackList<IUserSwitchObserver>();
623
624    /**
625     * Currently active user switch.
626     */
627    Object mCurUserSwitchCallback;
628
629    /**
630     * Packages that the user has asked to have run in screen size
631     * compatibility mode instead of filling the screen.
632     */
633    final CompatModePackages mCompatModePackages;
634
635    /**
636     * Set of IntentSenderRecord objects that are currently active.
637     */
638    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
639            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
640
641    /**
642     * Fingerprints (hashCode()) of stack traces that we've
643     * already logged DropBox entries for.  Guarded by itself.  If
644     * something (rogue user app) forces this over
645     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
646     */
647    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
648    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
649
650    /**
651     * Strict Mode background batched logging state.
652     *
653     * The string buffer is guarded by itself, and its lock is also
654     * used to determine if another batched write is already
655     * in-flight.
656     */
657    private final StringBuilder mStrictModeBuffer = new StringBuilder();
658
659    /**
660     * Keeps track of all IIntentReceivers that have been registered for
661     * broadcasts.  Hash keys are the receiver IBinder, hash value is
662     * a ReceiverList.
663     */
664    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
665            new HashMap<IBinder, ReceiverList>();
666
667    /**
668     * Resolver for broadcast intents to registered receivers.
669     * Holds BroadcastFilter (subclass of IntentFilter).
670     */
671    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
672            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
673        @Override
674        protected boolean allowFilterResult(
675                BroadcastFilter filter, List<BroadcastFilter> dest) {
676            IBinder target = filter.receiverList.receiver.asBinder();
677            for (int i=dest.size()-1; i>=0; i--) {
678                if (dest.get(i).receiverList.receiver.asBinder() == target) {
679                    return false;
680                }
681            }
682            return true;
683        }
684
685        @Override
686        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
687            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
688                    || userId == filter.owningUserId) {
689                return super.newResult(filter, match, userId);
690            }
691            return null;
692        }
693
694        @Override
695        protected BroadcastFilter[] newArray(int size) {
696            return new BroadcastFilter[size];
697        }
698
699        @Override
700        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
701            return packageName.equals(filter.packageName);
702        }
703    };
704
705    /**
706     * State of all active sticky broadcasts per user.  Keys are the action of the
707     * sticky Intent, values are an ArrayList of all broadcasted intents with
708     * that action (which should usually be one).  The SparseArray is keyed
709     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
710     * for stickies that are sent to all users.
711     */
712    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
713            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
714
715    final ActiveServices mServices;
716
717    /**
718     * Backup/restore process management
719     */
720    String mBackupAppName = null;
721    BackupRecord mBackupTarget = null;
722
723    final ProviderMap mProviderMap;
724
725    /**
726     * List of content providers who have clients waiting for them.  The
727     * application is currently being launched and the provider will be
728     * removed from this list once it is published.
729     */
730    final ArrayList<ContentProviderRecord> mLaunchingProviders
731            = new ArrayList<ContentProviderRecord>();
732
733    /**
734     * File storing persisted {@link #mGrantedUriPermissions}.
735     */
736    private final AtomicFile mGrantFile;
737
738    /** XML constants used in {@link #mGrantFile} */
739    private static final String TAG_URI_GRANTS = "uri-grants";
740    private static final String TAG_URI_GRANT = "uri-grant";
741    private static final String ATTR_USER_HANDLE = "userHandle";
742    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
743    private static final String ATTR_TARGET_USER_ID = "targetUserId";
744    private static final String ATTR_SOURCE_PKG = "sourcePkg";
745    private static final String ATTR_TARGET_PKG = "targetPkg";
746    private static final String ATTR_URI = "uri";
747    private static final String ATTR_MODE_FLAGS = "modeFlags";
748    private static final String ATTR_CREATED_TIME = "createdTime";
749    private static final String ATTR_PREFIX = "prefix";
750
751    /**
752     * Global set of specific {@link Uri} permissions that have been granted.
753     * This optimized lookup structure maps from {@link UriPermission#targetUid}
754     * to {@link UriPermission#uri} to {@link UriPermission}.
755     */
756    @GuardedBy("this")
757    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
758            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
759
760    public static class GrantUri {
761        public final int sourceUserId;
762        public final Uri uri;
763        public boolean prefix;
764
765        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
766            this.sourceUserId = sourceUserId;
767            this.uri = uri;
768            this.prefix = prefix;
769        }
770
771        @Override
772        public int hashCode() {
773            return toString().hashCode();
774        }
775
776        @Override
777        public boolean equals(Object o) {
778            if (o instanceof GrantUri) {
779                GrantUri other = (GrantUri) o;
780                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
781                        && prefix == other.prefix;
782            }
783            return false;
784        }
785
786        @Override
787        public String toString() {
788            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
789            if (prefix) result += " [prefix]";
790            return result;
791        }
792
793        public String toSafeString() {
794            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
795            if (prefix) result += " [prefix]";
796            return result;
797        }
798
799        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
800            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
801                    ContentProvider.getUriWithoutUserId(uri), false);
802        }
803    }
804
805    CoreSettingsObserver mCoreSettingsObserver;
806
807    /**
808     * Thread-local storage used to carry caller permissions over through
809     * indirect content-provider access.
810     */
811    private class Identity {
812        public int pid;
813        public int uid;
814
815        Identity(int _pid, int _uid) {
816            pid = _pid;
817            uid = _uid;
818        }
819    }
820
821    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
822
823    /**
824     * All information we have collected about the runtime performance of
825     * any user id that can impact battery performance.
826     */
827    final BatteryStatsService mBatteryStatsService;
828
829    /**
830     * Information about component usage
831     */
832    final UsageStatsService mUsageStatsService;
833
834    /**
835     * Information about and control over application operations
836     */
837    final AppOpsService mAppOpsService;
838
839    /**
840     * Save recent tasks information across reboots.
841     */
842    final TaskPersister mTaskPersister;
843
844    /**
845     * Current configuration information.  HistoryRecord objects are given
846     * a reference to this object to indicate which configuration they are
847     * currently running in, so this object must be kept immutable.
848     */
849    Configuration mConfiguration = new Configuration();
850
851    /**
852     * Current sequencing integer of the configuration, for skipping old
853     * configurations.
854     */
855    int mConfigurationSeq = 0;
856
857    /**
858     * Hardware-reported OpenGLES version.
859     */
860    final int GL_ES_VERSION;
861
862    /**
863     * List of initialization arguments to pass to all processes when binding applications to them.
864     * For example, references to the commonly used services.
865     */
866    HashMap<String, IBinder> mAppBindArgs;
867
868    /**
869     * Temporary to avoid allocations.  Protected by main lock.
870     */
871    final StringBuilder mStringBuilder = new StringBuilder(256);
872
873    /**
874     * Used to control how we initialize the service.
875     */
876    ComponentName mTopComponent;
877    String mTopAction = Intent.ACTION_MAIN;
878    String mTopData;
879    boolean mProcessesReady = false;
880    boolean mSystemReady = false;
881    boolean mBooting = false;
882    boolean mWaitingUpdate = false;
883    boolean mDidUpdate = false;
884    boolean mOnBattery = false;
885    boolean mLaunchWarningShown = false;
886
887    Context mContext;
888
889    int mFactoryTest;
890
891    boolean mCheckedForSetup;
892
893    /**
894     * The time at which we will allow normal application switches again,
895     * after a call to {@link #stopAppSwitches()}.
896     */
897    long mAppSwitchesAllowedTime;
898
899    /**
900     * This is set to true after the first switch after mAppSwitchesAllowedTime
901     * is set; any switches after that will clear the time.
902     */
903    boolean mDidAppSwitch;
904
905    /**
906     * Last time (in realtime) at which we checked for power usage.
907     */
908    long mLastPowerCheckRealtime;
909
910    /**
911     * Last time (in uptime) at which we checked for power usage.
912     */
913    long mLastPowerCheckUptime;
914
915    /**
916     * Set while we are wanting to sleep, to prevent any
917     * activities from being started/resumed.
918     */
919    private boolean mSleeping = false;
920
921    /**
922     * Set while we are running a voice interaction.  This overrides
923     * sleeping while it is active.
924     */
925    private boolean mRunningVoice = false;
926
927    /**
928     * State of external calls telling us if the device is asleep.
929     */
930    private boolean mWentToSleep = false;
931
932    /**
933     * State of external call telling us if the lock screen is shown.
934     */
935    private boolean mLockScreenShown = false;
936
937    /**
938     * Set if we are shutting down the system, similar to sleeping.
939     */
940    boolean mShuttingDown = false;
941
942    /**
943     * Current sequence id for oom_adj computation traversal.
944     */
945    int mAdjSeq = 0;
946
947    /**
948     * Current sequence id for process LRU updating.
949     */
950    int mLruSeq = 0;
951
952    /**
953     * Keep track of the non-cached/empty process we last found, to help
954     * determine how to distribute cached/empty processes next time.
955     */
956    int mNumNonCachedProcs = 0;
957
958    /**
959     * Keep track of the number of cached hidden procs, to balance oom adj
960     * distribution between those and empty procs.
961     */
962    int mNumCachedHiddenProcs = 0;
963
964    /**
965     * Keep track of the number of service processes we last found, to
966     * determine on the next iteration which should be B services.
967     */
968    int mNumServiceProcs = 0;
969    int mNewNumAServiceProcs = 0;
970    int mNewNumServiceProcs = 0;
971
972    /**
973     * Allow the current computed overall memory level of the system to go down?
974     * This is set to false when we are killing processes for reasons other than
975     * memory management, so that the now smaller process list will not be taken as
976     * an indication that memory is tighter.
977     */
978    boolean mAllowLowerMemLevel = false;
979
980    /**
981     * The last computed memory level, for holding when we are in a state that
982     * processes are going away for other reasons.
983     */
984    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
985
986    /**
987     * The last total number of process we have, to determine if changes actually look
988     * like a shrinking number of process due to lower RAM.
989     */
990    int mLastNumProcesses;
991
992    /**
993     * The uptime of the last time we performed idle maintenance.
994     */
995    long mLastIdleTime = SystemClock.uptimeMillis();
996
997    /**
998     * Total time spent with RAM that has been added in the past since the last idle time.
999     */
1000    long mLowRamTimeSinceLastIdle = 0;
1001
1002    /**
1003     * If RAM is currently low, when that horrible situation started.
1004     */
1005    long mLowRamStartTime = 0;
1006
1007    /**
1008     * For reporting to battery stats the current top application.
1009     */
1010    private String mCurResumedPackage = null;
1011    private int mCurResumedUid = -1;
1012
1013    /**
1014     * For reporting to battery stats the apps currently running foreground
1015     * service.  The ProcessMap is package/uid tuples; each of these contain
1016     * an array of the currently foreground processes.
1017     */
1018    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1019            = new ProcessMap<ArrayList<ProcessRecord>>();
1020
1021    /**
1022     * This is set if we had to do a delayed dexopt of an app before launching
1023     * it, to increase the ANR timeouts in that case.
1024     */
1025    boolean mDidDexOpt;
1026
1027    /**
1028     * Set if the systemServer made a call to enterSafeMode.
1029     */
1030    boolean mSafeMode;
1031
1032    String mDebugApp = null;
1033    boolean mWaitForDebugger = false;
1034    boolean mDebugTransient = false;
1035    String mOrigDebugApp = null;
1036    boolean mOrigWaitForDebugger = false;
1037    boolean mAlwaysFinishActivities = false;
1038    IActivityController mController = null;
1039    String mProfileApp = null;
1040    ProcessRecord mProfileProc = null;
1041    String mProfileFile;
1042    ParcelFileDescriptor mProfileFd;
1043    int mProfileType = 0;
1044    boolean mAutoStopProfiler = false;
1045    String mOpenGlTraceApp = null;
1046
1047    static class ProcessChangeItem {
1048        static final int CHANGE_ACTIVITIES = 1<<0;
1049        static final int CHANGE_PROCESS_STATE = 1<<1;
1050        int changes;
1051        int uid;
1052        int pid;
1053        int processState;
1054        boolean foregroundActivities;
1055    }
1056
1057    final RemoteCallbackList<IProcessObserver> mProcessObservers
1058            = new RemoteCallbackList<IProcessObserver>();
1059    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1060
1061    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1062            = new ArrayList<ProcessChangeItem>();
1063    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1064            = new ArrayList<ProcessChangeItem>();
1065
1066    /**
1067     * Runtime CPU use collection thread.  This object's lock is used to
1068     * protect all related state.
1069     */
1070    final Thread mProcessCpuThread;
1071
1072    /**
1073     * Used to collect process stats when showing not responding dialog.
1074     * Protected by mProcessCpuThread.
1075     */
1076    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1077            MONITOR_THREAD_CPU_USAGE);
1078    final AtomicLong mLastCpuTime = new AtomicLong(0);
1079    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1080
1081    long mLastWriteTime = 0;
1082
1083    /**
1084     * Used to retain an update lock when the foreground activity is in
1085     * immersive mode.
1086     */
1087    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1088
1089    /**
1090     * Set to true after the system has finished booting.
1091     */
1092    boolean mBooted = false;
1093
1094    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1095    int mProcessLimitOverride = -1;
1096
1097    WindowManagerService mWindowManager;
1098
1099    final ActivityThread mSystemThread;
1100
1101    int mCurrentUserId = 0;
1102    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1103    private UserManagerService mUserManager;
1104
1105    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1106        final ProcessRecord mApp;
1107        final int mPid;
1108        final IApplicationThread mAppThread;
1109
1110        AppDeathRecipient(ProcessRecord app, int pid,
1111                IApplicationThread thread) {
1112            if (localLOGV) Slog.v(
1113                TAG, "New death recipient " + this
1114                + " for thread " + thread.asBinder());
1115            mApp = app;
1116            mPid = pid;
1117            mAppThread = thread;
1118        }
1119
1120        @Override
1121        public void binderDied() {
1122            if (localLOGV) Slog.v(
1123                TAG, "Death received in " + this
1124                + " for thread " + mAppThread.asBinder());
1125            synchronized(ActivityManagerService.this) {
1126                appDiedLocked(mApp, mPid, mAppThread);
1127            }
1128        }
1129    }
1130
1131    static final int SHOW_ERROR_MSG = 1;
1132    static final int SHOW_NOT_RESPONDING_MSG = 2;
1133    static final int SHOW_FACTORY_ERROR_MSG = 3;
1134    static final int UPDATE_CONFIGURATION_MSG = 4;
1135    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1136    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1137    static final int SERVICE_TIMEOUT_MSG = 12;
1138    static final int UPDATE_TIME_ZONE = 13;
1139    static final int SHOW_UID_ERROR_MSG = 14;
1140    static final int IM_FEELING_LUCKY_MSG = 15;
1141    static final int PROC_START_TIMEOUT_MSG = 20;
1142    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1143    static final int KILL_APPLICATION_MSG = 22;
1144    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1145    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1146    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1147    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1148    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1149    static final int CLEAR_DNS_CACHE_MSG = 28;
1150    static final int UPDATE_HTTP_PROXY_MSG = 29;
1151    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1152    static final int DISPATCH_PROCESSES_CHANGED = 31;
1153    static final int DISPATCH_PROCESS_DIED = 32;
1154    static final int REPORT_MEM_USAGE_MSG = 33;
1155    static final int REPORT_USER_SWITCH_MSG = 34;
1156    static final int CONTINUE_USER_SWITCH_MSG = 35;
1157    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1158    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1159    static final int PERSIST_URI_GRANTS_MSG = 38;
1160    static final int REQUEST_ALL_PSS_MSG = 39;
1161    static final int START_PROFILES_MSG = 40;
1162    static final int UPDATE_TIME = 41;
1163    static final int SYSTEM_USER_START_MSG = 42;
1164    static final int SYSTEM_USER_CURRENT_MSG = 43;
1165
1166    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1167    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1168    static final int FIRST_COMPAT_MODE_MSG = 300;
1169    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1170
1171    AlertDialog mUidAlert;
1172    CompatModeDialog mCompatModeDialog;
1173    long mLastMemUsageReportTime = 0;
1174
1175    private LockToAppRequestDialog mLockToAppRequest;
1176
1177    /**
1178     * Flag whether the current user is a "monkey", i.e. whether
1179     * the UI is driven by a UI automation tool.
1180     */
1181    private boolean mUserIsMonkey;
1182
1183    final ServiceThread mHandlerThread;
1184    final MainHandler mHandler;
1185
1186    final class MainHandler extends Handler {
1187        public MainHandler(Looper looper) {
1188            super(looper, null, true);
1189        }
1190
1191        @Override
1192        public void handleMessage(Message msg) {
1193            switch (msg.what) {
1194            case SHOW_ERROR_MSG: {
1195                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1196                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1197                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1198                synchronized (ActivityManagerService.this) {
1199                    ProcessRecord proc = (ProcessRecord)data.get("app");
1200                    AppErrorResult res = (AppErrorResult) data.get("result");
1201                    if (proc != null && proc.crashDialog != null) {
1202                        Slog.e(TAG, "App already has crash dialog: " + proc);
1203                        if (res != null) {
1204                            res.set(0);
1205                        }
1206                        return;
1207                    }
1208                    if (!showBackground && UserHandle.getAppId(proc.uid)
1209                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1210                            && proc.pid != MY_PID) {
1211                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1212                        if (res != null) {
1213                            res.set(0);
1214                        }
1215                        return;
1216                    }
1217                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1218                        Dialog d = new AppErrorDialog(mContext,
1219                                ActivityManagerService.this, res, proc);
1220                        d.show();
1221                        proc.crashDialog = d;
1222                    } else {
1223                        // The device is asleep, so just pretend that the user
1224                        // saw a crash dialog and hit "force quit".
1225                        if (res != null) {
1226                            res.set(0);
1227                        }
1228                    }
1229                }
1230
1231                ensureBootCompleted();
1232            } break;
1233            case SHOW_NOT_RESPONDING_MSG: {
1234                synchronized (ActivityManagerService.this) {
1235                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    if (proc != null && proc.anrDialog != null) {
1238                        Slog.e(TAG, "App already has anr dialog: " + proc);
1239                        return;
1240                    }
1241
1242                    Intent intent = new Intent("android.intent.action.ANR");
1243                    if (!mProcessesReady) {
1244                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1245                                | Intent.FLAG_RECEIVER_FOREGROUND);
1246                    }
1247                    broadcastIntentLocked(null, null, intent,
1248                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1249                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1250
1251                    if (mShowDialogs) {
1252                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1253                                mContext, proc, (ActivityRecord)data.get("activity"),
1254                                msg.arg1 != 0);
1255                        d.show();
1256                        proc.anrDialog = d;
1257                    } else {
1258                        // Just kill the app if there is no dialog to be shown.
1259                        killAppAtUsersRequest(proc, null);
1260                    }
1261                }
1262
1263                ensureBootCompleted();
1264            } break;
1265            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1266                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                synchronized (ActivityManagerService.this) {
1268                    ProcessRecord proc = (ProcessRecord) data.get("app");
1269                    if (proc == null) {
1270                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1271                        break;
1272                    }
1273                    if (proc.crashDialog != null) {
1274                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1275                        return;
1276                    }
1277                    AppErrorResult res = (AppErrorResult) data.get("result");
1278                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1279                        Dialog d = new StrictModeViolationDialog(mContext,
1280                                ActivityManagerService.this, res, proc);
1281                        d.show();
1282                        proc.crashDialog = d;
1283                    } else {
1284                        // The device is asleep, so just pretend that the user
1285                        // saw a crash dialog and hit "force quit".
1286                        res.set(0);
1287                    }
1288                }
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_FACTORY_ERROR_MSG: {
1292                Dialog d = new FactoryErrorDialog(
1293                    mContext, msg.getData().getCharSequence("msg"));
1294                d.show();
1295                ensureBootCompleted();
1296            } break;
1297            case UPDATE_CONFIGURATION_MSG: {
1298                final ContentResolver resolver = mContext.getContentResolver();
1299                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1300            } break;
1301            case GC_BACKGROUND_PROCESSES_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    performAppGcsIfAppropriateLocked();
1304                }
1305            } break;
1306            case WAIT_FOR_DEBUGGER_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    ProcessRecord app = (ProcessRecord)msg.obj;
1309                    if (msg.arg1 != 0) {
1310                        if (!app.waitedForDebugger) {
1311                            Dialog d = new AppWaitingForDebuggerDialog(
1312                                    ActivityManagerService.this,
1313                                    mContext, app);
1314                            app.waitDialog = d;
1315                            app.waitedForDebugger = true;
1316                            d.show();
1317                        }
1318                    } else {
1319                        if (app.waitDialog != null) {
1320                            app.waitDialog.dismiss();
1321                            app.waitDialog = null;
1322                        }
1323                    }
1324                }
1325            } break;
1326            case SERVICE_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1332                    return;
1333                }
1334                mServices.serviceTimeout((ProcessRecord)msg.obj);
1335            } break;
1336            case UPDATE_TIME_ZONE: {
1337                synchronized (ActivityManagerService.this) {
1338                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1339                        ProcessRecord r = mLruProcesses.get(i);
1340                        if (r.thread != null) {
1341                            try {
1342                                r.thread.updateTimeZone();
1343                            } catch (RemoteException ex) {
1344                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1345                            }
1346                        }
1347                    }
1348                }
1349            } break;
1350            case CLEAR_DNS_CACHE_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1353                        ProcessRecord r = mLruProcesses.get(i);
1354                        if (r.thread != null) {
1355                            try {
1356                                r.thread.clearDnsCache();
1357                            } catch (RemoteException ex) {
1358                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1359                            }
1360                        }
1361                    }
1362                }
1363            } break;
1364            case UPDATE_HTTP_PROXY_MSG: {
1365                ProxyInfo proxy = (ProxyInfo)msg.obj;
1366                String host = "";
1367                String port = "";
1368                String exclList = "";
1369                Uri pacFileUrl = Uri.EMPTY;
1370                if (proxy != null) {
1371                    host = proxy.getHost();
1372                    port = Integer.toString(proxy.getPort());
1373                    exclList = proxy.getExclusionListAsString();
1374                    pacFileUrl = proxy.getPacFileUrl();
1375                }
1376                synchronized (ActivityManagerService.this) {
1377                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1378                        ProcessRecord r = mLruProcesses.get(i);
1379                        if (r.thread != null) {
1380                            try {
1381                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1382                            } catch (RemoteException ex) {
1383                                Slog.w(TAG, "Failed to update http proxy for: " +
1384                                        r.info.processName);
1385                            }
1386                        }
1387                    }
1388                }
1389            } break;
1390            case SHOW_UID_ERROR_MSG: {
1391                String title = "System UIDs Inconsistent";
1392                String text = "UIDs on the system are inconsistent, you need to wipe your"
1393                        + " data partition or your device will be unstable.";
1394                Log.e(TAG, title + ": " + text);
1395                if (mShowDialogs) {
1396                    // XXX This is a temporary dialog, no need to localize.
1397                    AlertDialog d = new BaseErrorDialog(mContext);
1398                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1399                    d.setCancelable(false);
1400                    d.setTitle(title);
1401                    d.setMessage(text);
1402                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1403                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1404                    mUidAlert = d;
1405                    d.show();
1406                }
1407            } break;
1408            case IM_FEELING_LUCKY_MSG: {
1409                if (mUidAlert != null) {
1410                    mUidAlert.dismiss();
1411                    mUidAlert = null;
1412                }
1413            } break;
1414            case PROC_START_TIMEOUT_MSG: {
1415                if (mDidDexOpt) {
1416                    mDidDexOpt = false;
1417                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1418                    nmsg.obj = msg.obj;
1419                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1420                    return;
1421                }
1422                ProcessRecord app = (ProcessRecord)msg.obj;
1423                synchronized (ActivityManagerService.this) {
1424                    processStartTimedOutLocked(app);
1425                }
1426            } break;
1427            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    doPendingActivityLaunchesLocked(true);
1430                }
1431            } break;
1432            case KILL_APPLICATION_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    int appid = msg.arg1;
1435                    boolean restart = (msg.arg2 == 1);
1436                    Bundle bundle = (Bundle)msg.obj;
1437                    String pkg = bundle.getString("pkg");
1438                    String reason = bundle.getString("reason");
1439                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1440                            false, UserHandle.USER_ALL, reason);
1441                }
1442            } break;
1443            case FINALIZE_PENDING_INTENT_MSG: {
1444                ((PendingIntentRecord)msg.obj).completeFinalize();
1445            } break;
1446            case POST_HEAVY_NOTIFICATION_MSG: {
1447                INotificationManager inm = NotificationManager.getService();
1448                if (inm == null) {
1449                    return;
1450                }
1451
1452                ActivityRecord root = (ActivityRecord)msg.obj;
1453                ProcessRecord process = root.app;
1454                if (process == null) {
1455                    return;
1456                }
1457
1458                try {
1459                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1460                    String text = mContext.getString(R.string.heavy_weight_notification,
1461                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1462                    Notification notification = new Notification();
1463                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1464                    notification.when = 0;
1465                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1466                    notification.tickerText = text;
1467                    notification.defaults = 0; // please be quiet
1468                    notification.sound = null;
1469                    notification.vibrate = null;
1470                    notification.setLatestEventInfo(context, text,
1471                            mContext.getText(R.string.heavy_weight_notification_detail),
1472                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1473                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1474                                    new UserHandle(root.userId)));
1475
1476                    try {
1477                        int[] outId = new int[1];
1478                        inm.enqueueNotificationWithTag("android", "android", null,
1479                                R.string.heavy_weight_notification,
1480                                notification, outId, root.userId);
1481                    } catch (RuntimeException e) {
1482                        Slog.w(ActivityManagerService.TAG,
1483                                "Error showing notification for heavy-weight app", e);
1484                    } catch (RemoteException e) {
1485                    }
1486                } catch (NameNotFoundException e) {
1487                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1488                }
1489            } break;
1490            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1491                INotificationManager inm = NotificationManager.getService();
1492                if (inm == null) {
1493                    return;
1494                }
1495                try {
1496                    inm.cancelNotificationWithTag("android", null,
1497                            R.string.heavy_weight_notification,  msg.arg1);
1498                } catch (RuntimeException e) {
1499                    Slog.w(ActivityManagerService.TAG,
1500                            "Error canceling notification for service", e);
1501                } catch (RemoteException e) {
1502                }
1503            } break;
1504            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1505                synchronized (ActivityManagerService.this) {
1506                    checkExcessivePowerUsageLocked(true);
1507                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1508                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1510                }
1511            } break;
1512            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1513                synchronized (ActivityManagerService.this) {
1514                    ActivityRecord ar = (ActivityRecord)msg.obj;
1515                    if (mCompatModeDialog != null) {
1516                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1517                                ar.info.applicationInfo.packageName)) {
1518                            return;
1519                        }
1520                        mCompatModeDialog.dismiss();
1521                        mCompatModeDialog = null;
1522                    }
1523                    if (ar != null && false) {
1524                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1525                                ar.packageName)) {
1526                            int mode = mCompatModePackages.computeCompatModeLocked(
1527                                    ar.info.applicationInfo);
1528                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1529                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1530                                mCompatModeDialog = new CompatModeDialog(
1531                                        ActivityManagerService.this, mContext,
1532                                        ar.info.applicationInfo);
1533                                mCompatModeDialog.show();
1534                            }
1535                        }
1536                    }
1537                }
1538                break;
1539            }
1540            case DISPATCH_PROCESSES_CHANGED: {
1541                dispatchProcessesChanged();
1542                break;
1543            }
1544            case DISPATCH_PROCESS_DIED: {
1545                final int pid = msg.arg1;
1546                final int uid = msg.arg2;
1547                dispatchProcessDied(pid, uid);
1548                break;
1549            }
1550            case REPORT_MEM_USAGE_MSG: {
1551                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1552                Thread thread = new Thread() {
1553                    @Override public void run() {
1554                        final SparseArray<ProcessMemInfo> infoMap
1555                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1556                        for (int i=0, N=memInfos.size(); i<N; i++) {
1557                            ProcessMemInfo mi = memInfos.get(i);
1558                            infoMap.put(mi.pid, mi);
1559                        }
1560                        updateCpuStatsNow();
1561                        synchronized (mProcessCpuThread) {
1562                            final int N = mProcessCpuTracker.countStats();
1563                            for (int i=0; i<N; i++) {
1564                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1565                                if (st.vsize > 0) {
1566                                    long pss = Debug.getPss(st.pid, null);
1567                                    if (pss > 0) {
1568                                        if (infoMap.indexOfKey(st.pid) < 0) {
1569                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1570                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1571                                            mi.pss = pss;
1572                                            memInfos.add(mi);
1573                                        }
1574                                    }
1575                                }
1576                            }
1577                        }
1578
1579                        long totalPss = 0;
1580                        for (int i=0, N=memInfos.size(); i<N; i++) {
1581                            ProcessMemInfo mi = memInfos.get(i);
1582                            if (mi.pss == 0) {
1583                                mi.pss = Debug.getPss(mi.pid, null);
1584                            }
1585                            totalPss += mi.pss;
1586                        }
1587                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1588                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1589                                if (lhs.oomAdj != rhs.oomAdj) {
1590                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1591                                }
1592                                if (lhs.pss != rhs.pss) {
1593                                    return lhs.pss < rhs.pss ? 1 : -1;
1594                                }
1595                                return 0;
1596                            }
1597                        });
1598
1599                        StringBuilder tag = new StringBuilder(128);
1600                        StringBuilder stack = new StringBuilder(128);
1601                        tag.append("Low on memory -- ");
1602                        appendMemBucket(tag, totalPss, "total", false);
1603                        appendMemBucket(stack, totalPss, "total", true);
1604
1605                        StringBuilder logBuilder = new StringBuilder(1024);
1606                        logBuilder.append("Low on memory:\n");
1607
1608                        boolean firstLine = true;
1609                        int lastOomAdj = Integer.MIN_VALUE;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612
1613                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1614                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1615                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1616                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1617                                if (lastOomAdj != mi.oomAdj) {
1618                                    lastOomAdj = mi.oomAdj;
1619                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                        tag.append(" / ");
1621                                    }
1622                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1623                                        if (firstLine) {
1624                                            stack.append(":");
1625                                            firstLine = false;
1626                                        }
1627                                        stack.append("\n\t at ");
1628                                    } else {
1629                                        stack.append("$");
1630                                    }
1631                                } else {
1632                                    tag.append(" ");
1633                                    stack.append("$");
1634                                }
1635                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1636                                    appendMemBucket(tag, mi.pss, mi.name, false);
1637                                }
1638                                appendMemBucket(stack, mi.pss, mi.name, true);
1639                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1640                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1641                                    stack.append("(");
1642                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1643                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1644                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1645                                            stack.append(":");
1646                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1647                                        }
1648                                    }
1649                                    stack.append(")");
1650                                }
1651                            }
1652
1653                            logBuilder.append("  ");
1654                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1655                            logBuilder.append(' ');
1656                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1657                            logBuilder.append(' ');
1658                            ProcessList.appendRamKb(logBuilder, mi.pss);
1659                            logBuilder.append(" kB: ");
1660                            logBuilder.append(mi.name);
1661                            logBuilder.append(" (");
1662                            logBuilder.append(mi.pid);
1663                            logBuilder.append(") ");
1664                            logBuilder.append(mi.adjType);
1665                            logBuilder.append('\n');
1666                            if (mi.adjReason != null) {
1667                                logBuilder.append("                      ");
1668                                logBuilder.append(mi.adjReason);
1669                                logBuilder.append('\n');
1670                            }
1671                        }
1672
1673                        logBuilder.append("           ");
1674                        ProcessList.appendRamKb(logBuilder, totalPss);
1675                        logBuilder.append(" kB: TOTAL\n");
1676
1677                        long[] infos = new long[Debug.MEMINFO_COUNT];
1678                        Debug.getMemInfo(infos);
1679                        logBuilder.append("  MemInfo: ");
1680                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1685                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1686                            logBuilder.append("  ZRAM: ");
1687                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1688                            logBuilder.append(" kB RAM, ");
1689                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1690                            logBuilder.append(" kB swap total, ");
1691                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1692                            logBuilder.append(" kB swap free\n");
1693                        }
1694                        Slog.i(TAG, logBuilder.toString());
1695
1696                        StringBuilder dropBuilder = new StringBuilder(1024);
1697                        /*
1698                        StringWriter oomSw = new StringWriter();
1699                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1700                        StringWriter catSw = new StringWriter();
1701                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                        String[] emptyArgs = new String[] { };
1703                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1704                        oomPw.flush();
1705                        String oomString = oomSw.toString();
1706                        */
1707                        dropBuilder.append(stack);
1708                        dropBuilder.append('\n');
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append(logBuilder);
1711                        dropBuilder.append('\n');
1712                        /*
1713                        dropBuilder.append(oomString);
1714                        dropBuilder.append('\n');
1715                        */
1716                        StringWriter catSw = new StringWriter();
1717                        synchronized (ActivityManagerService.this) {
1718                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1719                            String[] emptyArgs = new String[] { };
1720                            catPw.println();
1721                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1722                            catPw.println();
1723                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1724                                    false, false, null);
1725                            catPw.println();
1726                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1727                            catPw.flush();
1728                        }
1729                        dropBuilder.append(catSw.toString());
1730                        addErrorToDropBox("lowmem", null, "system_server", null,
1731                                null, tag.toString(), dropBuilder.toString(), null, null);
1732                        //Slog.i(TAG, "Sent to dropbox:");
1733                        //Slog.i(TAG, dropBuilder.toString());
1734                        synchronized (ActivityManagerService.this) {
1735                            long now = SystemClock.uptimeMillis();
1736                            if (mLastMemUsageReportTime < now) {
1737                                mLastMemUsageReportTime = now;
1738                            }
1739                        }
1740                    }
1741                };
1742                thread.start();
1743                break;
1744            }
1745            case REPORT_USER_SWITCH_MSG: {
1746                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1747                break;
1748            }
1749            case CONTINUE_USER_SWITCH_MSG: {
1750                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1751                break;
1752            }
1753            case USER_SWITCH_TIMEOUT_MSG: {
1754                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1755                break;
1756            }
1757            case IMMERSIVE_MODE_LOCK_MSG: {
1758                final boolean nextState = (msg.arg1 != 0);
1759                if (mUpdateLock.isHeld() != nextState) {
1760                    if (DEBUG_IMMERSIVE) {
1761                        final ActivityRecord r = (ActivityRecord) msg.obj;
1762                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1763                    }
1764                    if (nextState) {
1765                        mUpdateLock.acquire();
1766                    } else {
1767                        mUpdateLock.release();
1768                    }
1769                }
1770                break;
1771            }
1772            case PERSIST_URI_GRANTS_MSG: {
1773                writeGrantedUriPermissions();
1774                break;
1775            }
1776            case REQUEST_ALL_PSS_MSG: {
1777                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1778                break;
1779            }
1780            case START_PROFILES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    startProfilesLocked();
1783                }
1784                break;
1785            }
1786            case UPDATE_TIME: {
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799                break;
1800            }
1801            case SYSTEM_USER_START_MSG: {
1802                mSystemServiceManager.startUser(msg.arg1);
1803                break;
1804            }
1805            case SYSTEM_USER_CURRENT_MSG: {
1806                mSystemServiceManager.switchUser(msg.arg1);
1807                break;
1808            }
1809            }
1810        }
1811    };
1812
1813    static final int COLLECT_PSS_BG_MSG = 1;
1814
1815    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1816        @Override
1817        public void handleMessage(Message msg) {
1818            switch (msg.what) {
1819            case COLLECT_PSS_BG_MSG: {
1820                long start = SystemClock.uptimeMillis();
1821                MemInfoReader memInfo = null;
1822                synchronized (ActivityManagerService.this) {
1823                    if (mFullPssPending) {
1824                        mFullPssPending = false;
1825                        memInfo = new MemInfoReader();
1826                    }
1827                }
1828                if (memInfo != null) {
1829                    updateCpuStatsNow();
1830                    long nativeTotalPss = 0;
1831                    synchronized (mProcessCpuThread) {
1832                        final int N = mProcessCpuTracker.countStats();
1833                        for (int j=0; j<N; j++) {
1834                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1835                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID
1836                                    || st.uid == Process.SYSTEM_UID) {
1837                                // This is definitely an application process; skip it.
1838                                continue;
1839                            }
1840                            synchronized (mPidsSelfLocked) {
1841                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1842                                    // This is one of our own processes; skip it.
1843                                    continue;
1844                                }
1845                            }
1846                            nativeTotalPss += Debug.getPss(st.pid, null);
1847                        }
1848                    }
1849                    memInfo.readMemInfo();
1850                    synchronized (this) {
1851                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1852                                + (SystemClock.uptimeMillis()-start) + "ms");
1853                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1854                                memInfo.getFreeSizeKb(),
1855                                memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
1856                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1857                                        +memInfo.getSlabSizeKb(),
1858                                nativeTotalPss);
1859                    }
1860                }
1861
1862                int i=0, num=0;
1863                long[] tmp = new long[1];
1864                do {
1865                    ProcessRecord proc;
1866                    int procState;
1867                    int pid;
1868                    synchronized (ActivityManagerService.this) {
1869                        if (i >= mPendingPssProcesses.size()) {
1870                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1871                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1872                            mPendingPssProcesses.clear();
1873                            return;
1874                        }
1875                        proc = mPendingPssProcesses.get(i);
1876                        procState = proc.pssProcState;
1877                        if (proc.thread != null && procState == proc.setProcState) {
1878                            pid = proc.pid;
1879                        } else {
1880                            proc = null;
1881                            pid = 0;
1882                        }
1883                        i++;
1884                    }
1885                    if (proc != null) {
1886                        long pss = Debug.getPss(pid, tmp);
1887                        synchronized (ActivityManagerService.this) {
1888                            if (proc.thread != null && proc.setProcState == procState
1889                                    && proc.pid == pid) {
1890                                num++;
1891                                proc.lastPssTime = SystemClock.uptimeMillis();
1892                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1893                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1894                                        + ": " + pss + " lastPss=" + proc.lastPss
1895                                        + " state=" + ProcessList.makeProcStateString(procState));
1896                                if (proc.initialIdlePss == 0) {
1897                                    proc.initialIdlePss = pss;
1898                                }
1899                                proc.lastPss = pss;
1900                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1901                                    proc.lastCachedPss = pss;
1902                                }
1903                            }
1904                        }
1905                    }
1906                } while (true);
1907            }
1908            }
1909        }
1910    };
1911
1912    /**
1913     * Monitor for package changes and update our internal state.
1914     */
1915    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1916        @Override
1917        public void onPackageRemoved(String packageName, int uid) {
1918            // Remove all tasks with activities in the specified package from the list of recent tasks
1919            synchronized (ActivityManagerService.this) {
1920                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1921                    TaskRecord tr = mRecentTasks.get(i);
1922                    ComponentName cn = tr.intent.getComponent();
1923                    if (cn != null && cn.getPackageName().equals(packageName)) {
1924                        // If the package name matches, remove the task and kill the process
1925                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1926                    }
1927                }
1928            }
1929        }
1930
1931        @Override
1932        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1933            onPackageModified(packageName);
1934            return true;
1935        }
1936
1937        @Override
1938        public void onPackageModified(String packageName) {
1939            final PackageManager pm = mContext.getPackageManager();
1940            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1941                    new ArrayList<Pair<Intent, Integer>>();
1942            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1943            // Copy the list of recent tasks so that we don't hold onto the lock on
1944            // ActivityManagerService for long periods while checking if components exist.
1945            synchronized (ActivityManagerService.this) {
1946                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1947                    TaskRecord tr = mRecentTasks.get(i);
1948                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1949                }
1950            }
1951            // Check the recent tasks and filter out all tasks with components that no longer exist.
1952            Intent tmpI = new Intent();
1953            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1954                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1955                ComponentName cn = p.first.getComponent();
1956                if (cn != null && cn.getPackageName().equals(packageName)) {
1957                    try {
1958                        // Add the task to the list to remove if the component no longer exists
1959                        tmpI.setComponent(cn);
1960                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1961                            tasksToRemove.add(p.second);
1962                        }
1963                    } catch (Exception e) {}
1964                }
1965            }
1966            // Prune all the tasks with removed components from the list of recent tasks
1967            synchronized (ActivityManagerService.this) {
1968                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1969                    // Remove the task but don't kill the process (since other components in that
1970                    // package may still be running and in the background)
1971                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1972                }
1973            }
1974        }
1975
1976        @Override
1977        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1978            // Force stop the specified packages
1979            if (packages != null) {
1980                for (String pkg : packages) {
1981                    synchronized (ActivityManagerService.this) {
1982                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1983                                "finished booting")) {
1984                            return true;
1985                        }
1986                    }
1987                }
1988            }
1989            return false;
1990        }
1991    };
1992
1993    public void setSystemProcess() {
1994        try {
1995            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1996            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1997            ServiceManager.addService("meminfo", new MemBinder(this));
1998            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1999            ServiceManager.addService("dbinfo", new DbBinder(this));
2000            if (MONITOR_CPU_USAGE) {
2001                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2002            }
2003            ServiceManager.addService("permission", new PermissionController(this));
2004
2005            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2006                    "android", STOCK_PM_FLAGS);
2007            mSystemThread.installSystemApplicationInfo(info);
2008
2009            synchronized (this) {
2010                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2011                app.persistent = true;
2012                app.pid = MY_PID;
2013                app.maxAdj = ProcessList.SYSTEM_ADJ;
2014                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2015                mProcessNames.put(app.processName, app.uid, app);
2016                synchronized (mPidsSelfLocked) {
2017                    mPidsSelfLocked.put(app.pid, app);
2018                }
2019                updateLruProcessLocked(app, false, null);
2020                updateOomAdjLocked();
2021            }
2022        } catch (PackageManager.NameNotFoundException e) {
2023            throw new RuntimeException(
2024                    "Unable to find android system package", e);
2025        }
2026    }
2027
2028    public void setWindowManager(WindowManagerService wm) {
2029        mWindowManager = wm;
2030        mStackSupervisor.setWindowManager(wm);
2031    }
2032
2033    public void startObservingNativeCrashes() {
2034        final NativeCrashListener ncl = new NativeCrashListener(this);
2035        ncl.start();
2036    }
2037
2038    public IAppOpsService getAppOpsService() {
2039        return mAppOpsService;
2040    }
2041
2042    static class MemBinder extends Binder {
2043        ActivityManagerService mActivityManagerService;
2044        MemBinder(ActivityManagerService activityManagerService) {
2045            mActivityManagerService = activityManagerService;
2046        }
2047
2048        @Override
2049        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2050            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2051                    != PackageManager.PERMISSION_GRANTED) {
2052                pw.println("Permission Denial: can't dump meminfo from from pid="
2053                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2054                        + " without permission " + android.Manifest.permission.DUMP);
2055                return;
2056            }
2057
2058            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2059        }
2060    }
2061
2062    static class GraphicsBinder extends Binder {
2063        ActivityManagerService mActivityManagerService;
2064        GraphicsBinder(ActivityManagerService activityManagerService) {
2065            mActivityManagerService = activityManagerService;
2066        }
2067
2068        @Override
2069        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2070            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2071                    != PackageManager.PERMISSION_GRANTED) {
2072                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2073                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2074                        + " without permission " + android.Manifest.permission.DUMP);
2075                return;
2076            }
2077
2078            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2079        }
2080    }
2081
2082    static class DbBinder extends Binder {
2083        ActivityManagerService mActivityManagerService;
2084        DbBinder(ActivityManagerService activityManagerService) {
2085            mActivityManagerService = activityManagerService;
2086        }
2087
2088        @Override
2089        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2090            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2091                    != PackageManager.PERMISSION_GRANTED) {
2092                pw.println("Permission Denial: can't dump dbinfo from from pid="
2093                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2094                        + " without permission " + android.Manifest.permission.DUMP);
2095                return;
2096            }
2097
2098            mActivityManagerService.dumpDbInfo(fd, pw, args);
2099        }
2100    }
2101
2102    static class CpuBinder extends Binder {
2103        ActivityManagerService mActivityManagerService;
2104        CpuBinder(ActivityManagerService activityManagerService) {
2105            mActivityManagerService = activityManagerService;
2106        }
2107
2108        @Override
2109        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2110            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2111                    != PackageManager.PERMISSION_GRANTED) {
2112                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2113                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2114                        + " without permission " + android.Manifest.permission.DUMP);
2115                return;
2116            }
2117
2118            synchronized (mActivityManagerService.mProcessCpuThread) {
2119                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2120                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2121                        SystemClock.uptimeMillis()));
2122            }
2123        }
2124    }
2125
2126    public static final class Lifecycle extends SystemService {
2127        private final ActivityManagerService mService;
2128
2129        public Lifecycle(Context context) {
2130            super(context);
2131            mService = new ActivityManagerService(context);
2132        }
2133
2134        @Override
2135        public void onStart() {
2136            mService.start();
2137        }
2138
2139        public ActivityManagerService getService() {
2140            return mService;
2141        }
2142    }
2143
2144    // Note: This method is invoked on the main thread but may need to attach various
2145    // handlers to other threads.  So take care to be explicit about the looper.
2146    public ActivityManagerService(Context systemContext) {
2147        mContext = systemContext;
2148        mFactoryTest = FactoryTest.getMode();
2149        mSystemThread = ActivityThread.currentActivityThread();
2150
2151        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2152
2153        mHandlerThread = new ServiceThread(TAG,
2154                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2155        mHandlerThread.start();
2156        mHandler = new MainHandler(mHandlerThread.getLooper());
2157
2158        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2159                "foreground", BROADCAST_FG_TIMEOUT, false);
2160        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2161                "background", BROADCAST_BG_TIMEOUT, true);
2162        mBroadcastQueues[0] = mFgBroadcastQueue;
2163        mBroadcastQueues[1] = mBgBroadcastQueue;
2164
2165        mServices = new ActiveServices(this);
2166        mProviderMap = new ProviderMap(this);
2167
2168        // TODO: Move creation of battery stats service outside of activity manager service.
2169        File dataDir = Environment.getDataDirectory();
2170        File systemDir = new File(dataDir, "system");
2171        systemDir.mkdirs();
2172        mBatteryStatsService = new BatteryStatsService(new File(
2173                systemDir, "batterystats.bin").toString(), mHandler);
2174        mBatteryStatsService.getActiveStatistics().readLocked();
2175        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2176        mOnBattery = DEBUG_POWER ? true
2177                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2178        mBatteryStatsService.getActiveStatistics().setCallback(this);
2179
2180        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2181
2182        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2183        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2184
2185        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2186
2187        // User 0 is the first and only user that runs at boot.
2188        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2189        mUserLru.add(Integer.valueOf(0));
2190        updateStartedUserArrayLocked();
2191
2192        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2193            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2194
2195        mConfiguration.setToDefaults();
2196        mConfiguration.setLocale(Locale.getDefault());
2197
2198        mConfigurationSeq = mConfiguration.seq = 1;
2199        mProcessCpuTracker.init();
2200
2201        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2202        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2203        mStackSupervisor = new ActivityStackSupervisor(this);
2204        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2205
2206        mProcessCpuThread = new Thread("CpuTracker") {
2207            @Override
2208            public void run() {
2209                while (true) {
2210                    try {
2211                        try {
2212                            synchronized(this) {
2213                                final long now = SystemClock.uptimeMillis();
2214                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2215                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2216                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2217                                //        + ", write delay=" + nextWriteDelay);
2218                                if (nextWriteDelay < nextCpuDelay) {
2219                                    nextCpuDelay = nextWriteDelay;
2220                                }
2221                                if (nextCpuDelay > 0) {
2222                                    mProcessCpuMutexFree.set(true);
2223                                    this.wait(nextCpuDelay);
2224                                }
2225                            }
2226                        } catch (InterruptedException e) {
2227                        }
2228                        updateCpuStatsNow();
2229                    } catch (Exception e) {
2230                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2231                    }
2232                }
2233            }
2234        };
2235
2236        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2237
2238        Watchdog.getInstance().addMonitor(this);
2239        Watchdog.getInstance().addThread(mHandler);
2240    }
2241
2242    public void setSystemServiceManager(SystemServiceManager mgr) {
2243        mSystemServiceManager = mgr;
2244    }
2245
2246    private void start() {
2247        mProcessCpuThread.start();
2248
2249        mBatteryStatsService.publish(mContext);
2250        mUsageStatsService.publish(mContext);
2251        mAppOpsService.publish(mContext);
2252        Slog.d("AppOps", "AppOpsService published");
2253        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2254    }
2255
2256    public void initPowerManagement() {
2257        mStackSupervisor.initPowerManagement();
2258        mBatteryStatsService.initPowerManagement();
2259    }
2260
2261    @Override
2262    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2263            throws RemoteException {
2264        if (code == SYSPROPS_TRANSACTION) {
2265            // We need to tell all apps about the system property change.
2266            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2267            synchronized(this) {
2268                final int NP = mProcessNames.getMap().size();
2269                for (int ip=0; ip<NP; ip++) {
2270                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2271                    final int NA = apps.size();
2272                    for (int ia=0; ia<NA; ia++) {
2273                        ProcessRecord app = apps.valueAt(ia);
2274                        if (app.thread != null) {
2275                            procs.add(app.thread.asBinder());
2276                        }
2277                    }
2278                }
2279            }
2280
2281            int N = procs.size();
2282            for (int i=0; i<N; i++) {
2283                Parcel data2 = Parcel.obtain();
2284                try {
2285                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2286                } catch (RemoteException e) {
2287                }
2288                data2.recycle();
2289            }
2290        }
2291        try {
2292            return super.onTransact(code, data, reply, flags);
2293        } catch (RuntimeException e) {
2294            // The activity manager only throws security exceptions, so let's
2295            // log all others.
2296            if (!(e instanceof SecurityException)) {
2297                Slog.wtf(TAG, "Activity Manager Crash", e);
2298            }
2299            throw e;
2300        }
2301    }
2302
2303    void updateCpuStats() {
2304        final long now = SystemClock.uptimeMillis();
2305        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2306            return;
2307        }
2308        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2309            synchronized (mProcessCpuThread) {
2310                mProcessCpuThread.notify();
2311            }
2312        }
2313    }
2314
2315    void updateCpuStatsNow() {
2316        synchronized (mProcessCpuThread) {
2317            mProcessCpuMutexFree.set(false);
2318            final long now = SystemClock.uptimeMillis();
2319            boolean haveNewCpuStats = false;
2320
2321            if (MONITOR_CPU_USAGE &&
2322                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2323                mLastCpuTime.set(now);
2324                haveNewCpuStats = true;
2325                mProcessCpuTracker.update();
2326                //Slog.i(TAG, mProcessCpu.printCurrentState());
2327                //Slog.i(TAG, "Total CPU usage: "
2328                //        + mProcessCpu.getTotalCpuPercent() + "%");
2329
2330                // Slog the cpu usage if the property is set.
2331                if ("true".equals(SystemProperties.get("events.cpu"))) {
2332                    int user = mProcessCpuTracker.getLastUserTime();
2333                    int system = mProcessCpuTracker.getLastSystemTime();
2334                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2335                    int irq = mProcessCpuTracker.getLastIrqTime();
2336                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2337                    int idle = mProcessCpuTracker.getLastIdleTime();
2338
2339                    int total = user + system + iowait + irq + softIrq + idle;
2340                    if (total == 0) total = 1;
2341
2342                    EventLog.writeEvent(EventLogTags.CPU,
2343                            ((user+system+iowait+irq+softIrq) * 100) / total,
2344                            (user * 100) / total,
2345                            (system * 100) / total,
2346                            (iowait * 100) / total,
2347                            (irq * 100) / total,
2348                            (softIrq * 100) / total);
2349                }
2350            }
2351
2352            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2353            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2354            synchronized(bstats) {
2355                synchronized(mPidsSelfLocked) {
2356                    if (haveNewCpuStats) {
2357                        if (mOnBattery) {
2358                            int perc = bstats.startAddingCpuLocked();
2359                            int totalUTime = 0;
2360                            int totalSTime = 0;
2361                            final int N = mProcessCpuTracker.countStats();
2362                            for (int i=0; i<N; i++) {
2363                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2364                                if (!st.working) {
2365                                    continue;
2366                                }
2367                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2368                                int otherUTime = (st.rel_utime*perc)/100;
2369                                int otherSTime = (st.rel_stime*perc)/100;
2370                                totalUTime += otherUTime;
2371                                totalSTime += otherSTime;
2372                                if (pr != null) {
2373                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2374                                    if (ps == null || !ps.isActive()) {
2375                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2376                                                pr.info.uid, pr.processName);
2377                                    }
2378                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2379                                            st.rel_stime-otherSTime);
2380                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2381                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2382                                } else {
2383                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2384                                    if (ps == null || !ps.isActive()) {
2385                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2386                                                bstats.mapUid(st.uid), st.name);
2387                                    }
2388                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2389                                            st.rel_stime-otherSTime);
2390                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2391                                }
2392                            }
2393                            bstats.finishAddingCpuLocked(perc, totalUTime,
2394                                    totalSTime, cpuSpeedTimes);
2395                        }
2396                    }
2397                }
2398
2399                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2400                    mLastWriteTime = now;
2401                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2402                }
2403            }
2404        }
2405    }
2406
2407    @Override
2408    public void batteryNeedsCpuUpdate() {
2409        updateCpuStatsNow();
2410    }
2411
2412    @Override
2413    public void batteryPowerChanged(boolean onBattery) {
2414        // When plugging in, update the CPU stats first before changing
2415        // the plug state.
2416        updateCpuStatsNow();
2417        synchronized (this) {
2418            synchronized(mPidsSelfLocked) {
2419                mOnBattery = DEBUG_POWER ? true : onBattery;
2420            }
2421        }
2422    }
2423
2424    /**
2425     * Initialize the application bind args. These are passed to each
2426     * process when the bindApplication() IPC is sent to the process. They're
2427     * lazily setup to make sure the services are running when they're asked for.
2428     */
2429    private HashMap<String, IBinder> getCommonServicesLocked() {
2430        if (mAppBindArgs == null) {
2431            mAppBindArgs = new HashMap<String, IBinder>();
2432
2433            // Setup the application init args
2434            mAppBindArgs.put("package", ServiceManager.getService("package"));
2435            mAppBindArgs.put("window", ServiceManager.getService("window"));
2436            mAppBindArgs.put(Context.ALARM_SERVICE,
2437                    ServiceManager.getService(Context.ALARM_SERVICE));
2438        }
2439        return mAppBindArgs;
2440    }
2441
2442    final void setFocusedActivityLocked(ActivityRecord r) {
2443        if (mFocusedActivity != r) {
2444            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2445            mFocusedActivity = r;
2446            if (r.task != null && r.task.voiceInteractor != null) {
2447                startRunningVoiceLocked();
2448            } else {
2449                finishRunningVoiceLocked();
2450            }
2451            mStackSupervisor.setFocusedStack(r);
2452            if (r != null) {
2453                mWindowManager.setFocusedApp(r.appToken, true);
2454            }
2455            applyUpdateLockStateLocked(r);
2456        }
2457    }
2458
2459    final void clearFocusedActivity(ActivityRecord r) {
2460        if (mFocusedActivity == r) {
2461            mFocusedActivity = null;
2462        }
2463    }
2464
2465    @Override
2466    public void setFocusedStack(int stackId) {
2467        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2468        synchronized (ActivityManagerService.this) {
2469            ActivityStack stack = mStackSupervisor.getStack(stackId);
2470            if (stack != null) {
2471                ActivityRecord r = stack.topRunningActivityLocked(null);
2472                if (r != null) {
2473                    setFocusedActivityLocked(r);
2474                }
2475            }
2476        }
2477    }
2478
2479    @Override
2480    public void notifyActivityDrawn(IBinder token) {
2481        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2482        synchronized (this) {
2483            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2484            if (r != null) {
2485                r.task.stack.notifyActivityDrawnLocked(r);
2486            }
2487        }
2488    }
2489
2490    final void applyUpdateLockStateLocked(ActivityRecord r) {
2491        // Modifications to the UpdateLock state are done on our handler, outside
2492        // the activity manager's locks.  The new state is determined based on the
2493        // state *now* of the relevant activity record.  The object is passed to
2494        // the handler solely for logging detail, not to be consulted/modified.
2495        final boolean nextState = r != null && r.immersive;
2496        mHandler.sendMessage(
2497                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2498    }
2499
2500    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2501        Message msg = Message.obtain();
2502        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2503        msg.obj = r.task.askedCompatMode ? null : r;
2504        mHandler.sendMessage(msg);
2505    }
2506
2507    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2508            String what, Object obj, ProcessRecord srcApp) {
2509        app.lastActivityTime = now;
2510
2511        if (app.activities.size() > 0) {
2512            // Don't want to touch dependent processes that are hosting activities.
2513            return index;
2514        }
2515
2516        int lrui = mLruProcesses.lastIndexOf(app);
2517        if (lrui < 0) {
2518            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2519                    + what + " " + obj + " from " + srcApp);
2520            return index;
2521        }
2522
2523        if (lrui >= index) {
2524            // Don't want to cause this to move dependent processes *back* in the
2525            // list as if they were less frequently used.
2526            return index;
2527        }
2528
2529        if (lrui >= mLruProcessActivityStart) {
2530            // Don't want to touch dependent processes that are hosting activities.
2531            return index;
2532        }
2533
2534        mLruProcesses.remove(lrui);
2535        if (index > 0) {
2536            index--;
2537        }
2538        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2539                + " in LRU list: " + app);
2540        mLruProcesses.add(index, app);
2541        return index;
2542    }
2543
2544    final void removeLruProcessLocked(ProcessRecord app) {
2545        int lrui = mLruProcesses.lastIndexOf(app);
2546        if (lrui >= 0) {
2547            if (lrui <= mLruProcessActivityStart) {
2548                mLruProcessActivityStart--;
2549            }
2550            if (lrui <= mLruProcessServiceStart) {
2551                mLruProcessServiceStart--;
2552            }
2553            mLruProcesses.remove(lrui);
2554        }
2555    }
2556
2557    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2558            ProcessRecord client) {
2559        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2560                || app.treatLikeActivity;
2561        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2562        if (!activityChange && hasActivity) {
2563            // The process has activities, so we are only allowing activity-based adjustments
2564            // to move it.  It should be kept in the front of the list with other
2565            // processes that have activities, and we don't want those to change their
2566            // order except due to activity operations.
2567            return;
2568        }
2569
2570        mLruSeq++;
2571        final long now = SystemClock.uptimeMillis();
2572        app.lastActivityTime = now;
2573
2574        // First a quick reject: if the app is already at the position we will
2575        // put it, then there is nothing to do.
2576        if (hasActivity) {
2577            final int N = mLruProcesses.size();
2578            if (N > 0 && mLruProcesses.get(N-1) == app) {
2579                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2580                return;
2581            }
2582        } else {
2583            if (mLruProcessServiceStart > 0
2584                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2585                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2586                return;
2587            }
2588        }
2589
2590        int lrui = mLruProcesses.lastIndexOf(app);
2591
2592        if (app.persistent && lrui >= 0) {
2593            // We don't care about the position of persistent processes, as long as
2594            // they are in the list.
2595            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2596            return;
2597        }
2598
2599        /* In progress: compute new position first, so we can avoid doing work
2600           if the process is not actually going to move.  Not yet working.
2601        int addIndex;
2602        int nextIndex;
2603        boolean inActivity = false, inService = false;
2604        if (hasActivity) {
2605            // Process has activities, put it at the very tipsy-top.
2606            addIndex = mLruProcesses.size();
2607            nextIndex = mLruProcessServiceStart;
2608            inActivity = true;
2609        } else if (hasService) {
2610            // Process has services, put it at the top of the service list.
2611            addIndex = mLruProcessActivityStart;
2612            nextIndex = mLruProcessServiceStart;
2613            inActivity = true;
2614            inService = true;
2615        } else  {
2616            // Process not otherwise of interest, it goes to the top of the non-service area.
2617            addIndex = mLruProcessServiceStart;
2618            if (client != null) {
2619                int clientIndex = mLruProcesses.lastIndexOf(client);
2620                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2621                        + app);
2622                if (clientIndex >= 0 && addIndex > clientIndex) {
2623                    addIndex = clientIndex;
2624                }
2625            }
2626            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2627        }
2628
2629        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2630                + mLruProcessActivityStart + "): " + app);
2631        */
2632
2633        if (lrui >= 0) {
2634            if (lrui < mLruProcessActivityStart) {
2635                mLruProcessActivityStart--;
2636            }
2637            if (lrui < mLruProcessServiceStart) {
2638                mLruProcessServiceStart--;
2639            }
2640            /*
2641            if (addIndex > lrui) {
2642                addIndex--;
2643            }
2644            if (nextIndex > lrui) {
2645                nextIndex--;
2646            }
2647            */
2648            mLruProcesses.remove(lrui);
2649        }
2650
2651        /*
2652        mLruProcesses.add(addIndex, app);
2653        if (inActivity) {
2654            mLruProcessActivityStart++;
2655        }
2656        if (inService) {
2657            mLruProcessActivityStart++;
2658        }
2659        */
2660
2661        int nextIndex;
2662        if (hasActivity) {
2663            final int N = mLruProcesses.size();
2664            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2665                // Process doesn't have activities, but has clients with
2666                // activities...  move it up, but one below the top (the top
2667                // should always have a real activity).
2668                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2669                mLruProcesses.add(N-1, app);
2670                // To keep it from spamming the LRU list (by making a bunch of clients),
2671                // we will push down any other entries owned by the app.
2672                final int uid = app.info.uid;
2673                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2674                    ProcessRecord subProc = mLruProcesses.get(i);
2675                    if (subProc.info.uid == uid) {
2676                        // We want to push this one down the list.  If the process after
2677                        // it is for the same uid, however, don't do so, because we don't
2678                        // want them internally to be re-ordered.
2679                        if (mLruProcesses.get(i-1).info.uid != uid) {
2680                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2681                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2682                            ProcessRecord tmp = mLruProcesses.get(i);
2683                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2684                            mLruProcesses.set(i-1, tmp);
2685                            i--;
2686                        }
2687                    } else {
2688                        // A gap, we can stop here.
2689                        break;
2690                    }
2691                }
2692            } else {
2693                // Process has activities, put it at the very tipsy-top.
2694                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2695                mLruProcesses.add(app);
2696            }
2697            nextIndex = mLruProcessServiceStart;
2698        } else if (hasService) {
2699            // Process has services, put it at the top of the service list.
2700            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2701            mLruProcesses.add(mLruProcessActivityStart, app);
2702            nextIndex = mLruProcessServiceStart;
2703            mLruProcessActivityStart++;
2704        } else  {
2705            // Process not otherwise of interest, it goes to the top of the non-service area.
2706            int index = mLruProcessServiceStart;
2707            if (client != null) {
2708                // If there is a client, don't allow the process to be moved up higher
2709                // in the list than that client.
2710                int clientIndex = mLruProcesses.lastIndexOf(client);
2711                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2712                        + " when updating " + app);
2713                if (clientIndex <= lrui) {
2714                    // Don't allow the client index restriction to push it down farther in the
2715                    // list than it already is.
2716                    clientIndex = lrui;
2717                }
2718                if (clientIndex >= 0 && index > clientIndex) {
2719                    index = clientIndex;
2720                }
2721            }
2722            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2723            mLruProcesses.add(index, app);
2724            nextIndex = index-1;
2725            mLruProcessActivityStart++;
2726            mLruProcessServiceStart++;
2727        }
2728
2729        // If the app is currently using a content provider or service,
2730        // bump those processes as well.
2731        for (int j=app.connections.size()-1; j>=0; j--) {
2732            ConnectionRecord cr = app.connections.valueAt(j);
2733            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2734                    && cr.binding.service.app != null
2735                    && cr.binding.service.app.lruSeq != mLruSeq
2736                    && !cr.binding.service.app.persistent) {
2737                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2738                        "service connection", cr, app);
2739            }
2740        }
2741        for (int j=app.conProviders.size()-1; j>=0; j--) {
2742            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2743            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2744                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2745                        "provider reference", cpr, app);
2746            }
2747        }
2748    }
2749
2750    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2751        if (uid == Process.SYSTEM_UID) {
2752            // The system gets to run in any process.  If there are multiple
2753            // processes with the same uid, just pick the first (this
2754            // should never happen).
2755            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2756            if (procs == null) return null;
2757            final int N = procs.size();
2758            for (int i = 0; i < N; i++) {
2759                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2760            }
2761        }
2762        ProcessRecord proc = mProcessNames.get(processName, uid);
2763        if (false && proc != null && !keepIfLarge
2764                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2765                && proc.lastCachedPss >= 4000) {
2766            // Turn this condition on to cause killing to happen regularly, for testing.
2767            if (proc.baseProcessTracker != null) {
2768                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2769            }
2770            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2771                    + "k from cached");
2772        } else if (proc != null && !keepIfLarge
2773                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2774                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2775            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2776            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2777                if (proc.baseProcessTracker != null) {
2778                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2779                }
2780                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2781                        + "k from cached");
2782            }
2783        }
2784        return proc;
2785    }
2786
2787    void ensurePackageDexOpt(String packageName) {
2788        IPackageManager pm = AppGlobals.getPackageManager();
2789        try {
2790            if (pm.performDexOpt(packageName)) {
2791                mDidDexOpt = true;
2792            }
2793        } catch (RemoteException e) {
2794        }
2795    }
2796
2797    boolean isNextTransitionForward() {
2798        int transit = mWindowManager.getPendingAppTransition();
2799        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2800                || transit == AppTransition.TRANSIT_TASK_OPEN
2801                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2802    }
2803
2804    final ProcessRecord startProcessLocked(String processName,
2805            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2806            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2807            boolean isolated, boolean keepIfLarge) {
2808        ProcessRecord app;
2809        if (!isolated) {
2810            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2811        } else {
2812            // If this is an isolated process, it can't re-use an existing process.
2813            app = null;
2814        }
2815        // We don't have to do anything more if:
2816        // (1) There is an existing application record; and
2817        // (2) The caller doesn't think it is dead, OR there is no thread
2818        //     object attached to it so we know it couldn't have crashed; and
2819        // (3) There is a pid assigned to it, so it is either starting or
2820        //     already running.
2821        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2822                + " app=" + app + " knownToBeDead=" + knownToBeDead
2823                + " thread=" + (app != null ? app.thread : null)
2824                + " pid=" + (app != null ? app.pid : -1));
2825        if (app != null && app.pid > 0) {
2826            if (!knownToBeDead || app.thread == null) {
2827                // We already have the app running, or are waiting for it to
2828                // come up (we have a pid but not yet its thread), so keep it.
2829                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2830                // If this is a new package in the process, add the package to the list
2831                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2832                return app;
2833            }
2834
2835            // An application record is attached to a previous process,
2836            // clean it up now.
2837            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2838            handleAppDiedLocked(app, true, true);
2839        }
2840
2841        String hostingNameStr = hostingName != null
2842                ? hostingName.flattenToShortString() : null;
2843
2844        if (!isolated) {
2845            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2846                // If we are in the background, then check to see if this process
2847                // is bad.  If so, we will just silently fail.
2848                if (mBadProcesses.get(info.processName, info.uid) != null) {
2849                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2850                            + "/" + info.processName);
2851                    return null;
2852                }
2853            } else {
2854                // When the user is explicitly starting a process, then clear its
2855                // crash count so that we won't make it bad until they see at
2856                // least one crash dialog again, and make the process good again
2857                // if it had been bad.
2858                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2859                        + "/" + info.processName);
2860                mProcessCrashTimes.remove(info.processName, info.uid);
2861                if (mBadProcesses.get(info.processName, info.uid) != null) {
2862                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2863                            UserHandle.getUserId(info.uid), info.uid,
2864                            info.processName);
2865                    mBadProcesses.remove(info.processName, info.uid);
2866                    if (app != null) {
2867                        app.bad = false;
2868                    }
2869                }
2870            }
2871        }
2872
2873        if (app == null) {
2874            app = newProcessRecordLocked(info, processName, isolated);
2875            if (app == null) {
2876                Slog.w(TAG, "Failed making new process record for "
2877                        + processName + "/" + info.uid + " isolated=" + isolated);
2878                return null;
2879            }
2880            mProcessNames.put(processName, app.uid, app);
2881            if (isolated) {
2882                mIsolatedProcesses.put(app.uid, app);
2883            }
2884        } else {
2885            // If this is a new package in the process, add the package to the list
2886            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2887        }
2888
2889        // If the system is not ready yet, then hold off on starting this
2890        // process until it is.
2891        if (!mProcessesReady
2892                && !isAllowedWhileBooting(info)
2893                && !allowWhileBooting) {
2894            if (!mProcessesOnHold.contains(app)) {
2895                mProcessesOnHold.add(app);
2896            }
2897            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2898            return app;
2899        }
2900
2901        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2902        return (app.pid != 0) ? app : null;
2903    }
2904
2905    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2906        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2907    }
2908
2909    private final void startProcessLocked(ProcessRecord app,
2910            String hostingType, String hostingNameStr, String abiOverride) {
2911        if (app.pid > 0 && app.pid != MY_PID) {
2912            synchronized (mPidsSelfLocked) {
2913                mPidsSelfLocked.remove(app.pid);
2914                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2915            }
2916            app.setPid(0);
2917        }
2918
2919        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2920                "startProcessLocked removing on hold: " + app);
2921        mProcessesOnHold.remove(app);
2922
2923        updateCpuStats();
2924
2925        try {
2926            int uid = app.uid;
2927
2928            int[] gids = null;
2929            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2930            if (!app.isolated) {
2931                int[] permGids = null;
2932                try {
2933                    final PackageManager pm = mContext.getPackageManager();
2934                    permGids = pm.getPackageGids(app.info.packageName);
2935
2936                    if (Environment.isExternalStorageEmulated()) {
2937                        if (pm.checkPermission(
2938                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2939                                app.info.packageName) == PERMISSION_GRANTED) {
2940                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2941                        } else {
2942                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2943                        }
2944                    }
2945                } catch (PackageManager.NameNotFoundException e) {
2946                    Slog.w(TAG, "Unable to retrieve gids", e);
2947                }
2948
2949                /*
2950                 * Add shared application and profile GIDs so applications can share some
2951                 * resources like shared libraries and access user-wide resources
2952                 */
2953                if (permGids == null) {
2954                    gids = new int[2];
2955                } else {
2956                    gids = new int[permGids.length + 2];
2957                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2958                }
2959                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2960                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2961            }
2962            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2963                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2964                        && mTopComponent != null
2965                        && app.processName.equals(mTopComponent.getPackageName())) {
2966                    uid = 0;
2967                }
2968                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2969                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2970                    uid = 0;
2971                }
2972            }
2973            int debugFlags = 0;
2974            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2975                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2976                // Also turn on CheckJNI for debuggable apps. It's quite
2977                // awkward to turn on otherwise.
2978                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2979            }
2980            // Run the app in safe mode if its manifest requests so or the
2981            // system is booted in safe mode.
2982            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2983                mSafeMode == true) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2985            }
2986            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2987                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2988            }
2989            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2990                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2991            }
2992            if ("1".equals(SystemProperties.get("debug.assert"))) {
2993                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2994            }
2995
2996            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2997            if (requiredAbi == null) {
2998                requiredAbi = Build.SUPPORTED_ABIS[0];
2999            }
3000
3001            // Start the process.  It will either succeed and return a result containing
3002            // the PID of the new process, or else throw a RuntimeException.
3003            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3004                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3005                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3006
3007            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
3008            synchronized (bs) {
3009                if (bs.isOnBattery()) {
3010                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
3011                }
3012            }
3013
3014            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3015                    UserHandle.getUserId(uid), startResult.pid, uid,
3016                    app.processName, hostingType,
3017                    hostingNameStr != null ? hostingNameStr : "");
3018
3019            if (app.persistent) {
3020                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3021            }
3022
3023            StringBuilder buf = mStringBuilder;
3024            buf.setLength(0);
3025            buf.append("Start proc ");
3026            buf.append(app.processName);
3027            buf.append(" for ");
3028            buf.append(hostingType);
3029            if (hostingNameStr != null) {
3030                buf.append(" ");
3031                buf.append(hostingNameStr);
3032            }
3033            buf.append(": pid=");
3034            buf.append(startResult.pid);
3035            buf.append(" uid=");
3036            buf.append(uid);
3037            buf.append(" gids={");
3038            if (gids != null) {
3039                for (int gi=0; gi<gids.length; gi++) {
3040                    if (gi != 0) buf.append(", ");
3041                    buf.append(gids[gi]);
3042
3043                }
3044            }
3045            buf.append("}");
3046            if (requiredAbi != null) {
3047                buf.append(" abi=");
3048                buf.append(requiredAbi);
3049            }
3050            Slog.i(TAG, buf.toString());
3051            app.setPid(startResult.pid);
3052            app.usingWrapper = startResult.usingWrapper;
3053            app.removed = false;
3054            synchronized (mPidsSelfLocked) {
3055                this.mPidsSelfLocked.put(startResult.pid, app);
3056                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3057                msg.obj = app;
3058                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3059                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3060            }
3061            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3062                    app.processName, app.info.uid);
3063            if (app.isolated) {
3064                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3065            }
3066        } catch (RuntimeException e) {
3067            // XXX do better error recovery.
3068            app.setPid(0);
3069            Slog.e(TAG, "Failure starting process " + app.processName, e);
3070        }
3071    }
3072
3073    void updateUsageStats(ActivityRecord component, boolean resumed) {
3074        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3075        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3076        if (resumed) {
3077            mUsageStatsService.noteResumeComponent(component.realActivity);
3078            synchronized (stats) {
3079                stats.noteActivityResumedLocked(component.app.uid);
3080            }
3081        } else {
3082            mUsageStatsService.notePauseComponent(component.realActivity);
3083            synchronized (stats) {
3084                stats.noteActivityPausedLocked(component.app.uid);
3085            }
3086        }
3087    }
3088
3089    Intent getHomeIntent() {
3090        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3091        intent.setComponent(mTopComponent);
3092        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3093            intent.addCategory(Intent.CATEGORY_HOME);
3094        }
3095        return intent;
3096    }
3097
3098    boolean startHomeActivityLocked(int userId) {
3099        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3100                && mTopAction == null) {
3101            // We are running in factory test mode, but unable to find
3102            // the factory test app, so just sit around displaying the
3103            // error message and don't try to start anything.
3104            return false;
3105        }
3106        Intent intent = getHomeIntent();
3107        ActivityInfo aInfo =
3108            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3109        if (aInfo != null) {
3110            intent.setComponent(new ComponentName(
3111                    aInfo.applicationInfo.packageName, aInfo.name));
3112            // Don't do this if the home app is currently being
3113            // instrumented.
3114            aInfo = new ActivityInfo(aInfo);
3115            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3116            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3117                    aInfo.applicationInfo.uid, true);
3118            if (app == null || app.instrumentationClass == null) {
3119                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3120                mStackSupervisor.startHomeActivity(intent, aInfo);
3121            }
3122        }
3123
3124        return true;
3125    }
3126
3127    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3128        ActivityInfo ai = null;
3129        ComponentName comp = intent.getComponent();
3130        try {
3131            if (comp != null) {
3132                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3133            } else {
3134                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3135                        intent,
3136                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3137                            flags, userId);
3138
3139                if (info != null) {
3140                    ai = info.activityInfo;
3141                }
3142            }
3143        } catch (RemoteException e) {
3144            // ignore
3145        }
3146
3147        return ai;
3148    }
3149
3150    /**
3151     * Starts the "new version setup screen" if appropriate.
3152     */
3153    void startSetupActivityLocked() {
3154        // Only do this once per boot.
3155        if (mCheckedForSetup) {
3156            return;
3157        }
3158
3159        // We will show this screen if the current one is a different
3160        // version than the last one shown, and we are not running in
3161        // low-level factory test mode.
3162        final ContentResolver resolver = mContext.getContentResolver();
3163        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3164                Settings.Global.getInt(resolver,
3165                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3166            mCheckedForSetup = true;
3167
3168            // See if we should be showing the platform update setup UI.
3169            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3170            List<ResolveInfo> ris = mContext.getPackageManager()
3171                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3172
3173            // We don't allow third party apps to replace this.
3174            ResolveInfo ri = null;
3175            for (int i=0; ris != null && i<ris.size(); i++) {
3176                if ((ris.get(i).activityInfo.applicationInfo.flags
3177                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3178                    ri = ris.get(i);
3179                    break;
3180                }
3181            }
3182
3183            if (ri != null) {
3184                String vers = ri.activityInfo.metaData != null
3185                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3186                        : null;
3187                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3188                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3189                            Intent.METADATA_SETUP_VERSION);
3190                }
3191                String lastVers = Settings.Secure.getString(
3192                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3193                if (vers != null && !vers.equals(lastVers)) {
3194                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3195                    intent.setComponent(new ComponentName(
3196                            ri.activityInfo.packageName, ri.activityInfo.name));
3197                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3198                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3199                }
3200            }
3201        }
3202    }
3203
3204    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3205        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3206    }
3207
3208    void enforceNotIsolatedCaller(String caller) {
3209        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3210            throw new SecurityException("Isolated process not allowed to call " + caller);
3211        }
3212    }
3213
3214    @Override
3215    public int getFrontActivityScreenCompatMode() {
3216        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3217        synchronized (this) {
3218            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3219        }
3220    }
3221
3222    @Override
3223    public void setFrontActivityScreenCompatMode(int mode) {
3224        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3225                "setFrontActivityScreenCompatMode");
3226        synchronized (this) {
3227            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3228        }
3229    }
3230
3231    @Override
3232    public int getPackageScreenCompatMode(String packageName) {
3233        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3234        synchronized (this) {
3235            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3236        }
3237    }
3238
3239    @Override
3240    public void setPackageScreenCompatMode(String packageName, int mode) {
3241        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3242                "setPackageScreenCompatMode");
3243        synchronized (this) {
3244            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3245        }
3246    }
3247
3248    @Override
3249    public boolean getPackageAskScreenCompat(String packageName) {
3250        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3251        synchronized (this) {
3252            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3253        }
3254    }
3255
3256    @Override
3257    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3258        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3259                "setPackageAskScreenCompat");
3260        synchronized (this) {
3261            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3262        }
3263    }
3264
3265    private void dispatchProcessesChanged() {
3266        int N;
3267        synchronized (this) {
3268            N = mPendingProcessChanges.size();
3269            if (mActiveProcessChanges.length < N) {
3270                mActiveProcessChanges = new ProcessChangeItem[N];
3271            }
3272            mPendingProcessChanges.toArray(mActiveProcessChanges);
3273            mAvailProcessChanges.addAll(mPendingProcessChanges);
3274            mPendingProcessChanges.clear();
3275            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3276        }
3277
3278        int i = mProcessObservers.beginBroadcast();
3279        while (i > 0) {
3280            i--;
3281            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3282            if (observer != null) {
3283                try {
3284                    for (int j=0; j<N; j++) {
3285                        ProcessChangeItem item = mActiveProcessChanges[j];
3286                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3287                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3288                                    + item.pid + " uid=" + item.uid + ": "
3289                                    + item.foregroundActivities);
3290                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3291                                    item.foregroundActivities);
3292                        }
3293                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3294                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3295                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3296                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3297                        }
3298                    }
3299                } catch (RemoteException e) {
3300                }
3301            }
3302        }
3303        mProcessObservers.finishBroadcast();
3304    }
3305
3306    private void dispatchProcessDied(int pid, int uid) {
3307        int i = mProcessObservers.beginBroadcast();
3308        while (i > 0) {
3309            i--;
3310            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3311            if (observer != null) {
3312                try {
3313                    observer.onProcessDied(pid, uid);
3314                } catch (RemoteException e) {
3315                }
3316            }
3317        }
3318        mProcessObservers.finishBroadcast();
3319    }
3320
3321    final void doPendingActivityLaunchesLocked(boolean doResume) {
3322        final int N = mPendingActivityLaunches.size();
3323        if (N <= 0) {
3324            return;
3325        }
3326        for (int i=0; i<N; i++) {
3327            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3328            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3329                    doResume && i == (N-1), null);
3330        }
3331        mPendingActivityLaunches.clear();
3332    }
3333
3334    @Override
3335    public final int startActivity(IApplicationThread caller, String callingPackage,
3336            Intent intent, String resolvedType, IBinder resultTo,
3337            String resultWho, int requestCode, int startFlags,
3338            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3339        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3340                resultWho, requestCode,
3341                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3342    }
3343
3344    @Override
3345    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3346            Intent intent, String resolvedType, IBinder resultTo,
3347            String resultWho, int requestCode, int startFlags,
3348            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3349        enforceNotIsolatedCaller("startActivity");
3350        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3351                false, true, "startActivity", null);
3352        // TODO: Switch to user app stacks here.
3353        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3354                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3355                null, null, options, userId, null);
3356    }
3357
3358    @Override
3359    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3360            Intent intent, String resolvedType, IBinder resultTo,
3361            String resultWho, int requestCode, int startFlags, String profileFile,
3362            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3363        enforceNotIsolatedCaller("startActivityAndWait");
3364        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3365                false, true, "startActivityAndWait", null);
3366        WaitResult res = new WaitResult();
3367        // TODO: Switch to user app stacks here.
3368        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3369                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3370                res, null, options, UserHandle.getCallingUserId(), null);
3371        return res;
3372    }
3373
3374    @Override
3375    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3376            Intent intent, String resolvedType, IBinder resultTo,
3377            String resultWho, int requestCode, int startFlags, Configuration config,
3378            Bundle options, int userId) {
3379        enforceNotIsolatedCaller("startActivityWithConfig");
3380        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3381                false, true, "startActivityWithConfig", null);
3382        // TODO: Switch to user app stacks here.
3383        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3384                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3385                null, null, null, config, options, userId, null);
3386        return ret;
3387    }
3388
3389    @Override
3390    public int startActivityIntentSender(IApplicationThread caller,
3391            IntentSender intent, Intent fillInIntent, String resolvedType,
3392            IBinder resultTo, String resultWho, int requestCode,
3393            int flagsMask, int flagsValues, Bundle options) {
3394        enforceNotIsolatedCaller("startActivityIntentSender");
3395        // Refuse possible leaked file descriptors
3396        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3397            throw new IllegalArgumentException("File descriptors passed in Intent");
3398        }
3399
3400        IIntentSender sender = intent.getTarget();
3401        if (!(sender instanceof PendingIntentRecord)) {
3402            throw new IllegalArgumentException("Bad PendingIntent object");
3403        }
3404
3405        PendingIntentRecord pir = (PendingIntentRecord)sender;
3406
3407        synchronized (this) {
3408            // If this is coming from the currently resumed activity, it is
3409            // effectively saying that app switches are allowed at this point.
3410            final ActivityStack stack = getFocusedStack();
3411            if (stack.mResumedActivity != null &&
3412                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3413                mAppSwitchesAllowedTime = 0;
3414            }
3415        }
3416        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3417                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3418        return ret;
3419    }
3420
3421    @Override
3422    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3423            Intent intent, String resolvedType, IVoiceInteractionSession session,
3424            IVoiceInteractor interactor, int startFlags, String profileFile,
3425            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3426        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3427                != PackageManager.PERMISSION_GRANTED) {
3428            String msg = "Permission Denial: startVoiceActivity() from pid="
3429                    + Binder.getCallingPid()
3430                    + ", uid=" + Binder.getCallingUid()
3431                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3432            Slog.w(TAG, msg);
3433            throw new SecurityException(msg);
3434        }
3435        if (session == null || interactor == null) {
3436            throw new NullPointerException("null session or interactor");
3437        }
3438        userId = handleIncomingUser(callingPid, callingUid, userId,
3439                false, true, "startVoiceActivity", null);
3440        // TODO: Switch to user app stacks here.
3441        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3442                resolvedType, session, interactor, null, null, 0, startFlags,
3443                profileFile, profileFd, null, null, options, userId, null);
3444    }
3445
3446    @Override
3447    public boolean startNextMatchingActivity(IBinder callingActivity,
3448            Intent intent, Bundle options) {
3449        // Refuse possible leaked file descriptors
3450        if (intent != null && intent.hasFileDescriptors() == true) {
3451            throw new IllegalArgumentException("File descriptors passed in Intent");
3452        }
3453
3454        synchronized (this) {
3455            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3456            if (r == null) {
3457                ActivityOptions.abort(options);
3458                return false;
3459            }
3460            if (r.app == null || r.app.thread == null) {
3461                // The caller is not running...  d'oh!
3462                ActivityOptions.abort(options);
3463                return false;
3464            }
3465            intent = new Intent(intent);
3466            // The caller is not allowed to change the data.
3467            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3468            // And we are resetting to find the next component...
3469            intent.setComponent(null);
3470
3471            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3472
3473            ActivityInfo aInfo = null;
3474            try {
3475                List<ResolveInfo> resolves =
3476                    AppGlobals.getPackageManager().queryIntentActivities(
3477                            intent, r.resolvedType,
3478                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3479                            UserHandle.getCallingUserId());
3480
3481                // Look for the original activity in the list...
3482                final int N = resolves != null ? resolves.size() : 0;
3483                for (int i=0; i<N; i++) {
3484                    ResolveInfo rInfo = resolves.get(i);
3485                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3486                            && rInfo.activityInfo.name.equals(r.info.name)) {
3487                        // We found the current one...  the next matching is
3488                        // after it.
3489                        i++;
3490                        if (i<N) {
3491                            aInfo = resolves.get(i).activityInfo;
3492                        }
3493                        if (debug) {
3494                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3495                                    + "/" + r.info.name);
3496                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3497                                    + "/" + aInfo.name);
3498                        }
3499                        break;
3500                    }
3501                }
3502            } catch (RemoteException e) {
3503            }
3504
3505            if (aInfo == null) {
3506                // Nobody who is next!
3507                ActivityOptions.abort(options);
3508                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3509                return false;
3510            }
3511
3512            intent.setComponent(new ComponentName(
3513                    aInfo.applicationInfo.packageName, aInfo.name));
3514            intent.setFlags(intent.getFlags()&~(
3515                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3516                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3517                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3518                    Intent.FLAG_ACTIVITY_NEW_TASK));
3519
3520            // Okay now we need to start the new activity, replacing the
3521            // currently running activity.  This is a little tricky because
3522            // we want to start the new one as if the current one is finished,
3523            // but not finish the current one first so that there is no flicker.
3524            // And thus...
3525            final boolean wasFinishing = r.finishing;
3526            r.finishing = true;
3527
3528            // Propagate reply information over to the new activity.
3529            final ActivityRecord resultTo = r.resultTo;
3530            final String resultWho = r.resultWho;
3531            final int requestCode = r.requestCode;
3532            r.resultTo = null;
3533            if (resultTo != null) {
3534                resultTo.removeResultsLocked(r, resultWho, requestCode);
3535            }
3536
3537            final long origId = Binder.clearCallingIdentity();
3538            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3539                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3540                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3541                    options, false, null, null);
3542            Binder.restoreCallingIdentity(origId);
3543
3544            r.finishing = wasFinishing;
3545            if (res != ActivityManager.START_SUCCESS) {
3546                return false;
3547            }
3548            return true;
3549        }
3550    }
3551
3552    final int startActivityInPackage(int uid, String callingPackage,
3553            Intent intent, String resolvedType, IBinder resultTo,
3554            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3555                    IActivityContainer container) {
3556
3557        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3558                false, true, "startActivityInPackage", null);
3559
3560        // TODO: Switch to user app stacks here.
3561        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3562                null, null, resultTo, resultWho, requestCode, startFlags,
3563                null, null, null, null, options, userId, container);
3564        return ret;
3565    }
3566
3567    @Override
3568    public final int startActivities(IApplicationThread caller, String callingPackage,
3569            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3570            int userId) {
3571        enforceNotIsolatedCaller("startActivities");
3572        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3573                false, true, "startActivity", null);
3574        // TODO: Switch to user app stacks here.
3575        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3576                resolvedTypes, resultTo, options, userId);
3577        return ret;
3578    }
3579
3580    final int startActivitiesInPackage(int uid, String callingPackage,
3581            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3582            Bundle options, int userId) {
3583
3584        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3585                false, true, "startActivityInPackage", null);
3586        // TODO: Switch to user app stacks here.
3587        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3588                resultTo, options, userId);
3589        return ret;
3590    }
3591
3592    final void addRecentTaskLocked(TaskRecord task) {
3593        int N = mRecentTasks.size();
3594        // Quick case: check if the top-most recent task is the same.
3595        if (N > 0 && mRecentTasks.get(0) == task) {
3596            return;
3597        }
3598        // Another quick case: never add voice sessions.
3599        if (task.voiceSession != null) {
3600            return;
3601        }
3602        // Remove any existing entries that are the same kind of task.
3603        final Intent intent = task.intent;
3604        final boolean document = intent != null && intent.isDocument();
3605        final ComponentName comp = intent.getComponent();
3606
3607        int maxRecents = task.maxRecents - 1;
3608        for (int i=0; i<N; i++) {
3609            TaskRecord tr = mRecentTasks.get(i);
3610            if (task != tr) {
3611                if (task.userId != tr.userId) {
3612                    continue;
3613                }
3614                final Intent trIntent = tr.intent;
3615                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3616                    (intent == null || !intent.filterEquals(trIntent))) {
3617                    continue;
3618                }
3619                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3620                if (document && trIsDocument) {
3621                    // These are the same document activity (not necessarily the same doc).
3622                    if (maxRecents > 0) {
3623                        --maxRecents;
3624                        continue;
3625                    }
3626                    // Hit the maximum number of documents for this task. Fall through
3627                    // and remove this document from recents.
3628                } else if (document || trIsDocument) {
3629                    // Only one of these is a document. Not the droid we're looking for.
3630                    continue;
3631                }
3632            }
3633
3634            // Either task and tr are the same or, their affinities match or their intents match
3635            // and neither of them is a document, or they are documents using the same activity
3636            // and their maxRecents has been reached.
3637            tr.disposeThumbnail();
3638            mRecentTasks.remove(i);
3639            i--;
3640            N--;
3641            if (task.intent == null) {
3642                // If the new recent task we are adding is not fully
3643                // specified, then replace it with the existing recent task.
3644                task = tr;
3645            }
3646            mTaskPersister.notify(tr, false);
3647        }
3648        if (N >= MAX_RECENT_TASKS) {
3649            mRecentTasks.remove(N-1).disposeThumbnail();
3650        }
3651        mRecentTasks.add(0, task);
3652    }
3653
3654    @Override
3655    public void reportActivityFullyDrawn(IBinder token) {
3656        synchronized (this) {
3657            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3658            if (r == null) {
3659                return;
3660            }
3661            r.reportFullyDrawnLocked();
3662        }
3663    }
3664
3665    @Override
3666    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3667        synchronized (this) {
3668            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3669            if (r == null) {
3670                return;
3671            }
3672            final long origId = Binder.clearCallingIdentity();
3673            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3674            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3675                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3676            if (config != null) {
3677                r.frozenBeforeDestroy = true;
3678                if (!updateConfigurationLocked(config, r, false, false)) {
3679                    mStackSupervisor.resumeTopActivitiesLocked();
3680                }
3681            }
3682            Binder.restoreCallingIdentity(origId);
3683        }
3684    }
3685
3686    @Override
3687    public int getRequestedOrientation(IBinder token) {
3688        synchronized (this) {
3689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3690            if (r == null) {
3691                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3692            }
3693            return mWindowManager.getAppOrientation(r.appToken);
3694        }
3695    }
3696
3697    /**
3698     * This is the internal entry point for handling Activity.finish().
3699     *
3700     * @param token The Binder token referencing the Activity we want to finish.
3701     * @param resultCode Result code, if any, from this Activity.
3702     * @param resultData Result data (Intent), if any, from this Activity.
3703     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3704     *            the root Activity in the task.
3705     *
3706     * @return Returns true if the activity successfully finished, or false if it is still running.
3707     */
3708    @Override
3709    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3710            boolean finishTask) {
3711        // Refuse possible leaked file descriptors
3712        if (resultData != null && resultData.hasFileDescriptors() == true) {
3713            throw new IllegalArgumentException("File descriptors passed in Intent");
3714        }
3715
3716        synchronized(this) {
3717            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3718            if (r == null) {
3719                return true;
3720            }
3721            // Keep track of the root activity of the task before we finish it
3722            TaskRecord tr = r.task;
3723            ActivityRecord rootR = tr.getRootActivity();
3724            // Do not allow task to finish in Lock Task mode.
3725            if (tr == mStackSupervisor.mLockTaskModeTask) {
3726                if (rootR == r) {
3727                    return false;
3728                }
3729            }
3730            if (mController != null) {
3731                // Find the first activity that is not finishing.
3732                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3733                if (next != null) {
3734                    // ask watcher if this is allowed
3735                    boolean resumeOK = true;
3736                    try {
3737                        resumeOK = mController.activityResuming(next.packageName);
3738                    } catch (RemoteException e) {
3739                        mController = null;
3740                        Watchdog.getInstance().setActivityController(null);
3741                    }
3742
3743                    if (!resumeOK) {
3744                        return false;
3745                    }
3746                }
3747            }
3748            final long origId = Binder.clearCallingIdentity();
3749            try {
3750                boolean res;
3751                if (finishTask && r == rootR) {
3752                    // If requested, remove the task that is associated to this activity only if it
3753                    // was the root activity in the task.  The result code and data is ignored because
3754                    // we don't support returning them across task boundaries.
3755                    res = removeTaskByIdLocked(tr.taskId, 0);
3756                } else {
3757                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3758                            resultData, "app-request", true);
3759                }
3760                return res;
3761            } finally {
3762                Binder.restoreCallingIdentity(origId);
3763            }
3764        }
3765    }
3766
3767    @Override
3768    public final void finishHeavyWeightApp() {
3769        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3770                != PackageManager.PERMISSION_GRANTED) {
3771            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3772                    + Binder.getCallingPid()
3773                    + ", uid=" + Binder.getCallingUid()
3774                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3775            Slog.w(TAG, msg);
3776            throw new SecurityException(msg);
3777        }
3778
3779        synchronized(this) {
3780            if (mHeavyWeightProcess == null) {
3781                return;
3782            }
3783
3784            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3785                    mHeavyWeightProcess.activities);
3786            for (int i=0; i<activities.size(); i++) {
3787                ActivityRecord r = activities.get(i);
3788                if (!r.finishing) {
3789                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3790                            null, "finish-heavy", true);
3791                }
3792            }
3793
3794            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3795                    mHeavyWeightProcess.userId, 0));
3796            mHeavyWeightProcess = null;
3797        }
3798    }
3799
3800    @Override
3801    public void crashApplication(int uid, int initialPid, String packageName,
3802            String message) {
3803        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3804                != PackageManager.PERMISSION_GRANTED) {
3805            String msg = "Permission Denial: crashApplication() from pid="
3806                    + Binder.getCallingPid()
3807                    + ", uid=" + Binder.getCallingUid()
3808                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3809            Slog.w(TAG, msg);
3810            throw new SecurityException(msg);
3811        }
3812
3813        synchronized(this) {
3814            ProcessRecord proc = null;
3815
3816            // Figure out which process to kill.  We don't trust that initialPid
3817            // still has any relation to current pids, so must scan through the
3818            // list.
3819            synchronized (mPidsSelfLocked) {
3820                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3821                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3822                    if (p.uid != uid) {
3823                        continue;
3824                    }
3825                    if (p.pid == initialPid) {
3826                        proc = p;
3827                        break;
3828                    }
3829                    if (p.pkgList.containsKey(packageName)) {
3830                        proc = p;
3831                    }
3832                }
3833            }
3834
3835            if (proc == null) {
3836                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3837                        + " initialPid=" + initialPid
3838                        + " packageName=" + packageName);
3839                return;
3840            }
3841
3842            if (proc.thread != null) {
3843                if (proc.pid == Process.myPid()) {
3844                    Log.w(TAG, "crashApplication: trying to crash self!");
3845                    return;
3846                }
3847                long ident = Binder.clearCallingIdentity();
3848                try {
3849                    proc.thread.scheduleCrash(message);
3850                } catch (RemoteException e) {
3851                }
3852                Binder.restoreCallingIdentity(ident);
3853            }
3854        }
3855    }
3856
3857    @Override
3858    public final void finishSubActivity(IBinder token, String resultWho,
3859            int requestCode) {
3860        synchronized(this) {
3861            final long origId = Binder.clearCallingIdentity();
3862            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3863            if (r != null) {
3864                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3865            }
3866            Binder.restoreCallingIdentity(origId);
3867        }
3868    }
3869
3870    @Override
3871    public boolean finishActivityAffinity(IBinder token) {
3872        synchronized(this) {
3873            final long origId = Binder.clearCallingIdentity();
3874            try {
3875                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3876
3877                ActivityRecord rootR = r.task.getRootActivity();
3878                // Do not allow task to finish in Lock Task mode.
3879                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3880                    if (rootR == r) {
3881                        Binder.restoreCallingIdentity(origId);
3882                        return false;
3883                    }
3884                }
3885                boolean res = false;
3886                if (r != null) {
3887                    res = r.task.stack.finishActivityAffinityLocked(r);
3888                }
3889                return res;
3890            } finally {
3891                Binder.restoreCallingIdentity(origId);
3892            }
3893        }
3894    }
3895
3896    @Override
3897    public boolean willActivityBeVisible(IBinder token) {
3898        synchronized(this) {
3899            ActivityStack stack = ActivityRecord.getStackLocked(token);
3900            if (stack != null) {
3901                return stack.willActivityBeVisibleLocked(token);
3902            }
3903            return false;
3904        }
3905    }
3906
3907    @Override
3908    public void overridePendingTransition(IBinder token, String packageName,
3909            int enterAnim, int exitAnim) {
3910        synchronized(this) {
3911            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3912            if (self == null) {
3913                return;
3914            }
3915
3916            final long origId = Binder.clearCallingIdentity();
3917
3918            if (self.state == ActivityState.RESUMED
3919                    || self.state == ActivityState.PAUSING) {
3920                mWindowManager.overridePendingAppTransition(packageName,
3921                        enterAnim, exitAnim, null);
3922            }
3923
3924            Binder.restoreCallingIdentity(origId);
3925        }
3926    }
3927
3928    /**
3929     * Main function for removing an existing process from the activity manager
3930     * as a result of that process going away.  Clears out all connections
3931     * to the process.
3932     */
3933    private final void handleAppDiedLocked(ProcessRecord app,
3934            boolean restarting, boolean allowRestart) {
3935        int pid = app.pid;
3936        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3937        if (!restarting) {
3938            removeLruProcessLocked(app);
3939            if (pid > 0) {
3940                ProcessList.remove(pid);
3941            }
3942        }
3943
3944        if (mProfileProc == app) {
3945            clearProfilerLocked();
3946        }
3947
3948        // Remove this application's activities from active lists.
3949        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3950
3951        app.activities.clear();
3952
3953        if (app.instrumentationClass != null) {
3954            Slog.w(TAG, "Crash of app " + app.processName
3955                  + " running instrumentation " + app.instrumentationClass);
3956            Bundle info = new Bundle();
3957            info.putString("shortMsg", "Process crashed.");
3958            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3959        }
3960
3961        if (!restarting) {
3962            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3963                // If there was nothing to resume, and we are not already
3964                // restarting this process, but there is a visible activity that
3965                // is hosted by the process...  then make sure all visible
3966                // activities are running, taking care of restarting this
3967                // process.
3968                if (hasVisibleActivities) {
3969                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3970                }
3971            }
3972        }
3973    }
3974
3975    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3976        IBinder threadBinder = thread.asBinder();
3977        // Find the application record.
3978        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3979            ProcessRecord rec = mLruProcesses.get(i);
3980            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3981                return i;
3982            }
3983        }
3984        return -1;
3985    }
3986
3987    final ProcessRecord getRecordForAppLocked(
3988            IApplicationThread thread) {
3989        if (thread == null) {
3990            return null;
3991        }
3992
3993        int appIndex = getLRURecordIndexForAppLocked(thread);
3994        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3995    }
3996
3997    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3998        // If there are no longer any background processes running,
3999        // and the app that died was not running instrumentation,
4000        // then tell everyone we are now low on memory.
4001        boolean haveBg = false;
4002        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4003            ProcessRecord rec = mLruProcesses.get(i);
4004            if (rec.thread != null
4005                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4006                haveBg = true;
4007                break;
4008            }
4009        }
4010
4011        if (!haveBg) {
4012            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4013            if (doReport) {
4014                long now = SystemClock.uptimeMillis();
4015                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4016                    doReport = false;
4017                } else {
4018                    mLastMemUsageReportTime = now;
4019                }
4020            }
4021            final ArrayList<ProcessMemInfo> memInfos
4022                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4023            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4024            long now = SystemClock.uptimeMillis();
4025            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4026                ProcessRecord rec = mLruProcesses.get(i);
4027                if (rec == dyingProc || rec.thread == null) {
4028                    continue;
4029                }
4030                if (doReport) {
4031                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4032                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4033                }
4034                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4035                    // The low memory report is overriding any current
4036                    // state for a GC request.  Make sure to do
4037                    // heavy/important/visible/foreground processes first.
4038                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4039                        rec.lastRequestedGc = 0;
4040                    } else {
4041                        rec.lastRequestedGc = rec.lastLowMemory;
4042                    }
4043                    rec.reportLowMemory = true;
4044                    rec.lastLowMemory = now;
4045                    mProcessesToGc.remove(rec);
4046                    addProcessToGcListLocked(rec);
4047                }
4048            }
4049            if (doReport) {
4050                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4051                mHandler.sendMessage(msg);
4052            }
4053            scheduleAppGcsLocked();
4054        }
4055    }
4056
4057    final void appDiedLocked(ProcessRecord app, int pid,
4058            IApplicationThread thread) {
4059
4060        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4061        synchronized (stats) {
4062            stats.noteProcessDiedLocked(app.info.uid, pid);
4063        }
4064
4065        // Clean up already done if the process has been re-started.
4066        if (app.pid == pid && app.thread != null &&
4067                app.thread.asBinder() == thread.asBinder()) {
4068            boolean doLowMem = app.instrumentationClass == null;
4069            boolean doOomAdj = doLowMem;
4070            if (!app.killedByAm) {
4071                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4072                        + ") has died.");
4073                mAllowLowerMemLevel = true;
4074            } else {
4075                // Note that we always want to do oom adj to update our state with the
4076                // new number of procs.
4077                mAllowLowerMemLevel = false;
4078                doLowMem = false;
4079            }
4080            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4081            if (DEBUG_CLEANUP) Slog.v(
4082                TAG, "Dying app: " + app + ", pid: " + pid
4083                + ", thread: " + thread.asBinder());
4084            handleAppDiedLocked(app, false, true);
4085
4086            if (doOomAdj) {
4087                updateOomAdjLocked();
4088            }
4089            if (doLowMem) {
4090                doLowMemReportIfNeededLocked(app);
4091            }
4092        } else if (app.pid != pid) {
4093            // A new process has already been started.
4094            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4095                    + ") has died and restarted (pid " + app.pid + ").");
4096            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4097        } else if (DEBUG_PROCESSES) {
4098            Slog.d(TAG, "Received spurious death notification for thread "
4099                    + thread.asBinder());
4100        }
4101    }
4102
4103    /**
4104     * If a stack trace dump file is configured, dump process stack traces.
4105     * @param clearTraces causes the dump file to be erased prior to the new
4106     *    traces being written, if true; when false, the new traces will be
4107     *    appended to any existing file content.
4108     * @param firstPids of dalvik VM processes to dump stack traces for first
4109     * @param lastPids of dalvik VM processes to dump stack traces for last
4110     * @param nativeProcs optional list of native process names to dump stack crawls
4111     * @return file containing stack traces, or null if no dump file is configured
4112     */
4113    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4114            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4115        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4116        if (tracesPath == null || tracesPath.length() == 0) {
4117            return null;
4118        }
4119
4120        File tracesFile = new File(tracesPath);
4121        try {
4122            File tracesDir = tracesFile.getParentFile();
4123            if (!tracesDir.exists()) {
4124                tracesFile.mkdirs();
4125                if (!SELinux.restorecon(tracesDir)) {
4126                    return null;
4127                }
4128            }
4129            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4130
4131            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4132            tracesFile.createNewFile();
4133            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4134        } catch (IOException e) {
4135            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4136            return null;
4137        }
4138
4139        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4140        return tracesFile;
4141    }
4142
4143    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4144            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4145        // Use a FileObserver to detect when traces finish writing.
4146        // The order of traces is considered important to maintain for legibility.
4147        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4148            @Override
4149            public synchronized void onEvent(int event, String path) { notify(); }
4150        };
4151
4152        try {
4153            observer.startWatching();
4154
4155            // First collect all of the stacks of the most important pids.
4156            if (firstPids != null) {
4157                try {
4158                    int num = firstPids.size();
4159                    for (int i = 0; i < num; i++) {
4160                        synchronized (observer) {
4161                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4162                            observer.wait(200);  // Wait for write-close, give up after 200msec
4163                        }
4164                    }
4165                } catch (InterruptedException e) {
4166                    Log.wtf(TAG, e);
4167                }
4168            }
4169
4170            // Next collect the stacks of the native pids
4171            if (nativeProcs != null) {
4172                int[] pids = Process.getPidsForCommands(nativeProcs);
4173                if (pids != null) {
4174                    for (int pid : pids) {
4175                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4176                    }
4177                }
4178            }
4179
4180            // Lastly, measure CPU usage.
4181            if (processCpuTracker != null) {
4182                processCpuTracker.init();
4183                System.gc();
4184                processCpuTracker.update();
4185                try {
4186                    synchronized (processCpuTracker) {
4187                        processCpuTracker.wait(500); // measure over 1/2 second.
4188                    }
4189                } catch (InterruptedException e) {
4190                }
4191                processCpuTracker.update();
4192
4193                // We'll take the stack crawls of just the top apps using CPU.
4194                final int N = processCpuTracker.countWorkingStats();
4195                int numProcs = 0;
4196                for (int i=0; i<N && numProcs<5; i++) {
4197                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4198                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4199                        numProcs++;
4200                        try {
4201                            synchronized (observer) {
4202                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4203                                observer.wait(200);  // Wait for write-close, give up after 200msec
4204                            }
4205                        } catch (InterruptedException e) {
4206                            Log.wtf(TAG, e);
4207                        }
4208
4209                    }
4210                }
4211            }
4212        } finally {
4213            observer.stopWatching();
4214        }
4215    }
4216
4217    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4218        if (true || IS_USER_BUILD) {
4219            return;
4220        }
4221        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4222        if (tracesPath == null || tracesPath.length() == 0) {
4223            return;
4224        }
4225
4226        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4227        StrictMode.allowThreadDiskWrites();
4228        try {
4229            final File tracesFile = new File(tracesPath);
4230            final File tracesDir = tracesFile.getParentFile();
4231            final File tracesTmp = new File(tracesDir, "__tmp__");
4232            try {
4233                if (!tracesDir.exists()) {
4234                    tracesFile.mkdirs();
4235                    if (!SELinux.restorecon(tracesDir.getPath())) {
4236                        return;
4237                    }
4238                }
4239                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4240
4241                if (tracesFile.exists()) {
4242                    tracesTmp.delete();
4243                    tracesFile.renameTo(tracesTmp);
4244                }
4245                StringBuilder sb = new StringBuilder();
4246                Time tobj = new Time();
4247                tobj.set(System.currentTimeMillis());
4248                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4249                sb.append(": ");
4250                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4251                sb.append(" since ");
4252                sb.append(msg);
4253                FileOutputStream fos = new FileOutputStream(tracesFile);
4254                fos.write(sb.toString().getBytes());
4255                if (app == null) {
4256                    fos.write("\n*** No application process!".getBytes());
4257                }
4258                fos.close();
4259                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4260            } catch (IOException e) {
4261                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4262                return;
4263            }
4264
4265            if (app != null) {
4266                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4267                firstPids.add(app.pid);
4268                dumpStackTraces(tracesPath, firstPids, null, null, null);
4269            }
4270
4271            File lastTracesFile = null;
4272            File curTracesFile = null;
4273            for (int i=9; i>=0; i--) {
4274                String name = String.format(Locale.US, "slow%02d.txt", i);
4275                curTracesFile = new File(tracesDir, name);
4276                if (curTracesFile.exists()) {
4277                    if (lastTracesFile != null) {
4278                        curTracesFile.renameTo(lastTracesFile);
4279                    } else {
4280                        curTracesFile.delete();
4281                    }
4282                }
4283                lastTracesFile = curTracesFile;
4284            }
4285            tracesFile.renameTo(curTracesFile);
4286            if (tracesTmp.exists()) {
4287                tracesTmp.renameTo(tracesFile);
4288            }
4289        } finally {
4290            StrictMode.setThreadPolicy(oldPolicy);
4291        }
4292    }
4293
4294    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4295            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4296        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4297        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4298
4299        if (mController != null) {
4300            try {
4301                // 0 == continue, -1 = kill process immediately
4302                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4303                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4304            } catch (RemoteException e) {
4305                mController = null;
4306                Watchdog.getInstance().setActivityController(null);
4307            }
4308        }
4309
4310        long anrTime = SystemClock.uptimeMillis();
4311        if (MONITOR_CPU_USAGE) {
4312            updateCpuStatsNow();
4313        }
4314
4315        synchronized (this) {
4316            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4317            if (mShuttingDown) {
4318                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4319                return;
4320            } else if (app.notResponding) {
4321                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4322                return;
4323            } else if (app.crashing) {
4324                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4325                return;
4326            }
4327
4328            // In case we come through here for the same app before completing
4329            // this one, mark as anring now so we will bail out.
4330            app.notResponding = true;
4331
4332            // Log the ANR to the event log.
4333            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4334                    app.processName, app.info.flags, annotation);
4335
4336            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4337            firstPids.add(app.pid);
4338
4339            int parentPid = app.pid;
4340            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4341            if (parentPid != app.pid) firstPids.add(parentPid);
4342
4343            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4344
4345            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4346                ProcessRecord r = mLruProcesses.get(i);
4347                if (r != null && r.thread != null) {
4348                    int pid = r.pid;
4349                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4350                        if (r.persistent) {
4351                            firstPids.add(pid);
4352                        } else {
4353                            lastPids.put(pid, Boolean.TRUE);
4354                        }
4355                    }
4356                }
4357            }
4358        }
4359
4360        // Log the ANR to the main log.
4361        StringBuilder info = new StringBuilder();
4362        info.setLength(0);
4363        info.append("ANR in ").append(app.processName);
4364        if (activity != null && activity.shortComponentName != null) {
4365            info.append(" (").append(activity.shortComponentName).append(")");
4366        }
4367        info.append("\n");
4368        info.append("PID: ").append(app.pid).append("\n");
4369        if (annotation != null) {
4370            info.append("Reason: ").append(annotation).append("\n");
4371        }
4372        if (parent != null && parent != activity) {
4373            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4374        }
4375
4376        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4377
4378        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4379                NATIVE_STACKS_OF_INTEREST);
4380
4381        String cpuInfo = null;
4382        if (MONITOR_CPU_USAGE) {
4383            updateCpuStatsNow();
4384            synchronized (mProcessCpuThread) {
4385                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4386            }
4387            info.append(processCpuTracker.printCurrentLoad());
4388            info.append(cpuInfo);
4389        }
4390
4391        info.append(processCpuTracker.printCurrentState(anrTime));
4392
4393        Slog.e(TAG, info.toString());
4394        if (tracesFile == null) {
4395            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4396            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4397        }
4398
4399        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4400                cpuInfo, tracesFile, null);
4401
4402        if (mController != null) {
4403            try {
4404                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4405                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4406                if (res != 0) {
4407                    if (res < 0 && app.pid != MY_PID) {
4408                        Process.killProcess(app.pid);
4409                    } else {
4410                        synchronized (this) {
4411                            mServices.scheduleServiceTimeoutLocked(app);
4412                        }
4413                    }
4414                    return;
4415                }
4416            } catch (RemoteException e) {
4417                mController = null;
4418                Watchdog.getInstance().setActivityController(null);
4419            }
4420        }
4421
4422        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4423        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4424                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4425
4426        synchronized (this) {
4427            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4428                killUnneededProcessLocked(app, "background ANR");
4429                return;
4430            }
4431
4432            // Set the app's notResponding state, and look up the errorReportReceiver
4433            makeAppNotRespondingLocked(app,
4434                    activity != null ? activity.shortComponentName : null,
4435                    annotation != null ? "ANR " + annotation : "ANR",
4436                    info.toString());
4437
4438            // Bring up the infamous App Not Responding dialog
4439            Message msg = Message.obtain();
4440            HashMap<String, Object> map = new HashMap<String, Object>();
4441            msg.what = SHOW_NOT_RESPONDING_MSG;
4442            msg.obj = map;
4443            msg.arg1 = aboveSystem ? 1 : 0;
4444            map.put("app", app);
4445            if (activity != null) {
4446                map.put("activity", activity);
4447            }
4448
4449            mHandler.sendMessage(msg);
4450        }
4451    }
4452
4453    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4454        if (!mLaunchWarningShown) {
4455            mLaunchWarningShown = true;
4456            mHandler.post(new Runnable() {
4457                @Override
4458                public void run() {
4459                    synchronized (ActivityManagerService.this) {
4460                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4461                        d.show();
4462                        mHandler.postDelayed(new Runnable() {
4463                            @Override
4464                            public void run() {
4465                                synchronized (ActivityManagerService.this) {
4466                                    d.dismiss();
4467                                    mLaunchWarningShown = false;
4468                                }
4469                            }
4470                        }, 4000);
4471                    }
4472                }
4473            });
4474        }
4475    }
4476
4477    @Override
4478    public boolean clearApplicationUserData(final String packageName,
4479            final IPackageDataObserver observer, int userId) {
4480        enforceNotIsolatedCaller("clearApplicationUserData");
4481        int uid = Binder.getCallingUid();
4482        int pid = Binder.getCallingPid();
4483        userId = handleIncomingUser(pid, uid,
4484                userId, false, true, "clearApplicationUserData", null);
4485        long callingId = Binder.clearCallingIdentity();
4486        try {
4487            IPackageManager pm = AppGlobals.getPackageManager();
4488            int pkgUid = -1;
4489            synchronized(this) {
4490                try {
4491                    pkgUid = pm.getPackageUid(packageName, userId);
4492                } catch (RemoteException e) {
4493                }
4494                if (pkgUid == -1) {
4495                    Slog.w(TAG, "Invalid packageName: " + packageName);
4496                    if (observer != null) {
4497                        try {
4498                            observer.onRemoveCompleted(packageName, false);
4499                        } catch (RemoteException e) {
4500                            Slog.i(TAG, "Observer no longer exists.");
4501                        }
4502                    }
4503                    return false;
4504                }
4505                if (uid == pkgUid || checkComponentPermission(
4506                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4507                        pid, uid, -1, true)
4508                        == PackageManager.PERMISSION_GRANTED) {
4509                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4510                } else {
4511                    throw new SecurityException("PID " + pid + " does not have permission "
4512                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4513                                    + " of package " + packageName);
4514                }
4515            }
4516
4517            try {
4518                // Clear application user data
4519                pm.clearApplicationUserData(packageName, observer, userId);
4520
4521                // Remove all permissions granted from/to this package
4522                removeUriPermissionsForPackageLocked(packageName, userId, true);
4523
4524                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4525                        Uri.fromParts("package", packageName, null));
4526                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4527                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4528                        null, null, 0, null, null, null, false, false, userId);
4529            } catch (RemoteException e) {
4530            }
4531        } finally {
4532            Binder.restoreCallingIdentity(callingId);
4533        }
4534        return true;
4535    }
4536
4537    @Override
4538    public void killBackgroundProcesses(final String packageName, int userId) {
4539        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4540                != PackageManager.PERMISSION_GRANTED &&
4541                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4542                        != PackageManager.PERMISSION_GRANTED) {
4543            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4544                    + Binder.getCallingPid()
4545                    + ", uid=" + Binder.getCallingUid()
4546                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4547            Slog.w(TAG, msg);
4548            throw new SecurityException(msg);
4549        }
4550
4551        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4552                userId, true, true, "killBackgroundProcesses", null);
4553        long callingId = Binder.clearCallingIdentity();
4554        try {
4555            IPackageManager pm = AppGlobals.getPackageManager();
4556            synchronized(this) {
4557                int appId = -1;
4558                try {
4559                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4560                } catch (RemoteException e) {
4561                }
4562                if (appId == -1) {
4563                    Slog.w(TAG, "Invalid packageName: " + packageName);
4564                    return;
4565                }
4566                killPackageProcessesLocked(packageName, appId, userId,
4567                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4568            }
4569        } finally {
4570            Binder.restoreCallingIdentity(callingId);
4571        }
4572    }
4573
4574    @Override
4575    public void killAllBackgroundProcesses() {
4576        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4577                != PackageManager.PERMISSION_GRANTED) {
4578            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4579                    + Binder.getCallingPid()
4580                    + ", uid=" + Binder.getCallingUid()
4581                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4582            Slog.w(TAG, msg);
4583            throw new SecurityException(msg);
4584        }
4585
4586        long callingId = Binder.clearCallingIdentity();
4587        try {
4588            synchronized(this) {
4589                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4590                final int NP = mProcessNames.getMap().size();
4591                for (int ip=0; ip<NP; ip++) {
4592                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4593                    final int NA = apps.size();
4594                    for (int ia=0; ia<NA; ia++) {
4595                        ProcessRecord app = apps.valueAt(ia);
4596                        if (app.persistent) {
4597                            // we don't kill persistent processes
4598                            continue;
4599                        }
4600                        if (app.removed) {
4601                            procs.add(app);
4602                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4603                            app.removed = true;
4604                            procs.add(app);
4605                        }
4606                    }
4607                }
4608
4609                int N = procs.size();
4610                for (int i=0; i<N; i++) {
4611                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4612                }
4613                mAllowLowerMemLevel = true;
4614                updateOomAdjLocked();
4615                doLowMemReportIfNeededLocked(null);
4616            }
4617        } finally {
4618            Binder.restoreCallingIdentity(callingId);
4619        }
4620    }
4621
4622    @Override
4623    public void forceStopPackage(final String packageName, int userId) {
4624        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4625                != PackageManager.PERMISSION_GRANTED) {
4626            String msg = "Permission Denial: forceStopPackage() from pid="
4627                    + Binder.getCallingPid()
4628                    + ", uid=" + Binder.getCallingUid()
4629                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4630            Slog.w(TAG, msg);
4631            throw new SecurityException(msg);
4632        }
4633        final int callingPid = Binder.getCallingPid();
4634        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4635                userId, true, true, "forceStopPackage", null);
4636        long callingId = Binder.clearCallingIdentity();
4637        try {
4638            IPackageManager pm = AppGlobals.getPackageManager();
4639            synchronized(this) {
4640                int[] users = userId == UserHandle.USER_ALL
4641                        ? getUsersLocked() : new int[] { userId };
4642                for (int user : users) {
4643                    int pkgUid = -1;
4644                    try {
4645                        pkgUid = pm.getPackageUid(packageName, user);
4646                    } catch (RemoteException e) {
4647                    }
4648                    if (pkgUid == -1) {
4649                        Slog.w(TAG, "Invalid packageName: " + packageName);
4650                        continue;
4651                    }
4652                    try {
4653                        pm.setPackageStoppedState(packageName, true, user);
4654                    } catch (RemoteException e) {
4655                    } catch (IllegalArgumentException e) {
4656                        Slog.w(TAG, "Failed trying to unstop package "
4657                                + packageName + ": " + e);
4658                    }
4659                    if (isUserRunningLocked(user, false)) {
4660                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4661                    }
4662                }
4663            }
4664        } finally {
4665            Binder.restoreCallingIdentity(callingId);
4666        }
4667    }
4668
4669    /*
4670     * The pkg name and app id have to be specified.
4671     */
4672    @Override
4673    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4674        if (pkg == null) {
4675            return;
4676        }
4677        // Make sure the uid is valid.
4678        if (appid < 0) {
4679            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4680            return;
4681        }
4682        int callerUid = Binder.getCallingUid();
4683        // Only the system server can kill an application
4684        if (callerUid == Process.SYSTEM_UID) {
4685            // Post an aysnc message to kill the application
4686            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4687            msg.arg1 = appid;
4688            msg.arg2 = 0;
4689            Bundle bundle = new Bundle();
4690            bundle.putString("pkg", pkg);
4691            bundle.putString("reason", reason);
4692            msg.obj = bundle;
4693            mHandler.sendMessage(msg);
4694        } else {
4695            throw new SecurityException(callerUid + " cannot kill pkg: " +
4696                    pkg);
4697        }
4698    }
4699
4700    @Override
4701    public void closeSystemDialogs(String reason) {
4702        enforceNotIsolatedCaller("closeSystemDialogs");
4703
4704        final int pid = Binder.getCallingPid();
4705        final int uid = Binder.getCallingUid();
4706        final long origId = Binder.clearCallingIdentity();
4707        try {
4708            synchronized (this) {
4709                // Only allow this from foreground processes, so that background
4710                // applications can't abuse it to prevent system UI from being shown.
4711                if (uid >= Process.FIRST_APPLICATION_UID) {
4712                    ProcessRecord proc;
4713                    synchronized (mPidsSelfLocked) {
4714                        proc = mPidsSelfLocked.get(pid);
4715                    }
4716                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4717                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4718                                + " from background process " + proc);
4719                        return;
4720                    }
4721                }
4722                closeSystemDialogsLocked(reason);
4723            }
4724        } finally {
4725            Binder.restoreCallingIdentity(origId);
4726        }
4727    }
4728
4729    void closeSystemDialogsLocked(String reason) {
4730        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4731        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4732                | Intent.FLAG_RECEIVER_FOREGROUND);
4733        if (reason != null) {
4734            intent.putExtra("reason", reason);
4735        }
4736        mWindowManager.closeSystemDialogs(reason);
4737
4738        mStackSupervisor.closeSystemDialogsLocked();
4739
4740        broadcastIntentLocked(null, null, intent, null,
4741                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4742                Process.SYSTEM_UID, UserHandle.USER_ALL);
4743    }
4744
4745    @Override
4746    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4747        enforceNotIsolatedCaller("getProcessMemoryInfo");
4748        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4749        for (int i=pids.length-1; i>=0; i--) {
4750            ProcessRecord proc;
4751            int oomAdj;
4752            synchronized (this) {
4753                synchronized (mPidsSelfLocked) {
4754                    proc = mPidsSelfLocked.get(pids[i]);
4755                    oomAdj = proc != null ? proc.setAdj : 0;
4756                }
4757            }
4758            infos[i] = new Debug.MemoryInfo();
4759            Debug.getMemoryInfo(pids[i], infos[i]);
4760            if (proc != null) {
4761                synchronized (this) {
4762                    if (proc.thread != null && proc.setAdj == oomAdj) {
4763                        // Record this for posterity if the process has been stable.
4764                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4765                                infos[i].getTotalUss(), false, proc.pkgList);
4766                    }
4767                }
4768            }
4769        }
4770        return infos;
4771    }
4772
4773    @Override
4774    public long[] getProcessPss(int[] pids) {
4775        enforceNotIsolatedCaller("getProcessPss");
4776        long[] pss = new long[pids.length];
4777        for (int i=pids.length-1; i>=0; i--) {
4778            ProcessRecord proc;
4779            int oomAdj;
4780            synchronized (this) {
4781                synchronized (mPidsSelfLocked) {
4782                    proc = mPidsSelfLocked.get(pids[i]);
4783                    oomAdj = proc != null ? proc.setAdj : 0;
4784                }
4785            }
4786            long[] tmpUss = new long[1];
4787            pss[i] = Debug.getPss(pids[i], tmpUss);
4788            if (proc != null) {
4789                synchronized (this) {
4790                    if (proc.thread != null && proc.setAdj == oomAdj) {
4791                        // Record this for posterity if the process has been stable.
4792                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4793                    }
4794                }
4795            }
4796        }
4797        return pss;
4798    }
4799
4800    @Override
4801    public void killApplicationProcess(String processName, int uid) {
4802        if (processName == null) {
4803            return;
4804        }
4805
4806        int callerUid = Binder.getCallingUid();
4807        // Only the system server can kill an application
4808        if (callerUid == Process.SYSTEM_UID) {
4809            synchronized (this) {
4810                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4811                if (app != null && app.thread != null) {
4812                    try {
4813                        app.thread.scheduleSuicide();
4814                    } catch (RemoteException e) {
4815                        // If the other end already died, then our work here is done.
4816                    }
4817                } else {
4818                    Slog.w(TAG, "Process/uid not found attempting kill of "
4819                            + processName + " / " + uid);
4820                }
4821            }
4822        } else {
4823            throw new SecurityException(callerUid + " cannot kill app process: " +
4824                    processName);
4825        }
4826    }
4827
4828    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4829        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4830                false, true, false, false, UserHandle.getUserId(uid), reason);
4831        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4832                Uri.fromParts("package", packageName, null));
4833        if (!mProcessesReady) {
4834            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4835                    | Intent.FLAG_RECEIVER_FOREGROUND);
4836        }
4837        intent.putExtra(Intent.EXTRA_UID, uid);
4838        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4839        broadcastIntentLocked(null, null, intent,
4840                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4841                false, false,
4842                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4843    }
4844
4845    private void forceStopUserLocked(int userId, String reason) {
4846        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4847        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4848        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4849                | Intent.FLAG_RECEIVER_FOREGROUND);
4850        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4851        broadcastIntentLocked(null, null, intent,
4852                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4853                false, false,
4854                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4855    }
4856
4857    private final boolean killPackageProcessesLocked(String packageName, int appId,
4858            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4859            boolean doit, boolean evenPersistent, String reason) {
4860        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4861
4862        // Remove all processes this package may have touched: all with the
4863        // same UID (except for the system or root user), and all whose name
4864        // matches the package name.
4865        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4866        final int NP = mProcessNames.getMap().size();
4867        for (int ip=0; ip<NP; ip++) {
4868            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4869            final int NA = apps.size();
4870            for (int ia=0; ia<NA; ia++) {
4871                ProcessRecord app = apps.valueAt(ia);
4872                if (app.persistent && !evenPersistent) {
4873                    // we don't kill persistent processes
4874                    continue;
4875                }
4876                if (app.removed) {
4877                    if (doit) {
4878                        procs.add(app);
4879                    }
4880                    continue;
4881                }
4882
4883                // Skip process if it doesn't meet our oom adj requirement.
4884                if (app.setAdj < minOomAdj) {
4885                    continue;
4886                }
4887
4888                // If no package is specified, we call all processes under the
4889                // give user id.
4890                if (packageName == null) {
4891                    if (app.userId != userId) {
4892                        continue;
4893                    }
4894                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4895                        continue;
4896                    }
4897                // Package has been specified, we want to hit all processes
4898                // that match it.  We need to qualify this by the processes
4899                // that are running under the specified app and user ID.
4900                } else {
4901                    if (UserHandle.getAppId(app.uid) != appId) {
4902                        continue;
4903                    }
4904                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4905                        continue;
4906                    }
4907                    if (!app.pkgList.containsKey(packageName)) {
4908                        continue;
4909                    }
4910                }
4911
4912                // Process has passed all conditions, kill it!
4913                if (!doit) {
4914                    return true;
4915                }
4916                app.removed = true;
4917                procs.add(app);
4918            }
4919        }
4920
4921        int N = procs.size();
4922        for (int i=0; i<N; i++) {
4923            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4924        }
4925        updateOomAdjLocked();
4926        return N > 0;
4927    }
4928
4929    private final boolean forceStopPackageLocked(String name, int appId,
4930            boolean callerWillRestart, boolean purgeCache, boolean doit,
4931            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4932        int i;
4933        int N;
4934
4935        if (userId == UserHandle.USER_ALL && name == null) {
4936            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4937        }
4938
4939        if (appId < 0 && name != null) {
4940            try {
4941                appId = UserHandle.getAppId(
4942                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4943            } catch (RemoteException e) {
4944            }
4945        }
4946
4947        if (doit) {
4948            if (name != null) {
4949                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4950                        + " user=" + userId + ": " + reason);
4951            } else {
4952                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4953            }
4954
4955            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4956            for (int ip=pmap.size()-1; ip>=0; ip--) {
4957                SparseArray<Long> ba = pmap.valueAt(ip);
4958                for (i=ba.size()-1; i>=0; i--) {
4959                    boolean remove = false;
4960                    final int entUid = ba.keyAt(i);
4961                    if (name != null) {
4962                        if (userId == UserHandle.USER_ALL) {
4963                            if (UserHandle.getAppId(entUid) == appId) {
4964                                remove = true;
4965                            }
4966                        } else {
4967                            if (entUid == UserHandle.getUid(userId, appId)) {
4968                                remove = true;
4969                            }
4970                        }
4971                    } else if (UserHandle.getUserId(entUid) == userId) {
4972                        remove = true;
4973                    }
4974                    if (remove) {
4975                        ba.removeAt(i);
4976                    }
4977                }
4978                if (ba.size() == 0) {
4979                    pmap.removeAt(ip);
4980                }
4981            }
4982        }
4983
4984        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4985                -100, callerWillRestart, true, doit, evenPersistent,
4986                name == null ? ("stop user " + userId) : ("stop " + name));
4987
4988        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4989            if (!doit) {
4990                return true;
4991            }
4992            didSomething = true;
4993        }
4994
4995        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4996            if (!doit) {
4997                return true;
4998            }
4999            didSomething = true;
5000        }
5001
5002        if (name == null) {
5003            // Remove all sticky broadcasts from this user.
5004            mStickyBroadcasts.remove(userId);
5005        }
5006
5007        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5008        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5009                userId, providers)) {
5010            if (!doit) {
5011                return true;
5012            }
5013            didSomething = true;
5014        }
5015        N = providers.size();
5016        for (i=0; i<N; i++) {
5017            removeDyingProviderLocked(null, providers.get(i), true);
5018        }
5019
5020        // Remove transient permissions granted from/to this package/user
5021        removeUriPermissionsForPackageLocked(name, userId, false);
5022
5023        if (name == null || uninstalling) {
5024            // Remove pending intents.  For now we only do this when force
5025            // stopping users, because we have some problems when doing this
5026            // for packages -- app widgets are not currently cleaned up for
5027            // such packages, so they can be left with bad pending intents.
5028            if (mIntentSenderRecords.size() > 0) {
5029                Iterator<WeakReference<PendingIntentRecord>> it
5030                        = mIntentSenderRecords.values().iterator();
5031                while (it.hasNext()) {
5032                    WeakReference<PendingIntentRecord> wpir = it.next();
5033                    if (wpir == null) {
5034                        it.remove();
5035                        continue;
5036                    }
5037                    PendingIntentRecord pir = wpir.get();
5038                    if (pir == null) {
5039                        it.remove();
5040                        continue;
5041                    }
5042                    if (name == null) {
5043                        // Stopping user, remove all objects for the user.
5044                        if (pir.key.userId != userId) {
5045                            // Not the same user, skip it.
5046                            continue;
5047                        }
5048                    } else {
5049                        if (UserHandle.getAppId(pir.uid) != appId) {
5050                            // Different app id, skip it.
5051                            continue;
5052                        }
5053                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5054                            // Different user, skip it.
5055                            continue;
5056                        }
5057                        if (!pir.key.packageName.equals(name)) {
5058                            // Different package, skip it.
5059                            continue;
5060                        }
5061                    }
5062                    if (!doit) {
5063                        return true;
5064                    }
5065                    didSomething = true;
5066                    it.remove();
5067                    pir.canceled = true;
5068                    if (pir.key.activity != null) {
5069                        pir.key.activity.pendingResults.remove(pir.ref);
5070                    }
5071                }
5072            }
5073        }
5074
5075        if (doit) {
5076            if (purgeCache && name != null) {
5077                AttributeCache ac = AttributeCache.instance();
5078                if (ac != null) {
5079                    ac.removePackage(name);
5080                }
5081            }
5082            if (mBooted) {
5083                mStackSupervisor.resumeTopActivitiesLocked();
5084                mStackSupervisor.scheduleIdleLocked();
5085            }
5086        }
5087
5088        return didSomething;
5089    }
5090
5091    private final boolean removeProcessLocked(ProcessRecord app,
5092            boolean callerWillRestart, boolean allowRestart, String reason) {
5093        final String name = app.processName;
5094        final int uid = app.uid;
5095        if (DEBUG_PROCESSES) Slog.d(
5096            TAG, "Force removing proc " + app.toShortString() + " (" + name
5097            + "/" + uid + ")");
5098
5099        mProcessNames.remove(name, uid);
5100        mIsolatedProcesses.remove(app.uid);
5101        if (mHeavyWeightProcess == app) {
5102            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5103                    mHeavyWeightProcess.userId, 0));
5104            mHeavyWeightProcess = null;
5105        }
5106        boolean needRestart = false;
5107        if (app.pid > 0 && app.pid != MY_PID) {
5108            int pid = app.pid;
5109            synchronized (mPidsSelfLocked) {
5110                mPidsSelfLocked.remove(pid);
5111                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5112            }
5113            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5114                    app.processName, app.info.uid);
5115            if (app.isolated) {
5116                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5117            }
5118            killUnneededProcessLocked(app, reason);
5119            handleAppDiedLocked(app, true, allowRestart);
5120            removeLruProcessLocked(app);
5121
5122            if (app.persistent && !app.isolated) {
5123                if (!callerWillRestart) {
5124                    addAppLocked(app.info, false, null /* ABI override */);
5125                } else {
5126                    needRestart = true;
5127                }
5128            }
5129        } else {
5130            mRemovedProcesses.add(app);
5131        }
5132
5133        return needRestart;
5134    }
5135
5136    private final void processStartTimedOutLocked(ProcessRecord app) {
5137        final int pid = app.pid;
5138        boolean gone = false;
5139        synchronized (mPidsSelfLocked) {
5140            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5141            if (knownApp != null && knownApp.thread == null) {
5142                mPidsSelfLocked.remove(pid);
5143                gone = true;
5144            }
5145        }
5146
5147        if (gone) {
5148            Slog.w(TAG, "Process " + app + " failed to attach");
5149            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5150                    pid, app.uid, app.processName);
5151            mProcessNames.remove(app.processName, app.uid);
5152            mIsolatedProcesses.remove(app.uid);
5153            if (mHeavyWeightProcess == app) {
5154                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5155                        mHeavyWeightProcess.userId, 0));
5156                mHeavyWeightProcess = null;
5157            }
5158            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5159                    app.processName, app.info.uid);
5160            if (app.isolated) {
5161                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5162            }
5163            // Take care of any launching providers waiting for this process.
5164            checkAppInLaunchingProvidersLocked(app, true);
5165            // Take care of any services that are waiting for the process.
5166            mServices.processStartTimedOutLocked(app);
5167            killUnneededProcessLocked(app, "start timeout");
5168            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5169                Slog.w(TAG, "Unattached app died before backup, skipping");
5170                try {
5171                    IBackupManager bm = IBackupManager.Stub.asInterface(
5172                            ServiceManager.getService(Context.BACKUP_SERVICE));
5173                    bm.agentDisconnected(app.info.packageName);
5174                } catch (RemoteException e) {
5175                    // Can't happen; the backup manager is local
5176                }
5177            }
5178            if (isPendingBroadcastProcessLocked(pid)) {
5179                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5180                skipPendingBroadcastLocked(pid);
5181            }
5182        } else {
5183            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5184        }
5185    }
5186
5187    private final boolean attachApplicationLocked(IApplicationThread thread,
5188            int pid) {
5189
5190        // Find the application record that is being attached...  either via
5191        // the pid if we are running in multiple processes, or just pull the
5192        // next app record if we are emulating process with anonymous threads.
5193        ProcessRecord app;
5194        if (pid != MY_PID && pid >= 0) {
5195            synchronized (mPidsSelfLocked) {
5196                app = mPidsSelfLocked.get(pid);
5197            }
5198        } else {
5199            app = null;
5200        }
5201
5202        if (app == null) {
5203            Slog.w(TAG, "No pending application record for pid " + pid
5204                    + " (IApplicationThread " + thread + "); dropping process");
5205            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5206            if (pid > 0 && pid != MY_PID) {
5207                Process.killProcessQuiet(pid);
5208            } else {
5209                try {
5210                    thread.scheduleExit();
5211                } catch (Exception e) {
5212                    // Ignore exceptions.
5213                }
5214            }
5215            return false;
5216        }
5217
5218        // If this application record is still attached to a previous
5219        // process, clean it up now.
5220        if (app.thread != null) {
5221            handleAppDiedLocked(app, true, true);
5222        }
5223
5224        // Tell the process all about itself.
5225
5226        if (localLOGV) Slog.v(
5227                TAG, "Binding process pid " + pid + " to record " + app);
5228
5229        final String processName = app.processName;
5230        try {
5231            AppDeathRecipient adr = new AppDeathRecipient(
5232                    app, pid, thread);
5233            thread.asBinder().linkToDeath(adr, 0);
5234            app.deathRecipient = adr;
5235        } catch (RemoteException e) {
5236            app.resetPackageList(mProcessStats);
5237            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5238            return false;
5239        }
5240
5241        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5242
5243        app.makeActive(thread, mProcessStats);
5244        app.curAdj = app.setAdj = -100;
5245        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5246        app.forcingToForeground = null;
5247        updateProcessForegroundLocked(app, false, false);
5248        app.hasShownUi = false;
5249        app.debugging = false;
5250        app.cached = false;
5251
5252        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5253
5254        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5255        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5256
5257        if (!normalMode) {
5258            Slog.i(TAG, "Launching preboot mode app: " + app);
5259        }
5260
5261        if (localLOGV) Slog.v(
5262            TAG, "New app record " + app
5263            + " thread=" + thread.asBinder() + " pid=" + pid);
5264        try {
5265            int testMode = IApplicationThread.DEBUG_OFF;
5266            if (mDebugApp != null && mDebugApp.equals(processName)) {
5267                testMode = mWaitForDebugger
5268                    ? IApplicationThread.DEBUG_WAIT
5269                    : IApplicationThread.DEBUG_ON;
5270                app.debugging = true;
5271                if (mDebugTransient) {
5272                    mDebugApp = mOrigDebugApp;
5273                    mWaitForDebugger = mOrigWaitForDebugger;
5274                }
5275            }
5276            String profileFile = app.instrumentationProfileFile;
5277            ParcelFileDescriptor profileFd = null;
5278            boolean profileAutoStop = false;
5279            if (mProfileApp != null && mProfileApp.equals(processName)) {
5280                mProfileProc = app;
5281                profileFile = mProfileFile;
5282                profileFd = mProfileFd;
5283                profileAutoStop = mAutoStopProfiler;
5284            }
5285            boolean enableOpenGlTrace = false;
5286            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5287                enableOpenGlTrace = true;
5288                mOpenGlTraceApp = null;
5289            }
5290
5291            // If the app is being launched for restore or full backup, set it up specially
5292            boolean isRestrictedBackupMode = false;
5293            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5294                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5295                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5296                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5297            }
5298
5299            ensurePackageDexOpt(app.instrumentationInfo != null
5300                    ? app.instrumentationInfo.packageName
5301                    : app.info.packageName);
5302            if (app.instrumentationClass != null) {
5303                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5304            }
5305            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5306                    + processName + " with config " + mConfiguration);
5307            ApplicationInfo appInfo = app.instrumentationInfo != null
5308                    ? app.instrumentationInfo : app.info;
5309            app.compat = compatibilityInfoForPackageLocked(appInfo);
5310            if (profileFd != null) {
5311                profileFd = profileFd.dup();
5312            }
5313            thread.bindApplication(processName, appInfo, providers,
5314                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5315                    app.instrumentationArguments, app.instrumentationWatcher,
5316                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5317                    isRestrictedBackupMode || !normalMode, app.persistent,
5318                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5319                    mCoreSettingsObserver.getCoreSettingsLocked());
5320            updateLruProcessLocked(app, false, null);
5321            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5322        } catch (Exception e) {
5323            // todo: Yikes!  What should we do?  For now we will try to
5324            // start another process, but that could easily get us in
5325            // an infinite loop of restarting processes...
5326            Slog.w(TAG, "Exception thrown during bind!", e);
5327
5328            app.resetPackageList(mProcessStats);
5329            app.unlinkDeathRecipient();
5330            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5331            return false;
5332        }
5333
5334        // Remove this record from the list of starting applications.
5335        mPersistentStartingProcesses.remove(app);
5336        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5337                "Attach application locked removing on hold: " + app);
5338        mProcessesOnHold.remove(app);
5339
5340        boolean badApp = false;
5341        boolean didSomething = false;
5342
5343        // See if the top visible activity is waiting to run in this process...
5344        if (normalMode) {
5345            try {
5346                if (mStackSupervisor.attachApplicationLocked(app)) {
5347                    didSomething = true;
5348                }
5349            } catch (Exception e) {
5350                badApp = true;
5351            }
5352        }
5353
5354        // Find any services that should be running in this process...
5355        if (!badApp) {
5356            try {
5357                didSomething |= mServices.attachApplicationLocked(app, processName);
5358            } catch (Exception e) {
5359                badApp = true;
5360            }
5361        }
5362
5363        // Check if a next-broadcast receiver is in this process...
5364        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5365            try {
5366                didSomething |= sendPendingBroadcastsLocked(app);
5367            } catch (Exception e) {
5368                // If the app died trying to launch the receiver we declare it 'bad'
5369                badApp = true;
5370            }
5371        }
5372
5373        // Check whether the next backup agent is in this process...
5374        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5375            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5376            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5377            try {
5378                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5379                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5380                        mBackupTarget.backupMode);
5381            } catch (Exception e) {
5382                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5383                e.printStackTrace();
5384            }
5385        }
5386
5387        if (badApp) {
5388            // todo: Also need to kill application to deal with all
5389            // kinds of exceptions.
5390            handleAppDiedLocked(app, false, true);
5391            return false;
5392        }
5393
5394        if (!didSomething) {
5395            updateOomAdjLocked();
5396        }
5397
5398        return true;
5399    }
5400
5401    @Override
5402    public final void attachApplication(IApplicationThread thread) {
5403        synchronized (this) {
5404            int callingPid = Binder.getCallingPid();
5405            final long origId = Binder.clearCallingIdentity();
5406            attachApplicationLocked(thread, callingPid);
5407            Binder.restoreCallingIdentity(origId);
5408        }
5409    }
5410
5411    @Override
5412    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5413        final long origId = Binder.clearCallingIdentity();
5414        synchronized (this) {
5415            ActivityStack stack = ActivityRecord.getStackLocked(token);
5416            if (stack != null) {
5417                ActivityRecord r =
5418                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5419                if (stopProfiling) {
5420                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5421                        try {
5422                            mProfileFd.close();
5423                        } catch (IOException e) {
5424                        }
5425                        clearProfilerLocked();
5426                    }
5427                }
5428            }
5429        }
5430        Binder.restoreCallingIdentity(origId);
5431    }
5432
5433    void enableScreenAfterBoot() {
5434        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5435                SystemClock.uptimeMillis());
5436        mWindowManager.enableScreenAfterBoot();
5437
5438        synchronized (this) {
5439            updateEventDispatchingLocked();
5440        }
5441    }
5442
5443    @Override
5444    public void showBootMessage(final CharSequence msg, final boolean always) {
5445        enforceNotIsolatedCaller("showBootMessage");
5446        mWindowManager.showBootMessage(msg, always);
5447    }
5448
5449    @Override
5450    public void dismissKeyguardOnNextActivity() {
5451        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5452        final long token = Binder.clearCallingIdentity();
5453        try {
5454            synchronized (this) {
5455                if (DEBUG_LOCKSCREEN) logLockScreen("");
5456                if (mLockScreenShown) {
5457                    mLockScreenShown = false;
5458                    comeOutOfSleepIfNeededLocked();
5459                }
5460                mStackSupervisor.setDismissKeyguard(true);
5461            }
5462        } finally {
5463            Binder.restoreCallingIdentity(token);
5464        }
5465    }
5466
5467    final void finishBooting() {
5468        // Register receivers to handle package update events
5469        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5470
5471        synchronized (this) {
5472            // Ensure that any processes we had put on hold are now started
5473            // up.
5474            final int NP = mProcessesOnHold.size();
5475            if (NP > 0) {
5476                ArrayList<ProcessRecord> procs =
5477                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5478                for (int ip=0; ip<NP; ip++) {
5479                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5480                            + procs.get(ip));
5481                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5482                }
5483            }
5484
5485            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5486                // Start looking for apps that are abusing wake locks.
5487                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5488                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5489                // Tell anyone interested that we are done booting!
5490                SystemProperties.set("sys.boot_completed", "1");
5491                SystemProperties.set("dev.bootcomplete", "1");
5492                for (int i=0; i<mStartedUsers.size(); i++) {
5493                    UserStartedState uss = mStartedUsers.valueAt(i);
5494                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5495                        uss.mState = UserStartedState.STATE_RUNNING;
5496                        final int userId = mStartedUsers.keyAt(i);
5497                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5498                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5499                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5500                        broadcastIntentLocked(null, null, intent, null,
5501                                new IIntentReceiver.Stub() {
5502                                    @Override
5503                                    public void performReceive(Intent intent, int resultCode,
5504                                            String data, Bundle extras, boolean ordered,
5505                                            boolean sticky, int sendingUser) {
5506                                        synchronized (ActivityManagerService.this) {
5507                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5508                                                    true, false);
5509                                        }
5510                                    }
5511                                },
5512                                0, null, null,
5513                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5514                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5515                                userId);
5516                    }
5517                }
5518                scheduleStartProfilesLocked();
5519            }
5520        }
5521    }
5522
5523    final void ensureBootCompleted() {
5524        boolean booting;
5525        boolean enableScreen;
5526        synchronized (this) {
5527            booting = mBooting;
5528            mBooting = false;
5529            enableScreen = !mBooted;
5530            mBooted = true;
5531        }
5532
5533        if (booting) {
5534            finishBooting();
5535        }
5536
5537        if (enableScreen) {
5538            enableScreenAfterBoot();
5539        }
5540    }
5541
5542    @Override
5543    public final void activityResumed(IBinder token) {
5544        final long origId = Binder.clearCallingIdentity();
5545        synchronized(this) {
5546            ActivityStack stack = ActivityRecord.getStackLocked(token);
5547            if (stack != null) {
5548                ActivityRecord.activityResumedLocked(token);
5549            }
5550        }
5551        Binder.restoreCallingIdentity(origId);
5552    }
5553
5554    @Override
5555    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5556        final long origId = Binder.clearCallingIdentity();
5557        synchronized(this) {
5558            ActivityStack stack = ActivityRecord.getStackLocked(token);
5559            if (stack != null) {
5560                stack.activityPausedLocked(token, false, persistentState);
5561            }
5562        }
5563        Binder.restoreCallingIdentity(origId);
5564    }
5565
5566    @Override
5567    public final void activityStopped(IBinder token, Bundle icicle,
5568            PersistableBundle persistentState, CharSequence description) {
5569        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5570
5571        // Refuse possible leaked file descriptors
5572        if (icicle != null && icicle.hasFileDescriptors()) {
5573            throw new IllegalArgumentException("File descriptors passed in Bundle");
5574        }
5575
5576        final long origId = Binder.clearCallingIdentity();
5577
5578        synchronized (this) {
5579            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5580            if (r != null) {
5581                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5582            }
5583        }
5584
5585        trimApplications();
5586
5587        Binder.restoreCallingIdentity(origId);
5588    }
5589
5590    @Override
5591    public final void activityDestroyed(IBinder token) {
5592        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5593        synchronized (this) {
5594            ActivityStack stack = ActivityRecord.getStackLocked(token);
5595            if (stack != null) {
5596                stack.activityDestroyedLocked(token);
5597            }
5598        }
5599    }
5600
5601    @Override
5602    public String getCallingPackage(IBinder token) {
5603        synchronized (this) {
5604            ActivityRecord r = getCallingRecordLocked(token);
5605            return r != null ? r.info.packageName : null;
5606        }
5607    }
5608
5609    @Override
5610    public ComponentName getCallingActivity(IBinder token) {
5611        synchronized (this) {
5612            ActivityRecord r = getCallingRecordLocked(token);
5613            return r != null ? r.intent.getComponent() : null;
5614        }
5615    }
5616
5617    private ActivityRecord getCallingRecordLocked(IBinder token) {
5618        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5619        if (r == null) {
5620            return null;
5621        }
5622        return r.resultTo;
5623    }
5624
5625    @Override
5626    public ComponentName getActivityClassForToken(IBinder token) {
5627        synchronized(this) {
5628            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5629            if (r == null) {
5630                return null;
5631            }
5632            return r.intent.getComponent();
5633        }
5634    }
5635
5636    @Override
5637    public String getPackageForToken(IBinder token) {
5638        synchronized(this) {
5639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5640            if (r == null) {
5641                return null;
5642            }
5643            return r.packageName;
5644        }
5645    }
5646
5647    @Override
5648    public IIntentSender getIntentSender(int type,
5649            String packageName, IBinder token, String resultWho,
5650            int requestCode, Intent[] intents, String[] resolvedTypes,
5651            int flags, Bundle options, int userId) {
5652        enforceNotIsolatedCaller("getIntentSender");
5653        // Refuse possible leaked file descriptors
5654        if (intents != null) {
5655            if (intents.length < 1) {
5656                throw new IllegalArgumentException("Intents array length must be >= 1");
5657            }
5658            for (int i=0; i<intents.length; i++) {
5659                Intent intent = intents[i];
5660                if (intent != null) {
5661                    if (intent.hasFileDescriptors()) {
5662                        throw new IllegalArgumentException("File descriptors passed in Intent");
5663                    }
5664                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5665                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5666                        throw new IllegalArgumentException(
5667                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5668                    }
5669                    intents[i] = new Intent(intent);
5670                }
5671            }
5672            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5673                throw new IllegalArgumentException(
5674                        "Intent array length does not match resolvedTypes length");
5675            }
5676        }
5677        if (options != null) {
5678            if (options.hasFileDescriptors()) {
5679                throw new IllegalArgumentException("File descriptors passed in options");
5680            }
5681        }
5682
5683        synchronized(this) {
5684            int callingUid = Binder.getCallingUid();
5685            int origUserId = userId;
5686            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5687                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5688                    "getIntentSender", null);
5689            if (origUserId == UserHandle.USER_CURRENT) {
5690                // We don't want to evaluate this until the pending intent is
5691                // actually executed.  However, we do want to always do the
5692                // security checking for it above.
5693                userId = UserHandle.USER_CURRENT;
5694            }
5695            try {
5696                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5697                    int uid = AppGlobals.getPackageManager()
5698                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5699                    if (!UserHandle.isSameApp(callingUid, uid)) {
5700                        String msg = "Permission Denial: getIntentSender() from pid="
5701                            + Binder.getCallingPid()
5702                            + ", uid=" + Binder.getCallingUid()
5703                            + ", (need uid=" + uid + ")"
5704                            + " is not allowed to send as package " + packageName;
5705                        Slog.w(TAG, msg);
5706                        throw new SecurityException(msg);
5707                    }
5708                }
5709
5710                return getIntentSenderLocked(type, packageName, callingUid, userId,
5711                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5712
5713            } catch (RemoteException e) {
5714                throw new SecurityException(e);
5715            }
5716        }
5717    }
5718
5719    IIntentSender getIntentSenderLocked(int type, String packageName,
5720            int callingUid, int userId, IBinder token, String resultWho,
5721            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5722            Bundle options) {
5723        if (DEBUG_MU)
5724            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5725        ActivityRecord activity = null;
5726        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5727            activity = ActivityRecord.isInStackLocked(token);
5728            if (activity == null) {
5729                return null;
5730            }
5731            if (activity.finishing) {
5732                return null;
5733            }
5734        }
5735
5736        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5737        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5738        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5739        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5740                |PendingIntent.FLAG_UPDATE_CURRENT);
5741
5742        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5743                type, packageName, activity, resultWho,
5744                requestCode, intents, resolvedTypes, flags, options, userId);
5745        WeakReference<PendingIntentRecord> ref;
5746        ref = mIntentSenderRecords.get(key);
5747        PendingIntentRecord rec = ref != null ? ref.get() : null;
5748        if (rec != null) {
5749            if (!cancelCurrent) {
5750                if (updateCurrent) {
5751                    if (rec.key.requestIntent != null) {
5752                        rec.key.requestIntent.replaceExtras(intents != null ?
5753                                intents[intents.length - 1] : null);
5754                    }
5755                    if (intents != null) {
5756                        intents[intents.length-1] = rec.key.requestIntent;
5757                        rec.key.allIntents = intents;
5758                        rec.key.allResolvedTypes = resolvedTypes;
5759                    } else {
5760                        rec.key.allIntents = null;
5761                        rec.key.allResolvedTypes = null;
5762                    }
5763                }
5764                return rec;
5765            }
5766            rec.canceled = true;
5767            mIntentSenderRecords.remove(key);
5768        }
5769        if (noCreate) {
5770            return rec;
5771        }
5772        rec = new PendingIntentRecord(this, key, callingUid);
5773        mIntentSenderRecords.put(key, rec.ref);
5774        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5775            if (activity.pendingResults == null) {
5776                activity.pendingResults
5777                        = new HashSet<WeakReference<PendingIntentRecord>>();
5778            }
5779            activity.pendingResults.add(rec.ref);
5780        }
5781        return rec;
5782    }
5783
5784    @Override
5785    public void cancelIntentSender(IIntentSender sender) {
5786        if (!(sender instanceof PendingIntentRecord)) {
5787            return;
5788        }
5789        synchronized(this) {
5790            PendingIntentRecord rec = (PendingIntentRecord)sender;
5791            try {
5792                int uid = AppGlobals.getPackageManager()
5793                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5794                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5795                    String msg = "Permission Denial: cancelIntentSender() from pid="
5796                        + Binder.getCallingPid()
5797                        + ", uid=" + Binder.getCallingUid()
5798                        + " is not allowed to cancel packges "
5799                        + rec.key.packageName;
5800                    Slog.w(TAG, msg);
5801                    throw new SecurityException(msg);
5802                }
5803            } catch (RemoteException e) {
5804                throw new SecurityException(e);
5805            }
5806            cancelIntentSenderLocked(rec, true);
5807        }
5808    }
5809
5810    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5811        rec.canceled = true;
5812        mIntentSenderRecords.remove(rec.key);
5813        if (cleanActivity && rec.key.activity != null) {
5814            rec.key.activity.pendingResults.remove(rec.ref);
5815        }
5816    }
5817
5818    @Override
5819    public String getPackageForIntentSender(IIntentSender pendingResult) {
5820        if (!(pendingResult instanceof PendingIntentRecord)) {
5821            return null;
5822        }
5823        try {
5824            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5825            return res.key.packageName;
5826        } catch (ClassCastException e) {
5827        }
5828        return null;
5829    }
5830
5831    @Override
5832    public int getUidForIntentSender(IIntentSender sender) {
5833        if (sender instanceof PendingIntentRecord) {
5834            try {
5835                PendingIntentRecord res = (PendingIntentRecord)sender;
5836                return res.uid;
5837            } catch (ClassCastException e) {
5838            }
5839        }
5840        return -1;
5841    }
5842
5843    @Override
5844    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5845        if (!(pendingResult instanceof PendingIntentRecord)) {
5846            return false;
5847        }
5848        try {
5849            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5850            if (res.key.allIntents == null) {
5851                return false;
5852            }
5853            for (int i=0; i<res.key.allIntents.length; i++) {
5854                Intent intent = res.key.allIntents[i];
5855                if (intent.getPackage() != null && intent.getComponent() != null) {
5856                    return false;
5857                }
5858            }
5859            return true;
5860        } catch (ClassCastException e) {
5861        }
5862        return false;
5863    }
5864
5865    @Override
5866    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5867        if (!(pendingResult instanceof PendingIntentRecord)) {
5868            return false;
5869        }
5870        try {
5871            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5872            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5873                return true;
5874            }
5875            return false;
5876        } catch (ClassCastException e) {
5877        }
5878        return false;
5879    }
5880
5881    @Override
5882    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5883        if (!(pendingResult instanceof PendingIntentRecord)) {
5884            return null;
5885        }
5886        try {
5887            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5888            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5889        } catch (ClassCastException e) {
5890        }
5891        return null;
5892    }
5893
5894    @Override
5895    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5896        if (!(pendingResult instanceof PendingIntentRecord)) {
5897            return null;
5898        }
5899        try {
5900            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5901            Intent intent = res.key.requestIntent;
5902            if (intent != null) {
5903                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5904                        || res.lastTagPrefix.equals(prefix))) {
5905                    return res.lastTag;
5906                }
5907                res.lastTagPrefix = prefix;
5908                StringBuilder sb = new StringBuilder(128);
5909                if (prefix != null) {
5910                    sb.append(prefix);
5911                }
5912                if (intent.getAction() != null) {
5913                    sb.append(intent.getAction());
5914                } else if (intent.getComponent() != null) {
5915                    intent.getComponent().appendShortString(sb);
5916                } else {
5917                    sb.append("?");
5918                }
5919                return res.lastTag = sb.toString();
5920            }
5921        } catch (ClassCastException e) {
5922        }
5923        return null;
5924    }
5925
5926    @Override
5927    public void setProcessLimit(int max) {
5928        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5929                "setProcessLimit()");
5930        synchronized (this) {
5931            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5932            mProcessLimitOverride = max;
5933        }
5934        trimApplications();
5935    }
5936
5937    @Override
5938    public int getProcessLimit() {
5939        synchronized (this) {
5940            return mProcessLimitOverride;
5941        }
5942    }
5943
5944    void foregroundTokenDied(ForegroundToken token) {
5945        synchronized (ActivityManagerService.this) {
5946            synchronized (mPidsSelfLocked) {
5947                ForegroundToken cur
5948                    = mForegroundProcesses.get(token.pid);
5949                if (cur != token) {
5950                    return;
5951                }
5952                mForegroundProcesses.remove(token.pid);
5953                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5954                if (pr == null) {
5955                    return;
5956                }
5957                pr.forcingToForeground = null;
5958                updateProcessForegroundLocked(pr, false, false);
5959            }
5960            updateOomAdjLocked();
5961        }
5962    }
5963
5964    @Override
5965    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5966        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5967                "setProcessForeground()");
5968        synchronized(this) {
5969            boolean changed = false;
5970
5971            synchronized (mPidsSelfLocked) {
5972                ProcessRecord pr = mPidsSelfLocked.get(pid);
5973                if (pr == null && isForeground) {
5974                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5975                    return;
5976                }
5977                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5978                if (oldToken != null) {
5979                    oldToken.token.unlinkToDeath(oldToken, 0);
5980                    mForegroundProcesses.remove(pid);
5981                    if (pr != null) {
5982                        pr.forcingToForeground = null;
5983                    }
5984                    changed = true;
5985                }
5986                if (isForeground && token != null) {
5987                    ForegroundToken newToken = new ForegroundToken() {
5988                        @Override
5989                        public void binderDied() {
5990                            foregroundTokenDied(this);
5991                        }
5992                    };
5993                    newToken.pid = pid;
5994                    newToken.token = token;
5995                    try {
5996                        token.linkToDeath(newToken, 0);
5997                        mForegroundProcesses.put(pid, newToken);
5998                        pr.forcingToForeground = token;
5999                        changed = true;
6000                    } catch (RemoteException e) {
6001                        // If the process died while doing this, we will later
6002                        // do the cleanup with the process death link.
6003                    }
6004                }
6005            }
6006
6007            if (changed) {
6008                updateOomAdjLocked();
6009            }
6010        }
6011    }
6012
6013    // =========================================================
6014    // PERMISSIONS
6015    // =========================================================
6016
6017    static class PermissionController extends IPermissionController.Stub {
6018        ActivityManagerService mActivityManagerService;
6019        PermissionController(ActivityManagerService activityManagerService) {
6020            mActivityManagerService = activityManagerService;
6021        }
6022
6023        @Override
6024        public boolean checkPermission(String permission, int pid, int uid) {
6025            return mActivityManagerService.checkPermission(permission, pid,
6026                    uid) == PackageManager.PERMISSION_GRANTED;
6027        }
6028    }
6029
6030    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6031        @Override
6032        public int checkComponentPermission(String permission, int pid, int uid,
6033                int owningUid, boolean exported) {
6034            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6035                    owningUid, exported);
6036        }
6037
6038        @Override
6039        public Object getAMSLock() {
6040            return ActivityManagerService.this;
6041        }
6042    }
6043
6044    /**
6045     * This can be called with or without the global lock held.
6046     */
6047    int checkComponentPermission(String permission, int pid, int uid,
6048            int owningUid, boolean exported) {
6049        // We might be performing an operation on behalf of an indirect binder
6050        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6051        // client identity accordingly before proceeding.
6052        Identity tlsIdentity = sCallerIdentity.get();
6053        if (tlsIdentity != null) {
6054            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6055                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6056            uid = tlsIdentity.uid;
6057            pid = tlsIdentity.pid;
6058        }
6059
6060        if (pid == MY_PID) {
6061            return PackageManager.PERMISSION_GRANTED;
6062        }
6063
6064        return ActivityManager.checkComponentPermission(permission, uid,
6065                owningUid, exported);
6066    }
6067
6068    /**
6069     * As the only public entry point for permissions checking, this method
6070     * can enforce the semantic that requesting a check on a null global
6071     * permission is automatically denied.  (Internally a null permission
6072     * string is used when calling {@link #checkComponentPermission} in cases
6073     * when only uid-based security is needed.)
6074     *
6075     * This can be called with or without the global lock held.
6076     */
6077    @Override
6078    public int checkPermission(String permission, int pid, int uid) {
6079        if (permission == null) {
6080            return PackageManager.PERMISSION_DENIED;
6081        }
6082        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6083    }
6084
6085    /**
6086     * Binder IPC calls go through the public entry point.
6087     * This can be called with or without the global lock held.
6088     */
6089    int checkCallingPermission(String permission) {
6090        return checkPermission(permission,
6091                Binder.getCallingPid(),
6092                UserHandle.getAppId(Binder.getCallingUid()));
6093    }
6094
6095    /**
6096     * This can be called with or without the global lock held.
6097     */
6098    void enforceCallingPermission(String permission, String func) {
6099        if (checkCallingPermission(permission)
6100                == PackageManager.PERMISSION_GRANTED) {
6101            return;
6102        }
6103
6104        String msg = "Permission Denial: " + func + " from pid="
6105                + Binder.getCallingPid()
6106                + ", uid=" + Binder.getCallingUid()
6107                + " requires " + permission;
6108        Slog.w(TAG, msg);
6109        throw new SecurityException(msg);
6110    }
6111
6112    /**
6113     * Determine if UID is holding permissions required to access {@link Uri} in
6114     * the given {@link ProviderInfo}. Final permission checking is always done
6115     * in {@link ContentProvider}.
6116     */
6117    private final boolean checkHoldingPermissionsLocked(
6118            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6119        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6120                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6121        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6122            return false;
6123        }
6124        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6125    }
6126
6127    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6128            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6129        if (pi.applicationInfo.uid == uid) {
6130            return true;
6131        } else if (!pi.exported) {
6132            return false;
6133        }
6134
6135        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6136        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6137        try {
6138            // check if target holds top-level <provider> permissions
6139            if (!readMet && pi.readPermission != null && considerUidPermissions
6140                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6141                readMet = true;
6142            }
6143            if (!writeMet && pi.writePermission != null && considerUidPermissions
6144                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6145                writeMet = true;
6146            }
6147
6148            // track if unprotected read/write is allowed; any denied
6149            // <path-permission> below removes this ability
6150            boolean allowDefaultRead = pi.readPermission == null;
6151            boolean allowDefaultWrite = pi.writePermission == null;
6152
6153            // check if target holds any <path-permission> that match uri
6154            final PathPermission[] pps = pi.pathPermissions;
6155            if (pps != null) {
6156                final String path = grantUri.uri.getPath();
6157                int i = pps.length;
6158                while (i > 0 && (!readMet || !writeMet)) {
6159                    i--;
6160                    PathPermission pp = pps[i];
6161                    if (pp.match(path)) {
6162                        if (!readMet) {
6163                            final String pprperm = pp.getReadPermission();
6164                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6165                                    + pprperm + " for " + pp.getPath()
6166                                    + ": match=" + pp.match(path)
6167                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6168                            if (pprperm != null) {
6169                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6170                                        == PERMISSION_GRANTED) {
6171                                    readMet = true;
6172                                } else {
6173                                    allowDefaultRead = false;
6174                                }
6175                            }
6176                        }
6177                        if (!writeMet) {
6178                            final String ppwperm = pp.getWritePermission();
6179                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6180                                    + ppwperm + " for " + pp.getPath()
6181                                    + ": match=" + pp.match(path)
6182                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6183                            if (ppwperm != null) {
6184                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6185                                        == PERMISSION_GRANTED) {
6186                                    writeMet = true;
6187                                } else {
6188                                    allowDefaultWrite = false;
6189                                }
6190                            }
6191                        }
6192                    }
6193                }
6194            }
6195
6196            // grant unprotected <provider> read/write, if not blocked by
6197            // <path-permission> above
6198            if (allowDefaultRead) readMet = true;
6199            if (allowDefaultWrite) writeMet = true;
6200
6201        } catch (RemoteException e) {
6202            return false;
6203        }
6204
6205        return readMet && writeMet;
6206    }
6207
6208    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6209        ProviderInfo pi = null;
6210        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6211        if (cpr != null) {
6212            pi = cpr.info;
6213        } else {
6214            try {
6215                pi = AppGlobals.getPackageManager().resolveContentProvider(
6216                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6217            } catch (RemoteException ex) {
6218            }
6219        }
6220        return pi;
6221    }
6222
6223    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6224        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6225        if (targetUris != null) {
6226            return targetUris.get(grantUri);
6227        }
6228        return null;
6229    }
6230
6231    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6232            String targetPkg, int targetUid, GrantUri grantUri) {
6233        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6234        if (targetUris == null) {
6235            targetUris = Maps.newArrayMap();
6236            mGrantedUriPermissions.put(targetUid, targetUris);
6237        }
6238
6239        UriPermission perm = targetUris.get(grantUri);
6240        if (perm == null) {
6241            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6242            targetUris.put(grantUri, perm);
6243        }
6244
6245        return perm;
6246    }
6247
6248    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6249            final int modeFlags) {
6250        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6251        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6252                : UriPermission.STRENGTH_OWNED;
6253
6254        // Root gets to do everything.
6255        if (uid == 0) {
6256            return true;
6257        }
6258
6259        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6260        if (perms == null) return false;
6261
6262        // First look for exact match
6263        final UriPermission exactPerm = perms.get(grantUri);
6264        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6265            return true;
6266        }
6267
6268        // No exact match, look for prefixes
6269        final int N = perms.size();
6270        for (int i = 0; i < N; i++) {
6271            final UriPermission perm = perms.valueAt(i);
6272            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6273                    && perm.getStrength(modeFlags) >= minStrength) {
6274                return true;
6275            }
6276        }
6277
6278        return false;
6279    }
6280
6281    @Override
6282    public int checkUriPermission(Uri uri, int pid, int uid,
6283            final int modeFlags, int userId) {
6284        enforceNotIsolatedCaller("checkUriPermission");
6285
6286        // Another redirected-binder-call permissions check as in
6287        // {@link checkComponentPermission}.
6288        Identity tlsIdentity = sCallerIdentity.get();
6289        if (tlsIdentity != null) {
6290            uid = tlsIdentity.uid;
6291            pid = tlsIdentity.pid;
6292        }
6293
6294        // Our own process gets to do everything.
6295        if (pid == MY_PID) {
6296            return PackageManager.PERMISSION_GRANTED;
6297        }
6298        synchronized (this) {
6299            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6300                    ? PackageManager.PERMISSION_GRANTED
6301                    : PackageManager.PERMISSION_DENIED;
6302        }
6303    }
6304
6305    /**
6306     * Check if the targetPkg can be granted permission to access uri by
6307     * the callingUid using the given modeFlags.  Throws a security exception
6308     * if callingUid is not allowed to do this.  Returns the uid of the target
6309     * if the URI permission grant should be performed; returns -1 if it is not
6310     * needed (for example targetPkg already has permission to access the URI).
6311     * If you already know the uid of the target, you can supply it in
6312     * lastTargetUid else set that to -1.
6313     */
6314    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6315            final int modeFlags, int lastTargetUid) {
6316        if (!Intent.isAccessUriMode(modeFlags)) {
6317            return -1;
6318        }
6319
6320        if (targetPkg != null) {
6321            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6322                    "Checking grant " + targetPkg + " permission to " + grantUri);
6323        }
6324
6325        final IPackageManager pm = AppGlobals.getPackageManager();
6326
6327        // If this is not a content: uri, we can't do anything with it.
6328        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6329            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6330                    "Can't grant URI permission for non-content URI: " + grantUri);
6331            return -1;
6332        }
6333
6334        final String authority = grantUri.uri.getAuthority();
6335        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6336        if (pi == null) {
6337            Slog.w(TAG, "No content provider found for permission check: " +
6338                    grantUri.uri.toSafeString());
6339            return -1;
6340        }
6341
6342        int targetUid = lastTargetUid;
6343        if (targetUid < 0 && targetPkg != null) {
6344            try {
6345                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6346                if (targetUid < 0) {
6347                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6348                            "Can't grant URI permission no uid for: " + targetPkg);
6349                    return -1;
6350                }
6351            } catch (RemoteException ex) {
6352                return -1;
6353            }
6354        }
6355
6356        if (targetUid >= 0) {
6357            // First...  does the target actually need this permission?
6358            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6359                // No need to grant the target this permission.
6360                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6361                        "Target " + targetPkg + " already has full permission to " + grantUri);
6362                return -1;
6363            }
6364        } else {
6365            // First...  there is no target package, so can anyone access it?
6366            boolean allowed = pi.exported;
6367            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6368                if (pi.readPermission != null) {
6369                    allowed = false;
6370                }
6371            }
6372            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6373                if (pi.writePermission != null) {
6374                    allowed = false;
6375                }
6376            }
6377            if (allowed) {
6378                return -1;
6379            }
6380        }
6381
6382        /* There is a special cross user grant if:
6383         * - The target is on another user.
6384         * - Apps on the current user can access the uri without any uid permissions.
6385         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6386         * grant uri permissions.
6387         */
6388        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6389                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6390                modeFlags, false /*without considering the uid permissions*/);
6391
6392        // Second...  is the provider allowing granting of URI permissions?
6393        if (!specialCrossUserGrant) {
6394            if (!pi.grantUriPermissions) {
6395                throw new SecurityException("Provider " + pi.packageName
6396                        + "/" + pi.name
6397                        + " does not allow granting of Uri permissions (uri "
6398                        + grantUri + ")");
6399            }
6400            if (pi.uriPermissionPatterns != null) {
6401                final int N = pi.uriPermissionPatterns.length;
6402                boolean allowed = false;
6403                for (int i=0; i<N; i++) {
6404                    if (pi.uriPermissionPatterns[i] != null
6405                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6406                        allowed = true;
6407                        break;
6408                    }
6409                }
6410                if (!allowed) {
6411                    throw new SecurityException("Provider " + pi.packageName
6412                            + "/" + pi.name
6413                            + " does not allow granting of permission to path of Uri "
6414                            + grantUri);
6415                }
6416            }
6417        }
6418
6419        // Third...  does the caller itself have permission to access
6420        // this uri?
6421        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6422            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6423                // Require they hold a strong enough Uri permission
6424                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6425                    throw new SecurityException("Uid " + callingUid
6426                            + " does not have permission to uri " + grantUri);
6427                }
6428            }
6429        }
6430        return targetUid;
6431    }
6432
6433    @Override
6434    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6435            final int modeFlags, int userId) {
6436        enforceNotIsolatedCaller("checkGrantUriPermission");
6437        synchronized(this) {
6438            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6439                    new GrantUri(userId, uri, false), modeFlags, -1);
6440        }
6441    }
6442
6443    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6444            final int modeFlags, UriPermissionOwner owner) {
6445        if (!Intent.isAccessUriMode(modeFlags)) {
6446            return;
6447        }
6448
6449        // So here we are: the caller has the assumed permission
6450        // to the uri, and the target doesn't.  Let's now give this to
6451        // the target.
6452
6453        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6454                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6455
6456        final String authority = grantUri.uri.getAuthority();
6457        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6458        if (pi == null) {
6459            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6460            return;
6461        }
6462
6463        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6464            grantUri.prefix = true;
6465        }
6466        final UriPermission perm = findOrCreateUriPermissionLocked(
6467                pi.packageName, targetPkg, targetUid, grantUri);
6468        perm.grantModes(modeFlags, owner);
6469    }
6470
6471    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6472            final int modeFlags, UriPermissionOwner owner) {
6473        if (targetPkg == null) {
6474            throw new NullPointerException("targetPkg");
6475        }
6476
6477        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6478                -1);
6479        if (targetUid < 0) {
6480            return;
6481        }
6482
6483        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6484                owner);
6485    }
6486
6487    static class NeededUriGrants extends ArrayList<GrantUri> {
6488        final String targetPkg;
6489        final int targetUid;
6490        final int flags;
6491
6492        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6493            this.targetPkg = targetPkg;
6494            this.targetUid = targetUid;
6495            this.flags = flags;
6496        }
6497    }
6498
6499    /**
6500     * Like checkGrantUriPermissionLocked, but takes an Intent.
6501     */
6502    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6503            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6504        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6505                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6506                + " clip=" + (intent != null ? intent.getClipData() : null)
6507                + " from " + intent + "; flags=0x"
6508                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6509
6510        if (targetPkg == null) {
6511            throw new NullPointerException("targetPkg");
6512        }
6513
6514        if (intent == null) {
6515            return null;
6516        }
6517        Uri data = intent.getData();
6518        ClipData clip = intent.getClipData();
6519        if (data == null && clip == null) {
6520            return null;
6521        }
6522        final IPackageManager pm = AppGlobals.getPackageManager();
6523        int targetUid;
6524        if (needed != null) {
6525            targetUid = needed.targetUid;
6526        } else {
6527            try {
6528                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6529            } catch (RemoteException ex) {
6530                return null;
6531            }
6532            if (targetUid < 0) {
6533                if (DEBUG_URI_PERMISSION) {
6534                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6535                            + " on user " + targetUserId);
6536                }
6537                return null;
6538            }
6539        }
6540        if (data != null) {
6541            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6542            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6543                    targetUid);
6544            if (targetUid > 0) {
6545                if (needed == null) {
6546                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6547                }
6548                needed.add(grantUri);
6549            }
6550        }
6551        if (clip != null) {
6552            for (int i=0; i<clip.getItemCount(); i++) {
6553                Uri uri = clip.getItemAt(i).getUri();
6554                if (uri != null) {
6555                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6556                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6557                            targetUid);
6558                    if (targetUid > 0) {
6559                        if (needed == null) {
6560                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6561                        }
6562                        needed.add(grantUri);
6563                    }
6564                } else {
6565                    Intent clipIntent = clip.getItemAt(i).getIntent();
6566                    if (clipIntent != null) {
6567                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6568                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6569                        if (newNeeded != null) {
6570                            needed = newNeeded;
6571                        }
6572                    }
6573                }
6574            }
6575        }
6576
6577        return needed;
6578    }
6579
6580    /**
6581     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6582     */
6583    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6584            UriPermissionOwner owner) {
6585        if (needed != null) {
6586            for (int i=0; i<needed.size(); i++) {
6587                GrantUri grantUri = needed.get(i);
6588                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6589                        grantUri, needed.flags, owner);
6590            }
6591        }
6592    }
6593
6594    void grantUriPermissionFromIntentLocked(int callingUid,
6595            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6596        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6597                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6598        if (needed == null) {
6599            return;
6600        }
6601
6602        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6603    }
6604
6605    @Override
6606    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6607            final int modeFlags, int userId) {
6608        enforceNotIsolatedCaller("grantUriPermission");
6609        GrantUri grantUri = new GrantUri(userId, uri, false);
6610        synchronized(this) {
6611            final ProcessRecord r = getRecordForAppLocked(caller);
6612            if (r == null) {
6613                throw new SecurityException("Unable to find app for caller "
6614                        + caller
6615                        + " when granting permission to uri " + grantUri);
6616            }
6617            if (targetPkg == null) {
6618                throw new IllegalArgumentException("null target");
6619            }
6620            if (grantUri == null) {
6621                throw new IllegalArgumentException("null uri");
6622            }
6623
6624            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6625                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6626                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6627                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6628
6629            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6630        }
6631    }
6632
6633    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6634        if (perm.modeFlags == 0) {
6635            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6636                    perm.targetUid);
6637            if (perms != null) {
6638                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6639                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6640
6641                perms.remove(perm.uri);
6642                if (perms.isEmpty()) {
6643                    mGrantedUriPermissions.remove(perm.targetUid);
6644                }
6645            }
6646        }
6647    }
6648
6649    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6650        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6651
6652        final IPackageManager pm = AppGlobals.getPackageManager();
6653        final String authority = grantUri.uri.getAuthority();
6654        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6655        if (pi == null) {
6656            Slog.w(TAG, "No content provider found for permission revoke: "
6657                    + grantUri.toSafeString());
6658            return;
6659        }
6660
6661        // Does the caller have this permission on the URI?
6662        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6663            // Right now, if you are not the original owner of the permission,
6664            // you are not allowed to revoke it.
6665            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6666                throw new SecurityException("Uid " + callingUid
6667                        + " does not have permission to uri " + grantUri);
6668            //}
6669        }
6670
6671        boolean persistChanged = false;
6672
6673        // Go through all of the permissions and remove any that match.
6674        int N = mGrantedUriPermissions.size();
6675        for (int i = 0; i < N; i++) {
6676            final int targetUid = mGrantedUriPermissions.keyAt(i);
6677            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6678
6679            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6680                final UriPermission perm = it.next();
6681                if (perm.uri.sourceUserId == grantUri.sourceUserId
6682                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6683                    if (DEBUG_URI_PERMISSION)
6684                        Slog.v(TAG,
6685                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6686                    persistChanged |= perm.revokeModes(
6687                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6688                    if (perm.modeFlags == 0) {
6689                        it.remove();
6690                    }
6691                }
6692            }
6693
6694            if (perms.isEmpty()) {
6695                mGrantedUriPermissions.remove(targetUid);
6696                N--;
6697                i--;
6698            }
6699        }
6700
6701        if (persistChanged) {
6702            schedulePersistUriGrants();
6703        }
6704    }
6705
6706    @Override
6707    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6708            int userId) {
6709        enforceNotIsolatedCaller("revokeUriPermission");
6710        synchronized(this) {
6711            final ProcessRecord r = getRecordForAppLocked(caller);
6712            if (r == null) {
6713                throw new SecurityException("Unable to find app for caller "
6714                        + caller
6715                        + " when revoking permission to uri " + uri);
6716            }
6717            if (uri == null) {
6718                Slog.w(TAG, "revokeUriPermission: null uri");
6719                return;
6720            }
6721
6722            if (!Intent.isAccessUriMode(modeFlags)) {
6723                return;
6724            }
6725
6726            final IPackageManager pm = AppGlobals.getPackageManager();
6727            final String authority = uri.getAuthority();
6728            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6729            if (pi == null) {
6730                Slog.w(TAG, "No content provider found for permission revoke: "
6731                        + uri.toSafeString());
6732                return;
6733            }
6734
6735            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6736        }
6737    }
6738
6739    /**
6740     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6741     * given package.
6742     *
6743     * @param packageName Package name to match, or {@code null} to apply to all
6744     *            packages.
6745     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6746     *            to all users.
6747     * @param persistable If persistable grants should be removed.
6748     */
6749    private void removeUriPermissionsForPackageLocked(
6750            String packageName, int userHandle, boolean persistable) {
6751        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6752            throw new IllegalArgumentException("Must narrow by either package or user");
6753        }
6754
6755        boolean persistChanged = false;
6756
6757        int N = mGrantedUriPermissions.size();
6758        for (int i = 0; i < N; i++) {
6759            final int targetUid = mGrantedUriPermissions.keyAt(i);
6760            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6761
6762            // Only inspect grants matching user
6763            if (userHandle == UserHandle.USER_ALL
6764                    || userHandle == UserHandle.getUserId(targetUid)) {
6765                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6766                    final UriPermission perm = it.next();
6767
6768                    // Only inspect grants matching package
6769                    if (packageName == null || perm.sourcePkg.equals(packageName)
6770                            || perm.targetPkg.equals(packageName)) {
6771                        persistChanged |= perm.revokeModes(
6772                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6773
6774                        // Only remove when no modes remain; any persisted grants
6775                        // will keep this alive.
6776                        if (perm.modeFlags == 0) {
6777                            it.remove();
6778                        }
6779                    }
6780                }
6781
6782                if (perms.isEmpty()) {
6783                    mGrantedUriPermissions.remove(targetUid);
6784                    N--;
6785                    i--;
6786                }
6787            }
6788        }
6789
6790        if (persistChanged) {
6791            schedulePersistUriGrants();
6792        }
6793    }
6794
6795    @Override
6796    public IBinder newUriPermissionOwner(String name) {
6797        enforceNotIsolatedCaller("newUriPermissionOwner");
6798        synchronized(this) {
6799            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6800            return owner.getExternalTokenLocked();
6801        }
6802    }
6803
6804    @Override
6805    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6806            final int modeFlags, int userId) {
6807        synchronized(this) {
6808            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6809            if (owner == null) {
6810                throw new IllegalArgumentException("Unknown owner: " + token);
6811            }
6812            if (fromUid != Binder.getCallingUid()) {
6813                if (Binder.getCallingUid() != Process.myUid()) {
6814                    // Only system code can grant URI permissions on behalf
6815                    // of other users.
6816                    throw new SecurityException("nice try");
6817                }
6818            }
6819            if (targetPkg == null) {
6820                throw new IllegalArgumentException("null target");
6821            }
6822            if (uri == null) {
6823                throw new IllegalArgumentException("null uri");
6824            }
6825
6826            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6827                    modeFlags, owner);
6828        }
6829    }
6830
6831    @Override
6832    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6833        synchronized(this) {
6834            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6835            if (owner == null) {
6836                throw new IllegalArgumentException("Unknown owner: " + token);
6837            }
6838
6839            if (uri == null) {
6840                owner.removeUriPermissionsLocked(mode);
6841            } else {
6842                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6843            }
6844        }
6845    }
6846
6847    private void schedulePersistUriGrants() {
6848        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6849            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6850                    10 * DateUtils.SECOND_IN_MILLIS);
6851        }
6852    }
6853
6854    private void writeGrantedUriPermissions() {
6855        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6856
6857        // Snapshot permissions so we can persist without lock
6858        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6859        synchronized (this) {
6860            final int size = mGrantedUriPermissions.size();
6861            for (int i = 0; i < size; i++) {
6862                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6863                for (UriPermission perm : perms.values()) {
6864                    if (perm.persistedModeFlags != 0) {
6865                        persist.add(perm.snapshot());
6866                    }
6867                }
6868            }
6869        }
6870
6871        FileOutputStream fos = null;
6872        try {
6873            fos = mGrantFile.startWrite();
6874
6875            XmlSerializer out = new FastXmlSerializer();
6876            out.setOutput(fos, "utf-8");
6877            out.startDocument(null, true);
6878            out.startTag(null, TAG_URI_GRANTS);
6879            for (UriPermission.Snapshot perm : persist) {
6880                out.startTag(null, TAG_URI_GRANT);
6881                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6882                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6883                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6884                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6885                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6886                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6887                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6888                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6889                out.endTag(null, TAG_URI_GRANT);
6890            }
6891            out.endTag(null, TAG_URI_GRANTS);
6892            out.endDocument();
6893
6894            mGrantFile.finishWrite(fos);
6895        } catch (IOException e) {
6896            if (fos != null) {
6897                mGrantFile.failWrite(fos);
6898            }
6899        }
6900    }
6901
6902    private void readGrantedUriPermissionsLocked() {
6903        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6904
6905        final long now = System.currentTimeMillis();
6906
6907        FileInputStream fis = null;
6908        try {
6909            fis = mGrantFile.openRead();
6910            final XmlPullParser in = Xml.newPullParser();
6911            in.setInput(fis, null);
6912
6913            int type;
6914            while ((type = in.next()) != END_DOCUMENT) {
6915                final String tag = in.getName();
6916                if (type == START_TAG) {
6917                    if (TAG_URI_GRANT.equals(tag)) {
6918                        final int sourceUserId;
6919                        final int targetUserId;
6920                        final int userHandle = readIntAttribute(in,
6921                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6922                        if (userHandle != UserHandle.USER_NULL) {
6923                            // For backwards compatibility.
6924                            sourceUserId = userHandle;
6925                            targetUserId = userHandle;
6926                        } else {
6927                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6928                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6929                        }
6930                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6931                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6932                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6933                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6934                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6935                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6936
6937                        // Sanity check that provider still belongs to source package
6938                        final ProviderInfo pi = getProviderInfoLocked(
6939                                uri.getAuthority(), sourceUserId);
6940                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6941                            int targetUid = -1;
6942                            try {
6943                                targetUid = AppGlobals.getPackageManager()
6944                                        .getPackageUid(targetPkg, targetUserId);
6945                            } catch (RemoteException e) {
6946                            }
6947                            if (targetUid != -1) {
6948                                final UriPermission perm = findOrCreateUriPermissionLocked(
6949                                        sourcePkg, targetPkg, targetUid,
6950                                        new GrantUri(sourceUserId, uri, prefix));
6951                                perm.initPersistedModes(modeFlags, createdTime);
6952                            }
6953                        } else {
6954                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6955                                    + " but instead found " + pi);
6956                        }
6957                    }
6958                }
6959            }
6960        } catch (FileNotFoundException e) {
6961            // Missing grants is okay
6962        } catch (IOException e) {
6963            Log.wtf(TAG, "Failed reading Uri grants", e);
6964        } catch (XmlPullParserException e) {
6965            Log.wtf(TAG, "Failed reading Uri grants", e);
6966        } finally {
6967            IoUtils.closeQuietly(fis);
6968        }
6969    }
6970
6971    @Override
6972    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6973        enforceNotIsolatedCaller("takePersistableUriPermission");
6974
6975        Preconditions.checkFlagsArgument(modeFlags,
6976                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6977
6978        synchronized (this) {
6979            final int callingUid = Binder.getCallingUid();
6980            boolean persistChanged = false;
6981            GrantUri grantUri = new GrantUri(userId, uri, false);
6982
6983            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6984                    new GrantUri(userId, uri, false));
6985            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6986                    new GrantUri(userId, uri, true));
6987
6988            final boolean exactValid = (exactPerm != null)
6989                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6990            final boolean prefixValid = (prefixPerm != null)
6991                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6992
6993            if (!(exactValid || prefixValid)) {
6994                throw new SecurityException("No persistable permission grants found for UID "
6995                        + callingUid + " and Uri " + grantUri.toSafeString());
6996            }
6997
6998            if (exactValid) {
6999                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7000            }
7001            if (prefixValid) {
7002                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7003            }
7004
7005            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7006
7007            if (persistChanged) {
7008                schedulePersistUriGrants();
7009            }
7010        }
7011    }
7012
7013    @Override
7014    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7015        enforceNotIsolatedCaller("releasePersistableUriPermission");
7016
7017        Preconditions.checkFlagsArgument(modeFlags,
7018                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7019
7020        synchronized (this) {
7021            final int callingUid = Binder.getCallingUid();
7022            boolean persistChanged = false;
7023
7024            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7025                    new GrantUri(userId, uri, false));
7026            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7027                    new GrantUri(userId, uri, true));
7028            if (exactPerm == null && prefixPerm == null) {
7029                throw new SecurityException("No permission grants found for UID " + callingUid
7030                        + " and Uri " + uri.toSafeString());
7031            }
7032
7033            if (exactPerm != null) {
7034                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7035                removeUriPermissionIfNeededLocked(exactPerm);
7036            }
7037            if (prefixPerm != null) {
7038                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7039                removeUriPermissionIfNeededLocked(prefixPerm);
7040            }
7041
7042            if (persistChanged) {
7043                schedulePersistUriGrants();
7044            }
7045        }
7046    }
7047
7048    /**
7049     * Prune any older {@link UriPermission} for the given UID until outstanding
7050     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7051     *
7052     * @return if any mutations occured that require persisting.
7053     */
7054    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7055        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7056        if (perms == null) return false;
7057        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7058
7059        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7060        for (UriPermission perm : perms.values()) {
7061            if (perm.persistedModeFlags != 0) {
7062                persisted.add(perm);
7063            }
7064        }
7065
7066        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7067        if (trimCount <= 0) return false;
7068
7069        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7070        for (int i = 0; i < trimCount; i++) {
7071            final UriPermission perm = persisted.get(i);
7072
7073            if (DEBUG_URI_PERMISSION) {
7074                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7075            }
7076
7077            perm.releasePersistableModes(~0);
7078            removeUriPermissionIfNeededLocked(perm);
7079        }
7080
7081        return true;
7082    }
7083
7084    @Override
7085    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7086            String packageName, boolean incoming) {
7087        enforceNotIsolatedCaller("getPersistedUriPermissions");
7088        Preconditions.checkNotNull(packageName, "packageName");
7089
7090        final int callingUid = Binder.getCallingUid();
7091        final IPackageManager pm = AppGlobals.getPackageManager();
7092        try {
7093            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7094            if (packageUid != callingUid) {
7095                throw new SecurityException(
7096                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7097            }
7098        } catch (RemoteException e) {
7099            throw new SecurityException("Failed to verify package name ownership");
7100        }
7101
7102        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7103        synchronized (this) {
7104            if (incoming) {
7105                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7106                        callingUid);
7107                if (perms == null) {
7108                    Slog.w(TAG, "No permission grants found for " + packageName);
7109                } else {
7110                    for (UriPermission perm : perms.values()) {
7111                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7112                            result.add(perm.buildPersistedPublicApiObject());
7113                        }
7114                    }
7115                }
7116            } else {
7117                final int size = mGrantedUriPermissions.size();
7118                for (int i = 0; i < size; i++) {
7119                    final ArrayMap<GrantUri, UriPermission> perms =
7120                            mGrantedUriPermissions.valueAt(i);
7121                    for (UriPermission perm : perms.values()) {
7122                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7123                            result.add(perm.buildPersistedPublicApiObject());
7124                        }
7125                    }
7126                }
7127            }
7128        }
7129        return new ParceledListSlice<android.content.UriPermission>(result);
7130    }
7131
7132    @Override
7133    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7134        synchronized (this) {
7135            ProcessRecord app =
7136                who != null ? getRecordForAppLocked(who) : null;
7137            if (app == null) return;
7138
7139            Message msg = Message.obtain();
7140            msg.what = WAIT_FOR_DEBUGGER_MSG;
7141            msg.obj = app;
7142            msg.arg1 = waiting ? 1 : 0;
7143            mHandler.sendMessage(msg);
7144        }
7145    }
7146
7147    @Override
7148    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7149        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7150        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7151        outInfo.availMem = Process.getFreeMemory();
7152        outInfo.totalMem = Process.getTotalMemory();
7153        outInfo.threshold = homeAppMem;
7154        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7155        outInfo.hiddenAppThreshold = cachedAppMem;
7156        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7157                ProcessList.SERVICE_ADJ);
7158        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7159                ProcessList.VISIBLE_APP_ADJ);
7160        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7161                ProcessList.FOREGROUND_APP_ADJ);
7162    }
7163
7164    // =========================================================
7165    // TASK MANAGEMENT
7166    // =========================================================
7167
7168    @Override
7169    public List<IAppTask> getAppTasks() {
7170        int callingUid = Binder.getCallingUid();
7171        long ident = Binder.clearCallingIdentity();
7172        synchronized(this) {
7173            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7174            try {
7175                if (localLOGV) Slog.v(TAG, "getAppTasks");
7176
7177                final int N = mRecentTasks.size();
7178                for (int i = 0; i < N; i++) {
7179                    TaskRecord tr = mRecentTasks.get(i);
7180                    // Skip tasks that are not created by the caller
7181                    if (tr.creatorUid == callingUid) {
7182                        ActivityManager.RecentTaskInfo taskInfo =
7183                                createRecentTaskInfoFromTaskRecord(tr);
7184                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7185                        list.add(taskImpl);
7186                    }
7187                }
7188            } finally {
7189                Binder.restoreCallingIdentity(ident);
7190            }
7191            return list;
7192        }
7193    }
7194
7195    @Override
7196    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7197        final int callingUid = Binder.getCallingUid();
7198        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7199
7200        synchronized(this) {
7201            if (localLOGV) Slog.v(
7202                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7203
7204            final boolean allowed = checkCallingPermission(
7205                    android.Manifest.permission.GET_TASKS)
7206                    == PackageManager.PERMISSION_GRANTED;
7207            if (!allowed) {
7208                Slog.w(TAG, "getTasks: caller " + callingUid
7209                        + " does not hold GET_TASKS; limiting output");
7210            }
7211
7212            // TODO: Improve with MRU list from all ActivityStacks.
7213            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7214        }
7215
7216        return list;
7217    }
7218
7219    TaskRecord getMostRecentTask() {
7220        return mRecentTasks.get(0);
7221    }
7222
7223    /**
7224     * Creates a new RecentTaskInfo from a TaskRecord.
7225     */
7226    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7227        // Update the task description to reflect any changes in the task stack
7228        tr.updateTaskDescription();
7229
7230        // Compose the recent task info
7231        ActivityManager.RecentTaskInfo rti
7232                = new ActivityManager.RecentTaskInfo();
7233        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7234        rti.persistentId = tr.taskId;
7235        rti.baseIntent = new Intent(tr.getBaseIntent());
7236        rti.origActivity = tr.origActivity;
7237        rti.description = tr.lastDescription;
7238        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7239        rti.userId = tr.userId;
7240        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7241        return rti;
7242    }
7243
7244    @Override
7245    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7246            int flags, int userId) {
7247        final int callingUid = Binder.getCallingUid();
7248        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7249                false, true, "getRecentTasks", null);
7250
7251        synchronized (this) {
7252            final boolean allowed = checkCallingPermission(
7253                    android.Manifest.permission.GET_TASKS)
7254                    == PackageManager.PERMISSION_GRANTED;
7255            if (!allowed) {
7256                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7257                        + " does not hold GET_TASKS; limiting output");
7258            }
7259            final boolean detailed = checkCallingPermission(
7260                    android.Manifest.permission.GET_DETAILED_TASKS)
7261                    == PackageManager.PERMISSION_GRANTED;
7262
7263            IPackageManager pm = AppGlobals.getPackageManager();
7264
7265            final int N = mRecentTasks.size();
7266            ArrayList<ActivityManager.RecentTaskInfo> res
7267                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7268                            maxNum < N ? maxNum : N);
7269
7270            final Set<Integer> includedUsers;
7271            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7272                includedUsers = getProfileIdsLocked(userId);
7273            } else {
7274                includedUsers = new HashSet<Integer>();
7275            }
7276            includedUsers.add(Integer.valueOf(userId));
7277            for (int i=0; i<N && maxNum > 0; i++) {
7278                TaskRecord tr = mRecentTasks.get(i);
7279                // Only add calling user or related users recent tasks
7280                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7281
7282                // Return the entry if desired by the caller.  We always return
7283                // the first entry, because callers always expect this to be the
7284                // foreground app.  We may filter others if the caller has
7285                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7286                // we should exclude the entry.
7287
7288                if (i == 0
7289                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7290                        || (tr.intent == null)
7291                        || ((tr.intent.getFlags()
7292                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7293                    if (!allowed) {
7294                        // If the caller doesn't have the GET_TASKS permission, then only
7295                        // allow them to see a small subset of tasks -- their own and home.
7296                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7297                            continue;
7298                        }
7299                    }
7300                    if (tr.intent != null &&
7301                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7302                            != 0 && tr.getTopActivity() == null) {
7303                        // Don't include auto remove tasks that are finished or finishing.
7304                        continue;
7305                    }
7306
7307                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7308                    if (!detailed) {
7309                        rti.baseIntent.replaceExtras((Bundle)null);
7310                    }
7311
7312                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7313                        // Check whether this activity is currently available.
7314                        try {
7315                            if (rti.origActivity != null) {
7316                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7317                                        == null) {
7318                                    continue;
7319                                }
7320                            } else if (rti.baseIntent != null) {
7321                                if (pm.queryIntentActivities(rti.baseIntent,
7322                                        null, 0, userId) == null) {
7323                                    continue;
7324                                }
7325                            }
7326                        } catch (RemoteException e) {
7327                            // Will never happen.
7328                        }
7329                    }
7330
7331                    res.add(rti);
7332                    maxNum--;
7333                }
7334            }
7335            return res;
7336        }
7337    }
7338
7339    private TaskRecord recentTaskForIdLocked(int id) {
7340        final int N = mRecentTasks.size();
7341            for (int i=0; i<N; i++) {
7342                TaskRecord tr = mRecentTasks.get(i);
7343                if (tr.taskId == id) {
7344                    return tr;
7345                }
7346            }
7347            return null;
7348    }
7349
7350    @Override
7351    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7352        synchronized (this) {
7353            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7354                    "getTaskThumbnails()");
7355            TaskRecord tr = recentTaskForIdLocked(id);
7356            if (tr != null) {
7357                return tr.getTaskThumbnailsLocked();
7358            }
7359        }
7360        return null;
7361    }
7362
7363    @Override
7364    public Bitmap getTaskTopThumbnail(int id) {
7365        synchronized (this) {
7366            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7367                    "getTaskTopThumbnail()");
7368            TaskRecord tr = recentTaskForIdLocked(id);
7369            if (tr != null) {
7370                return tr.getTaskTopThumbnailLocked();
7371            }
7372        }
7373        return null;
7374    }
7375
7376    @Override
7377    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7378        synchronized (this) {
7379            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7380            if (r != null) {
7381                r.taskDescription = td;
7382                r.task.updateTaskDescription();
7383            }
7384        }
7385    }
7386
7387    @Override
7388    public boolean removeSubTask(int taskId, int subTaskIndex) {
7389        synchronized (this) {
7390            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7391                    "removeSubTask()");
7392            long ident = Binder.clearCallingIdentity();
7393            try {
7394                TaskRecord tr = recentTaskForIdLocked(taskId);
7395                if (tr != null) {
7396                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7397                }
7398                return false;
7399            } finally {
7400                Binder.restoreCallingIdentity(ident);
7401            }
7402        }
7403    }
7404
7405    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7406        if (!pr.killedByAm) {
7407            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7408            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7409                    pr.processName, pr.setAdj, reason);
7410            pr.killedByAm = true;
7411            Process.killProcessQuiet(pr.pid);
7412        }
7413    }
7414
7415    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7416        tr.disposeThumbnail();
7417        mRecentTasks.remove(tr);
7418        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7419        Intent baseIntent = new Intent(
7420                tr.intent != null ? tr.intent : tr.affinityIntent);
7421        ComponentName component = baseIntent.getComponent();
7422        if (component == null) {
7423            Slog.w(TAG, "Now component for base intent of task: " + tr);
7424            return;
7425        }
7426
7427        // Find any running services associated with this app.
7428        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7429
7430        if (killProcesses) {
7431            // Find any running processes associated with this app.
7432            final String pkg = component.getPackageName();
7433            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7434            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7435            for (int i=0; i<pmap.size(); i++) {
7436                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7437                for (int j=0; j<uids.size(); j++) {
7438                    ProcessRecord proc = uids.valueAt(j);
7439                    if (proc.userId != tr.userId) {
7440                        continue;
7441                    }
7442                    if (!proc.pkgList.containsKey(pkg)) {
7443                        continue;
7444                    }
7445                    procs.add(proc);
7446                }
7447            }
7448
7449            // Kill the running processes.
7450            for (int i=0; i<procs.size(); i++) {
7451                ProcessRecord pr = procs.get(i);
7452                if (pr == mHomeProcess) {
7453                    // Don't kill the home process along with tasks from the same package.
7454                    continue;
7455                }
7456                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7457                    killUnneededProcessLocked(pr, "remove task");
7458                } else {
7459                    pr.waitingToKill = "remove task";
7460                }
7461            }
7462        }
7463    }
7464
7465    /**
7466     * Removes the task with the specified task id.
7467     *
7468     * @param taskId Identifier of the task to be removed.
7469     * @param flags Additional operational flags.  May be 0 or
7470     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7471     * @return Returns true if the given task was found and removed.
7472     */
7473    private boolean removeTaskByIdLocked(int taskId, int flags) {
7474        TaskRecord tr = recentTaskForIdLocked(taskId);
7475        if (tr != null) {
7476            tr.removeTaskActivitiesLocked(-1, false);
7477            cleanUpRemovedTaskLocked(tr, flags);
7478            if (tr.isPersistable) {
7479                notifyTaskPersisterLocked(tr, true);
7480            }
7481            return true;
7482        }
7483        return false;
7484    }
7485
7486    @Override
7487    public boolean removeTask(int taskId, int flags) {
7488        synchronized (this) {
7489            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7490                    "removeTask()");
7491            long ident = Binder.clearCallingIdentity();
7492            try {
7493                return removeTaskByIdLocked(taskId, flags);
7494            } finally {
7495                Binder.restoreCallingIdentity(ident);
7496            }
7497        }
7498    }
7499
7500    /**
7501     * TODO: Add mController hook
7502     */
7503    @Override
7504    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7505        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7506                "moveTaskToFront()");
7507
7508        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7509        synchronized(this) {
7510            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7511                    Binder.getCallingUid(), "Task to front")) {
7512                ActivityOptions.abort(options);
7513                return;
7514            }
7515            final long origId = Binder.clearCallingIdentity();
7516            try {
7517                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7518                if (task == null) {
7519                    return;
7520                }
7521                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7522                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7523                    return;
7524                }
7525                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7526            } finally {
7527                Binder.restoreCallingIdentity(origId);
7528            }
7529            ActivityOptions.abort(options);
7530        }
7531    }
7532
7533    @Override
7534    public void moveTaskToBack(int taskId) {
7535        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7536                "moveTaskToBack()");
7537
7538        synchronized(this) {
7539            TaskRecord tr = recentTaskForIdLocked(taskId);
7540            if (tr != null) {
7541                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7542                ActivityStack stack = tr.stack;
7543                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7544                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7545                            Binder.getCallingUid(), "Task to back")) {
7546                        return;
7547                    }
7548                }
7549                final long origId = Binder.clearCallingIdentity();
7550                try {
7551                    stack.moveTaskToBackLocked(taskId, null);
7552                } finally {
7553                    Binder.restoreCallingIdentity(origId);
7554                }
7555            }
7556        }
7557    }
7558
7559    /**
7560     * Moves an activity, and all of the other activities within the same task, to the bottom
7561     * of the history stack.  The activity's order within the task is unchanged.
7562     *
7563     * @param token A reference to the activity we wish to move
7564     * @param nonRoot If false then this only works if the activity is the root
7565     *                of a task; if true it will work for any activity in a task.
7566     * @return Returns true if the move completed, false if not.
7567     */
7568    @Override
7569    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7570        enforceNotIsolatedCaller("moveActivityTaskToBack");
7571        synchronized(this) {
7572            final long origId = Binder.clearCallingIdentity();
7573            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7574            if (taskId >= 0) {
7575                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7576            }
7577            Binder.restoreCallingIdentity(origId);
7578        }
7579        return false;
7580    }
7581
7582    @Override
7583    public void moveTaskBackwards(int task) {
7584        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7585                "moveTaskBackwards()");
7586
7587        synchronized(this) {
7588            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7589                    Binder.getCallingUid(), "Task backwards")) {
7590                return;
7591            }
7592            final long origId = Binder.clearCallingIdentity();
7593            moveTaskBackwardsLocked(task);
7594            Binder.restoreCallingIdentity(origId);
7595        }
7596    }
7597
7598    private final void moveTaskBackwardsLocked(int task) {
7599        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7600    }
7601
7602    @Override
7603    public IBinder getHomeActivityToken() throws RemoteException {
7604        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7605                "getHomeActivityToken()");
7606        synchronized (this) {
7607            return mStackSupervisor.getHomeActivityToken();
7608        }
7609    }
7610
7611    @Override
7612    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7613            IActivityContainerCallback callback) throws RemoteException {
7614        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7615                "createActivityContainer()");
7616        synchronized (this) {
7617            if (parentActivityToken == null) {
7618                throw new IllegalArgumentException("parent token must not be null");
7619            }
7620            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7621            if (r == null) {
7622                return null;
7623            }
7624            if (callback == null) {
7625                throw new IllegalArgumentException("callback must not be null");
7626            }
7627            return mStackSupervisor.createActivityContainer(r, callback);
7628        }
7629    }
7630
7631    @Override
7632    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7633        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7634                "deleteActivityContainer()");
7635        synchronized (this) {
7636            mStackSupervisor.deleteActivityContainer(container);
7637        }
7638    }
7639
7640    @Override
7641    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7642            throws RemoteException {
7643        synchronized (this) {
7644            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7645            if (stack != null) {
7646                return stack.mActivityContainer;
7647            }
7648            return null;
7649        }
7650    }
7651
7652    @Override
7653    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7654        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7655                "moveTaskToStack()");
7656        if (stackId == HOME_STACK_ID) {
7657            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7658                    new RuntimeException("here").fillInStackTrace());
7659        }
7660        synchronized (this) {
7661            long ident = Binder.clearCallingIdentity();
7662            try {
7663                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7664                        + stackId + " toTop=" + toTop);
7665                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7666            } finally {
7667                Binder.restoreCallingIdentity(ident);
7668            }
7669        }
7670    }
7671
7672    @Override
7673    public void resizeStack(int stackBoxId, Rect bounds) {
7674        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7675                "resizeStackBox()");
7676        long ident = Binder.clearCallingIdentity();
7677        try {
7678            mWindowManager.resizeStack(stackBoxId, bounds);
7679        } finally {
7680            Binder.restoreCallingIdentity(ident);
7681        }
7682    }
7683
7684    @Override
7685    public List<StackInfo> getAllStackInfos() {
7686        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7687                "getAllStackInfos()");
7688        long ident = Binder.clearCallingIdentity();
7689        try {
7690            synchronized (this) {
7691                return mStackSupervisor.getAllStackInfosLocked();
7692            }
7693        } finally {
7694            Binder.restoreCallingIdentity(ident);
7695        }
7696    }
7697
7698    @Override
7699    public StackInfo getStackInfo(int stackId) {
7700        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7701                "getStackInfo()");
7702        long ident = Binder.clearCallingIdentity();
7703        try {
7704            synchronized (this) {
7705                return mStackSupervisor.getStackInfoLocked(stackId);
7706            }
7707        } finally {
7708            Binder.restoreCallingIdentity(ident);
7709        }
7710    }
7711
7712    @Override
7713    public boolean isInHomeStack(int taskId) {
7714        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7715                "getStackInfo()");
7716        long ident = Binder.clearCallingIdentity();
7717        try {
7718            synchronized (this) {
7719                TaskRecord tr = recentTaskForIdLocked(taskId);
7720                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7721            }
7722        } finally {
7723            Binder.restoreCallingIdentity(ident);
7724        }
7725    }
7726
7727    @Override
7728    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7729        synchronized(this) {
7730            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7731        }
7732    }
7733
7734    private boolean isLockTaskAuthorized(String pkg) {
7735        final DevicePolicyManager dpm = (DevicePolicyManager)
7736                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7737        try {
7738            int uid = mContext.getPackageManager().getPackageUid(pkg,
7739                    Binder.getCallingUserHandle().getIdentifier());
7740            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7741        } catch (NameNotFoundException e) {
7742            return false;
7743        }
7744    }
7745
7746    void startLockTaskMode(TaskRecord task) {
7747        final String pkg;
7748        synchronized (this) {
7749            pkg = task.intent.getComponent().getPackageName();
7750        }
7751        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7752        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7753            final TaskRecord taskRecord = task;
7754            mHandler.post(new Runnable() {
7755                @Override
7756                public void run() {
7757                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7758                }
7759            });
7760            return;
7761        }
7762        long ident = Binder.clearCallingIdentity();
7763        try {
7764            synchronized (this) {
7765                // Since we lost lock on task, make sure it is still there.
7766                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7767                if (task != null) {
7768                    if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
7769                        throw new IllegalArgumentException("Invalid task, not in foreground");
7770                    }
7771                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7772                }
7773            }
7774        } finally {
7775            Binder.restoreCallingIdentity(ident);
7776        }
7777    }
7778
7779    @Override
7780    public void startLockTaskMode(int taskId) {
7781        final TaskRecord task;
7782        long ident = Binder.clearCallingIdentity();
7783        try {
7784            synchronized (this) {
7785                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7786            }
7787        } finally {
7788            Binder.restoreCallingIdentity(ident);
7789        }
7790        if (task != null) {
7791            startLockTaskMode(task);
7792        }
7793    }
7794
7795    @Override
7796    public void startLockTaskMode(IBinder token) {
7797        final TaskRecord task;
7798        long ident = Binder.clearCallingIdentity();
7799        try {
7800            synchronized (this) {
7801                final ActivityRecord r = ActivityRecord.forToken(token);
7802                if (r == null) {
7803                    return;
7804                }
7805                task = r.task;
7806            }
7807        } finally {
7808            Binder.restoreCallingIdentity(ident);
7809        }
7810        if (task != null) {
7811            startLockTaskMode(task);
7812        }
7813    }
7814
7815    @Override
7816    public void startLockTaskModeOnCurrent() throws RemoteException {
7817        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7818        ActivityRecord r = null;
7819        synchronized (this) {
7820            r = mStackSupervisor.topRunningActivityLocked();
7821        }
7822        startLockTaskMode(r.task);
7823    }
7824
7825    @Override
7826    public void stopLockTaskMode() {
7827        // Verify that the user matches the package of the intent for the TaskRecord
7828        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7829        // and stopLockTaskMode.
7830        final int callingUid = Binder.getCallingUid();
7831        if (callingUid != Process.SYSTEM_UID) {
7832            try {
7833                String pkg =
7834                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7835                int uid = mContext.getPackageManager().getPackageUid(pkg,
7836                        Binder.getCallingUserHandle().getIdentifier());
7837                if (uid != callingUid) {
7838                    throw new SecurityException("Invalid uid, expected " + uid);
7839                }
7840            } catch (NameNotFoundException e) {
7841                Log.d(TAG, "stopLockTaskMode " + e);
7842                return;
7843            }
7844        }
7845        long ident = Binder.clearCallingIdentity();
7846        try {
7847            Log.d(TAG, "stopLockTaskMode");
7848            // Stop lock task
7849            synchronized (this) {
7850                mStackSupervisor.setLockTaskModeLocked(null, false);
7851            }
7852        } finally {
7853            Binder.restoreCallingIdentity(ident);
7854        }
7855    }
7856
7857    @Override
7858    public void stopLockTaskModeOnCurrent() throws RemoteException {
7859        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7860        long ident = Binder.clearCallingIdentity();
7861        try {
7862            stopLockTaskMode();
7863        } finally {
7864            Binder.restoreCallingIdentity(ident);
7865        }
7866    }
7867
7868    @Override
7869    public boolean isInLockTaskMode() {
7870        synchronized (this) {
7871            return mStackSupervisor.isInLockTaskMode();
7872        }
7873    }
7874
7875    // =========================================================
7876    // CONTENT PROVIDERS
7877    // =========================================================
7878
7879    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7880        List<ProviderInfo> providers = null;
7881        try {
7882            providers = AppGlobals.getPackageManager().
7883                queryContentProviders(app.processName, app.uid,
7884                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7885        } catch (RemoteException ex) {
7886        }
7887        if (DEBUG_MU)
7888            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7889        int userId = app.userId;
7890        if (providers != null) {
7891            int N = providers.size();
7892            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7893            for (int i=0; i<N; i++) {
7894                ProviderInfo cpi =
7895                    (ProviderInfo)providers.get(i);
7896                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7897                        cpi.name, cpi.flags);
7898                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7899                    // This is a singleton provider, but a user besides the
7900                    // default user is asking to initialize a process it runs
7901                    // in...  well, no, it doesn't actually run in this process,
7902                    // it runs in the process of the default user.  Get rid of it.
7903                    providers.remove(i);
7904                    N--;
7905                    i--;
7906                    continue;
7907                }
7908
7909                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7910                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7911                if (cpr == null) {
7912                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7913                    mProviderMap.putProviderByClass(comp, cpr);
7914                }
7915                if (DEBUG_MU)
7916                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7917                app.pubProviders.put(cpi.name, cpr);
7918                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7919                    // Don't add this if it is a platform component that is marked
7920                    // to run in multiple processes, because this is actually
7921                    // part of the framework so doesn't make sense to track as a
7922                    // separate apk in the process.
7923                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7924                            mProcessStats);
7925                }
7926                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7927            }
7928        }
7929        return providers;
7930    }
7931
7932    /**
7933     * Check if {@link ProcessRecord} has a possible chance at accessing the
7934     * given {@link ProviderInfo}. Final permission checking is always done
7935     * in {@link ContentProvider}.
7936     */
7937    private final String checkContentProviderPermissionLocked(
7938            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7939        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7940        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7941        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7942        // Looking for cross-user grants before to enforce the typical cross-users permissions
7943        if (userId != UserHandle.getUserId(callingUid)) {
7944            if (perms != null) {
7945                for (GrantUri grantUri : perms.keySet()) {
7946                    if (grantUri.sourceUserId == userId) {
7947                        String authority = grantUri.uri.getAuthority();
7948                        if (authority.equals(cpi.authority)) {
7949                            return null;
7950                        }
7951                    }
7952                }
7953            }
7954        }
7955        if (checkUser) {
7956            userId = handleIncomingUser(callingPid, callingUid, userId,
7957                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7958        }
7959        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7960                cpi.applicationInfo.uid, cpi.exported)
7961                == PackageManager.PERMISSION_GRANTED) {
7962            return null;
7963        }
7964        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7965                cpi.applicationInfo.uid, cpi.exported)
7966                == PackageManager.PERMISSION_GRANTED) {
7967            return null;
7968        }
7969
7970        PathPermission[] pps = cpi.pathPermissions;
7971        if (pps != null) {
7972            int i = pps.length;
7973            while (i > 0) {
7974                i--;
7975                PathPermission pp = pps[i];
7976                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7977                        cpi.applicationInfo.uid, cpi.exported)
7978                        == PackageManager.PERMISSION_GRANTED) {
7979                    return null;
7980                }
7981                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7982                        cpi.applicationInfo.uid, cpi.exported)
7983                        == PackageManager.PERMISSION_GRANTED) {
7984                    return null;
7985                }
7986            }
7987        }
7988
7989        if (perms != null) {
7990            for (GrantUri grantUri : perms.keySet()) {
7991                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7992                    return null;
7993                }
7994            }
7995        }
7996
7997        String msg;
7998        if (!cpi.exported) {
7999            msg = "Permission Denial: opening provider " + cpi.name
8000                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8001                    + ", uid=" + callingUid + ") that is not exported from uid "
8002                    + cpi.applicationInfo.uid;
8003        } else {
8004            msg = "Permission Denial: opening provider " + cpi.name
8005                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8006                    + ", uid=" + callingUid + ") requires "
8007                    + cpi.readPermission + " or " + cpi.writePermission;
8008        }
8009        Slog.w(TAG, msg);
8010        return msg;
8011    }
8012
8013    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8014            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8015        if (r != null) {
8016            for (int i=0; i<r.conProviders.size(); i++) {
8017                ContentProviderConnection conn = r.conProviders.get(i);
8018                if (conn.provider == cpr) {
8019                    if (DEBUG_PROVIDER) Slog.v(TAG,
8020                            "Adding provider requested by "
8021                            + r.processName + " from process "
8022                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8023                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8024                    if (stable) {
8025                        conn.stableCount++;
8026                        conn.numStableIncs++;
8027                    } else {
8028                        conn.unstableCount++;
8029                        conn.numUnstableIncs++;
8030                    }
8031                    return conn;
8032                }
8033            }
8034            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8035            if (stable) {
8036                conn.stableCount = 1;
8037                conn.numStableIncs = 1;
8038            } else {
8039                conn.unstableCount = 1;
8040                conn.numUnstableIncs = 1;
8041            }
8042            cpr.connections.add(conn);
8043            r.conProviders.add(conn);
8044            return conn;
8045        }
8046        cpr.addExternalProcessHandleLocked(externalProcessToken);
8047        return null;
8048    }
8049
8050    boolean decProviderCountLocked(ContentProviderConnection conn,
8051            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8052        if (conn != null) {
8053            cpr = conn.provider;
8054            if (DEBUG_PROVIDER) Slog.v(TAG,
8055                    "Removing provider requested by "
8056                    + conn.client.processName + " from process "
8057                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8058                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8059            if (stable) {
8060                conn.stableCount--;
8061            } else {
8062                conn.unstableCount--;
8063            }
8064            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8065                cpr.connections.remove(conn);
8066                conn.client.conProviders.remove(conn);
8067                return true;
8068            }
8069            return false;
8070        }
8071        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8072        return false;
8073    }
8074
8075    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8076            String name, IBinder token, boolean stable, int userId) {
8077        ContentProviderRecord cpr;
8078        ContentProviderConnection conn = null;
8079        ProviderInfo cpi = null;
8080
8081        synchronized(this) {
8082            ProcessRecord r = null;
8083            if (caller != null) {
8084                r = getRecordForAppLocked(caller);
8085                if (r == null) {
8086                    throw new SecurityException(
8087                            "Unable to find app for caller " + caller
8088                          + " (pid=" + Binder.getCallingPid()
8089                          + ") when getting content provider " + name);
8090                }
8091            }
8092
8093            boolean checkCrossUser = true;
8094
8095            // First check if this content provider has been published...
8096            cpr = mProviderMap.getProviderByName(name, userId);
8097            // If that didn't work, check if it exists for user 0 and then
8098            // verify that it's a singleton provider before using it.
8099            if (cpr == null && userId != UserHandle.USER_OWNER) {
8100                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8101                if (cpr != null) {
8102                    cpi = cpr.info;
8103                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8104                            cpi.name, cpi.flags)
8105                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8106                        userId = UserHandle.USER_OWNER;
8107                        checkCrossUser = false;
8108                    } else {
8109                        cpr = null;
8110                        cpi = null;
8111                    }
8112                }
8113            }
8114
8115            boolean providerRunning = cpr != null;
8116            if (providerRunning) {
8117                cpi = cpr.info;
8118                String msg;
8119                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8120                        != null) {
8121                    throw new SecurityException(msg);
8122                }
8123
8124                if (r != null && cpr.canRunHere(r)) {
8125                    // This provider has been published or is in the process
8126                    // of being published...  but it is also allowed to run
8127                    // in the caller's process, so don't make a connection
8128                    // and just let the caller instantiate its own instance.
8129                    ContentProviderHolder holder = cpr.newHolder(null);
8130                    // don't give caller the provider object, it needs
8131                    // to make its own.
8132                    holder.provider = null;
8133                    return holder;
8134                }
8135
8136                final long origId = Binder.clearCallingIdentity();
8137
8138                // In this case the provider instance already exists, so we can
8139                // return it right away.
8140                conn = incProviderCountLocked(r, cpr, token, stable);
8141                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8142                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8143                        // If this is a perceptible app accessing the provider,
8144                        // make sure to count it as being accessed and thus
8145                        // back up on the LRU list.  This is good because
8146                        // content providers are often expensive to start.
8147                        updateLruProcessLocked(cpr.proc, false, null);
8148                    }
8149                }
8150
8151                if (cpr.proc != null) {
8152                    if (false) {
8153                        if (cpr.name.flattenToShortString().equals(
8154                                "com.android.providers.calendar/.CalendarProvider2")) {
8155                            Slog.v(TAG, "****************** KILLING "
8156                                + cpr.name.flattenToShortString());
8157                            Process.killProcess(cpr.proc.pid);
8158                        }
8159                    }
8160                    boolean success = updateOomAdjLocked(cpr.proc);
8161                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8162                    // NOTE: there is still a race here where a signal could be
8163                    // pending on the process even though we managed to update its
8164                    // adj level.  Not sure what to do about this, but at least
8165                    // the race is now smaller.
8166                    if (!success) {
8167                        // Uh oh...  it looks like the provider's process
8168                        // has been killed on us.  We need to wait for a new
8169                        // process to be started, and make sure its death
8170                        // doesn't kill our process.
8171                        Slog.i(TAG,
8172                                "Existing provider " + cpr.name.flattenToShortString()
8173                                + " is crashing; detaching " + r);
8174                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8175                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8176                        if (!lastRef) {
8177                            // This wasn't the last ref our process had on
8178                            // the provider...  we have now been killed, bail.
8179                            return null;
8180                        }
8181                        providerRunning = false;
8182                        conn = null;
8183                    }
8184                }
8185
8186                Binder.restoreCallingIdentity(origId);
8187            }
8188
8189            boolean singleton;
8190            if (!providerRunning) {
8191                try {
8192                    cpi = AppGlobals.getPackageManager().
8193                        resolveContentProvider(name,
8194                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8195                } catch (RemoteException ex) {
8196                }
8197                if (cpi == null) {
8198                    return null;
8199                }
8200                // If the provider is a singleton AND
8201                // (it's a call within the same user || the provider is a
8202                // privileged app)
8203                // Then allow connecting to the singleton provider
8204                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8205                        cpi.name, cpi.flags)
8206                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8207                if (singleton) {
8208                    userId = UserHandle.USER_OWNER;
8209                }
8210                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8211
8212                String msg;
8213                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8214                        != null) {
8215                    throw new SecurityException(msg);
8216                }
8217
8218                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8219                        && !cpi.processName.equals("system")) {
8220                    // If this content provider does not run in the system
8221                    // process, and the system is not yet ready to run other
8222                    // processes, then fail fast instead of hanging.
8223                    throw new IllegalArgumentException(
8224                            "Attempt to launch content provider before system ready");
8225                }
8226
8227                // Make sure that the user who owns this provider is started.  If not,
8228                // we don't want to allow it to run.
8229                if (mStartedUsers.get(userId) == null) {
8230                    Slog.w(TAG, "Unable to launch app "
8231                            + cpi.applicationInfo.packageName + "/"
8232                            + cpi.applicationInfo.uid + " for provider "
8233                            + name + ": user " + userId + " is stopped");
8234                    return null;
8235                }
8236
8237                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8238                cpr = mProviderMap.getProviderByClass(comp, userId);
8239                final boolean firstClass = cpr == null;
8240                if (firstClass) {
8241                    try {
8242                        ApplicationInfo ai =
8243                            AppGlobals.getPackageManager().
8244                                getApplicationInfo(
8245                                        cpi.applicationInfo.packageName,
8246                                        STOCK_PM_FLAGS, userId);
8247                        if (ai == null) {
8248                            Slog.w(TAG, "No package info for content provider "
8249                                    + cpi.name);
8250                            return null;
8251                        }
8252                        ai = getAppInfoForUser(ai, userId);
8253                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8254                    } catch (RemoteException ex) {
8255                        // pm is in same process, this will never happen.
8256                    }
8257                }
8258
8259                if (r != null && cpr.canRunHere(r)) {
8260                    // If this is a multiprocess provider, then just return its
8261                    // info and allow the caller to instantiate it.  Only do
8262                    // this if the provider is the same user as the caller's
8263                    // process, or can run as root (so can be in any process).
8264                    return cpr.newHolder(null);
8265                }
8266
8267                if (DEBUG_PROVIDER) {
8268                    RuntimeException e = new RuntimeException("here");
8269                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8270                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8271                }
8272
8273                // This is single process, and our app is now connecting to it.
8274                // See if we are already in the process of launching this
8275                // provider.
8276                final int N = mLaunchingProviders.size();
8277                int i;
8278                for (i=0; i<N; i++) {
8279                    if (mLaunchingProviders.get(i) == cpr) {
8280                        break;
8281                    }
8282                }
8283
8284                // If the provider is not already being launched, then get it
8285                // started.
8286                if (i >= N) {
8287                    final long origId = Binder.clearCallingIdentity();
8288
8289                    try {
8290                        // Content provider is now in use, its package can't be stopped.
8291                        try {
8292                            AppGlobals.getPackageManager().setPackageStoppedState(
8293                                    cpr.appInfo.packageName, false, userId);
8294                        } catch (RemoteException e) {
8295                        } catch (IllegalArgumentException e) {
8296                            Slog.w(TAG, "Failed trying to unstop package "
8297                                    + cpr.appInfo.packageName + ": " + e);
8298                        }
8299
8300                        // Use existing process if already started
8301                        ProcessRecord proc = getProcessRecordLocked(
8302                                cpi.processName, cpr.appInfo.uid, false);
8303                        if (proc != null && proc.thread != null) {
8304                            if (DEBUG_PROVIDER) {
8305                                Slog.d(TAG, "Installing in existing process " + proc);
8306                            }
8307                            proc.pubProviders.put(cpi.name, cpr);
8308                            try {
8309                                proc.thread.scheduleInstallProvider(cpi);
8310                            } catch (RemoteException e) {
8311                            }
8312                        } else {
8313                            proc = startProcessLocked(cpi.processName,
8314                                    cpr.appInfo, false, 0, "content provider",
8315                                    new ComponentName(cpi.applicationInfo.packageName,
8316                                            cpi.name), false, false, false);
8317                            if (proc == null) {
8318                                Slog.w(TAG, "Unable to launch app "
8319                                        + cpi.applicationInfo.packageName + "/"
8320                                        + cpi.applicationInfo.uid + " for provider "
8321                                        + name + ": process is bad");
8322                                return null;
8323                            }
8324                        }
8325                        cpr.launchingApp = proc;
8326                        mLaunchingProviders.add(cpr);
8327                    } finally {
8328                        Binder.restoreCallingIdentity(origId);
8329                    }
8330                }
8331
8332                // Make sure the provider is published (the same provider class
8333                // may be published under multiple names).
8334                if (firstClass) {
8335                    mProviderMap.putProviderByClass(comp, cpr);
8336                }
8337
8338                mProviderMap.putProviderByName(name, cpr);
8339                conn = incProviderCountLocked(r, cpr, token, stable);
8340                if (conn != null) {
8341                    conn.waiting = true;
8342                }
8343            }
8344        }
8345
8346        // Wait for the provider to be published...
8347        synchronized (cpr) {
8348            while (cpr.provider == null) {
8349                if (cpr.launchingApp == null) {
8350                    Slog.w(TAG, "Unable to launch app "
8351                            + cpi.applicationInfo.packageName + "/"
8352                            + cpi.applicationInfo.uid + " for provider "
8353                            + name + ": launching app became null");
8354                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8355                            UserHandle.getUserId(cpi.applicationInfo.uid),
8356                            cpi.applicationInfo.packageName,
8357                            cpi.applicationInfo.uid, name);
8358                    return null;
8359                }
8360                try {
8361                    if (DEBUG_MU) {
8362                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8363                                + cpr.launchingApp);
8364                    }
8365                    if (conn != null) {
8366                        conn.waiting = true;
8367                    }
8368                    cpr.wait();
8369                } catch (InterruptedException ex) {
8370                } finally {
8371                    if (conn != null) {
8372                        conn.waiting = false;
8373                    }
8374                }
8375            }
8376        }
8377        return cpr != null ? cpr.newHolder(conn) : null;
8378    }
8379
8380    @Override
8381    public final ContentProviderHolder getContentProvider(
8382            IApplicationThread caller, String name, int userId, boolean stable) {
8383        enforceNotIsolatedCaller("getContentProvider");
8384        if (caller == null) {
8385            String msg = "null IApplicationThread when getting content provider "
8386                    + name;
8387            Slog.w(TAG, msg);
8388            throw new SecurityException(msg);
8389        }
8390        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8391        // with cross-user grant.
8392        return getContentProviderImpl(caller, name, null, stable, userId);
8393    }
8394
8395    public ContentProviderHolder getContentProviderExternal(
8396            String name, int userId, IBinder token) {
8397        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8398            "Do not have permission in call getContentProviderExternal()");
8399        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8400                false, true, "getContentProvider", null);
8401        return getContentProviderExternalUnchecked(name, token, userId);
8402    }
8403
8404    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8405            IBinder token, int userId) {
8406        return getContentProviderImpl(null, name, token, true, userId);
8407    }
8408
8409    /**
8410     * Drop a content provider from a ProcessRecord's bookkeeping
8411     */
8412    public void removeContentProvider(IBinder connection, boolean stable) {
8413        enforceNotIsolatedCaller("removeContentProvider");
8414        long ident = Binder.clearCallingIdentity();
8415        try {
8416            synchronized (this) {
8417                ContentProviderConnection conn;
8418                try {
8419                    conn = (ContentProviderConnection)connection;
8420                } catch (ClassCastException e) {
8421                    String msg ="removeContentProvider: " + connection
8422                            + " not a ContentProviderConnection";
8423                    Slog.w(TAG, msg);
8424                    throw new IllegalArgumentException(msg);
8425                }
8426                if (conn == null) {
8427                    throw new NullPointerException("connection is null");
8428                }
8429                if (decProviderCountLocked(conn, null, null, stable)) {
8430                    updateOomAdjLocked();
8431                }
8432            }
8433        } finally {
8434            Binder.restoreCallingIdentity(ident);
8435        }
8436    }
8437
8438    public void removeContentProviderExternal(String name, IBinder token) {
8439        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8440            "Do not have permission in call removeContentProviderExternal()");
8441        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8442    }
8443
8444    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8445        synchronized (this) {
8446            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8447            if(cpr == null) {
8448                //remove from mProvidersByClass
8449                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8450                return;
8451            }
8452
8453            //update content provider record entry info
8454            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8455            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8456            if (localCpr.hasExternalProcessHandles()) {
8457                if (localCpr.removeExternalProcessHandleLocked(token)) {
8458                    updateOomAdjLocked();
8459                } else {
8460                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8461                            + " with no external reference for token: "
8462                            + token + ".");
8463                }
8464            } else {
8465                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8466                        + " with no external references.");
8467            }
8468        }
8469    }
8470
8471    public final void publishContentProviders(IApplicationThread caller,
8472            List<ContentProviderHolder> providers) {
8473        if (providers == null) {
8474            return;
8475        }
8476
8477        enforceNotIsolatedCaller("publishContentProviders");
8478        synchronized (this) {
8479            final ProcessRecord r = getRecordForAppLocked(caller);
8480            if (DEBUG_MU)
8481                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8482            if (r == null) {
8483                throw new SecurityException(
8484                        "Unable to find app for caller " + caller
8485                      + " (pid=" + Binder.getCallingPid()
8486                      + ") when publishing content providers");
8487            }
8488
8489            final long origId = Binder.clearCallingIdentity();
8490
8491            final int N = providers.size();
8492            for (int i=0; i<N; i++) {
8493                ContentProviderHolder src = providers.get(i);
8494                if (src == null || src.info == null || src.provider == null) {
8495                    continue;
8496                }
8497                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8498                if (DEBUG_MU)
8499                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8500                if (dst != null) {
8501                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8502                    mProviderMap.putProviderByClass(comp, dst);
8503                    String names[] = dst.info.authority.split(";");
8504                    for (int j = 0; j < names.length; j++) {
8505                        mProviderMap.putProviderByName(names[j], dst);
8506                    }
8507
8508                    int NL = mLaunchingProviders.size();
8509                    int j;
8510                    for (j=0; j<NL; j++) {
8511                        if (mLaunchingProviders.get(j) == dst) {
8512                            mLaunchingProviders.remove(j);
8513                            j--;
8514                            NL--;
8515                        }
8516                    }
8517                    synchronized (dst) {
8518                        dst.provider = src.provider;
8519                        dst.proc = r;
8520                        dst.notifyAll();
8521                    }
8522                    updateOomAdjLocked(r);
8523                }
8524            }
8525
8526            Binder.restoreCallingIdentity(origId);
8527        }
8528    }
8529
8530    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8531        ContentProviderConnection conn;
8532        try {
8533            conn = (ContentProviderConnection)connection;
8534        } catch (ClassCastException e) {
8535            String msg ="refContentProvider: " + connection
8536                    + " not a ContentProviderConnection";
8537            Slog.w(TAG, msg);
8538            throw new IllegalArgumentException(msg);
8539        }
8540        if (conn == null) {
8541            throw new NullPointerException("connection is null");
8542        }
8543
8544        synchronized (this) {
8545            if (stable > 0) {
8546                conn.numStableIncs += stable;
8547            }
8548            stable = conn.stableCount + stable;
8549            if (stable < 0) {
8550                throw new IllegalStateException("stableCount < 0: " + stable);
8551            }
8552
8553            if (unstable > 0) {
8554                conn.numUnstableIncs += unstable;
8555            }
8556            unstable = conn.unstableCount + unstable;
8557            if (unstable < 0) {
8558                throw new IllegalStateException("unstableCount < 0: " + unstable);
8559            }
8560
8561            if ((stable+unstable) <= 0) {
8562                throw new IllegalStateException("ref counts can't go to zero here: stable="
8563                        + stable + " unstable=" + unstable);
8564            }
8565            conn.stableCount = stable;
8566            conn.unstableCount = unstable;
8567            return !conn.dead;
8568        }
8569    }
8570
8571    public void unstableProviderDied(IBinder connection) {
8572        ContentProviderConnection conn;
8573        try {
8574            conn = (ContentProviderConnection)connection;
8575        } catch (ClassCastException e) {
8576            String msg ="refContentProvider: " + connection
8577                    + " not a ContentProviderConnection";
8578            Slog.w(TAG, msg);
8579            throw new IllegalArgumentException(msg);
8580        }
8581        if (conn == null) {
8582            throw new NullPointerException("connection is null");
8583        }
8584
8585        // Safely retrieve the content provider associated with the connection.
8586        IContentProvider provider;
8587        synchronized (this) {
8588            provider = conn.provider.provider;
8589        }
8590
8591        if (provider == null) {
8592            // Um, yeah, we're way ahead of you.
8593            return;
8594        }
8595
8596        // Make sure the caller is being honest with us.
8597        if (provider.asBinder().pingBinder()) {
8598            // Er, no, still looks good to us.
8599            synchronized (this) {
8600                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8601                        + " says " + conn + " died, but we don't agree");
8602                return;
8603            }
8604        }
8605
8606        // Well look at that!  It's dead!
8607        synchronized (this) {
8608            if (conn.provider.provider != provider) {
8609                // But something changed...  good enough.
8610                return;
8611            }
8612
8613            ProcessRecord proc = conn.provider.proc;
8614            if (proc == null || proc.thread == null) {
8615                // Seems like the process is already cleaned up.
8616                return;
8617            }
8618
8619            // As far as we're concerned, this is just like receiving a
8620            // death notification...  just a bit prematurely.
8621            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8622                    + ") early provider death");
8623            final long ident = Binder.clearCallingIdentity();
8624            try {
8625                appDiedLocked(proc, proc.pid, proc.thread);
8626            } finally {
8627                Binder.restoreCallingIdentity(ident);
8628            }
8629        }
8630    }
8631
8632    @Override
8633    public void appNotRespondingViaProvider(IBinder connection) {
8634        enforceCallingPermission(
8635                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8636
8637        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8638        if (conn == null) {
8639            Slog.w(TAG, "ContentProviderConnection is null");
8640            return;
8641        }
8642
8643        final ProcessRecord host = conn.provider.proc;
8644        if (host == null) {
8645            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8646            return;
8647        }
8648
8649        final long token = Binder.clearCallingIdentity();
8650        try {
8651            appNotResponding(host, null, null, false, "ContentProvider not responding");
8652        } finally {
8653            Binder.restoreCallingIdentity(token);
8654        }
8655    }
8656
8657    public final void installSystemProviders() {
8658        List<ProviderInfo> providers;
8659        synchronized (this) {
8660            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8661            providers = generateApplicationProvidersLocked(app);
8662            if (providers != null) {
8663                for (int i=providers.size()-1; i>=0; i--) {
8664                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8665                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8666                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8667                                + ": not system .apk");
8668                        providers.remove(i);
8669                    }
8670                }
8671            }
8672        }
8673        if (providers != null) {
8674            mSystemThread.installSystemProviders(providers);
8675        }
8676
8677        mCoreSettingsObserver = new CoreSettingsObserver(this);
8678
8679        mUsageStatsService.monitorPackages();
8680    }
8681
8682    /**
8683     * Allows app to retrieve the MIME type of a URI without having permission
8684     * to access its content provider.
8685     *
8686     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8687     *
8688     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8689     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8690     */
8691    public String getProviderMimeType(Uri uri, int userId) {
8692        enforceNotIsolatedCaller("getProviderMimeType");
8693        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8694                userId, false, true, "getProviderMimeType", null);
8695        final String name = uri.getAuthority();
8696        final long ident = Binder.clearCallingIdentity();
8697        ContentProviderHolder holder = null;
8698
8699        try {
8700            holder = getContentProviderExternalUnchecked(name, null, userId);
8701            if (holder != null) {
8702                return holder.provider.getType(uri);
8703            }
8704        } catch (RemoteException e) {
8705            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8706            return null;
8707        } finally {
8708            if (holder != null) {
8709                removeContentProviderExternalUnchecked(name, null, userId);
8710            }
8711            Binder.restoreCallingIdentity(ident);
8712        }
8713
8714        return null;
8715    }
8716
8717    // =========================================================
8718    // GLOBAL MANAGEMENT
8719    // =========================================================
8720
8721    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8722            boolean isolated) {
8723        String proc = customProcess != null ? customProcess : info.processName;
8724        BatteryStatsImpl.Uid.Proc ps = null;
8725        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8726        int uid = info.uid;
8727        if (isolated) {
8728            int userId = UserHandle.getUserId(uid);
8729            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8730            while (true) {
8731                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8732                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8733                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8734                }
8735                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8736                mNextIsolatedProcessUid++;
8737                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8738                    // No process for this uid, use it.
8739                    break;
8740                }
8741                stepsLeft--;
8742                if (stepsLeft <= 0) {
8743                    return null;
8744                }
8745            }
8746        }
8747        return new ProcessRecord(stats, info, proc, uid);
8748    }
8749
8750    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8751            String abiOverride) {
8752        ProcessRecord app;
8753        if (!isolated) {
8754            app = getProcessRecordLocked(info.processName, info.uid, true);
8755        } else {
8756            app = null;
8757        }
8758
8759        if (app == null) {
8760            app = newProcessRecordLocked(info, null, isolated);
8761            mProcessNames.put(info.processName, app.uid, app);
8762            if (isolated) {
8763                mIsolatedProcesses.put(app.uid, app);
8764            }
8765            updateLruProcessLocked(app, false, null);
8766            updateOomAdjLocked();
8767        }
8768
8769        // This package really, really can not be stopped.
8770        try {
8771            AppGlobals.getPackageManager().setPackageStoppedState(
8772                    info.packageName, false, UserHandle.getUserId(app.uid));
8773        } catch (RemoteException e) {
8774        } catch (IllegalArgumentException e) {
8775            Slog.w(TAG, "Failed trying to unstop package "
8776                    + info.packageName + ": " + e);
8777        }
8778
8779        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8780                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8781            app.persistent = true;
8782            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8783        }
8784        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8785            mPersistentStartingProcesses.add(app);
8786            startProcessLocked(app, "added application", app.processName,
8787                    abiOverride);
8788        }
8789
8790        return app;
8791    }
8792
8793    public void unhandledBack() {
8794        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8795                "unhandledBack()");
8796
8797        synchronized(this) {
8798            final long origId = Binder.clearCallingIdentity();
8799            try {
8800                getFocusedStack().unhandledBackLocked();
8801            } finally {
8802                Binder.restoreCallingIdentity(origId);
8803            }
8804        }
8805    }
8806
8807    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8808        enforceNotIsolatedCaller("openContentUri");
8809        final int userId = UserHandle.getCallingUserId();
8810        String name = uri.getAuthority();
8811        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8812        ParcelFileDescriptor pfd = null;
8813        if (cph != null) {
8814            // We record the binder invoker's uid in thread-local storage before
8815            // going to the content provider to open the file.  Later, in the code
8816            // that handles all permissions checks, we look for this uid and use
8817            // that rather than the Activity Manager's own uid.  The effect is that
8818            // we do the check against the caller's permissions even though it looks
8819            // to the content provider like the Activity Manager itself is making
8820            // the request.
8821            sCallerIdentity.set(new Identity(
8822                    Binder.getCallingPid(), Binder.getCallingUid()));
8823            try {
8824                pfd = cph.provider.openFile(null, uri, "r", null);
8825            } catch (FileNotFoundException e) {
8826                // do nothing; pfd will be returned null
8827            } finally {
8828                // Ensure that whatever happens, we clean up the identity state
8829                sCallerIdentity.remove();
8830            }
8831
8832            // We've got the fd now, so we're done with the provider.
8833            removeContentProviderExternalUnchecked(name, null, userId);
8834        } else {
8835            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8836        }
8837        return pfd;
8838    }
8839
8840    // Actually is sleeping or shutting down or whatever else in the future
8841    // is an inactive state.
8842    public boolean isSleepingOrShuttingDown() {
8843        return mSleeping || mShuttingDown;
8844    }
8845
8846    public boolean isSleeping() {
8847        return mSleeping;
8848    }
8849
8850    void goingToSleep() {
8851        synchronized(this) {
8852            mWentToSleep = true;
8853            updateEventDispatchingLocked();
8854            goToSleepIfNeededLocked();
8855        }
8856    }
8857
8858    void finishRunningVoiceLocked() {
8859        if (mRunningVoice) {
8860            mRunningVoice = false;
8861            goToSleepIfNeededLocked();
8862        }
8863    }
8864
8865    void goToSleepIfNeededLocked() {
8866        if (mWentToSleep && !mRunningVoice) {
8867            if (!mSleeping) {
8868                mSleeping = true;
8869                mStackSupervisor.goingToSleepLocked();
8870
8871                // Initialize the wake times of all processes.
8872                checkExcessivePowerUsageLocked(false);
8873                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8874                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8875                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8876            }
8877        }
8878    }
8879
8880    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8881        mTaskPersister.notify(task, flush);
8882    }
8883
8884    @Override
8885    public boolean shutdown(int timeout) {
8886        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8887                != PackageManager.PERMISSION_GRANTED) {
8888            throw new SecurityException("Requires permission "
8889                    + android.Manifest.permission.SHUTDOWN);
8890        }
8891
8892        boolean timedout = false;
8893
8894        synchronized(this) {
8895            mShuttingDown = true;
8896            updateEventDispatchingLocked();
8897            timedout = mStackSupervisor.shutdownLocked(timeout);
8898        }
8899
8900        mAppOpsService.shutdown();
8901        mUsageStatsService.shutdown();
8902        mBatteryStatsService.shutdown();
8903        synchronized (this) {
8904            mProcessStats.shutdownLocked();
8905        }
8906        notifyTaskPersisterLocked(null, true);
8907
8908        return timedout;
8909    }
8910
8911    public final void activitySlept(IBinder token) {
8912        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8913
8914        final long origId = Binder.clearCallingIdentity();
8915
8916        synchronized (this) {
8917            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8918            if (r != null) {
8919                mStackSupervisor.activitySleptLocked(r);
8920            }
8921        }
8922
8923        Binder.restoreCallingIdentity(origId);
8924    }
8925
8926    void logLockScreen(String msg) {
8927        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8928                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8929                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8930                mStackSupervisor.mDismissKeyguardOnNextActivity);
8931    }
8932
8933    private void comeOutOfSleepIfNeededLocked() {
8934        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8935            if (mSleeping) {
8936                mSleeping = false;
8937                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8938            }
8939        }
8940    }
8941
8942    void wakingUp() {
8943        synchronized(this) {
8944            mWentToSleep = false;
8945            updateEventDispatchingLocked();
8946            comeOutOfSleepIfNeededLocked();
8947        }
8948    }
8949
8950    void startRunningVoiceLocked() {
8951        if (!mRunningVoice) {
8952            mRunningVoice = true;
8953            comeOutOfSleepIfNeededLocked();
8954        }
8955    }
8956
8957    private void updateEventDispatchingLocked() {
8958        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8959    }
8960
8961    public void setLockScreenShown(boolean shown) {
8962        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8963                != PackageManager.PERMISSION_GRANTED) {
8964            throw new SecurityException("Requires permission "
8965                    + android.Manifest.permission.DEVICE_POWER);
8966        }
8967
8968        synchronized(this) {
8969            long ident = Binder.clearCallingIdentity();
8970            try {
8971                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8972                mLockScreenShown = shown;
8973                comeOutOfSleepIfNeededLocked();
8974            } finally {
8975                Binder.restoreCallingIdentity(ident);
8976            }
8977        }
8978    }
8979
8980    public void stopAppSwitches() {
8981        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8982                != PackageManager.PERMISSION_GRANTED) {
8983            throw new SecurityException("Requires permission "
8984                    + android.Manifest.permission.STOP_APP_SWITCHES);
8985        }
8986
8987        synchronized(this) {
8988            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8989                    + APP_SWITCH_DELAY_TIME;
8990            mDidAppSwitch = false;
8991            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8992            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8993            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8994        }
8995    }
8996
8997    public void resumeAppSwitches() {
8998        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8999                != PackageManager.PERMISSION_GRANTED) {
9000            throw new SecurityException("Requires permission "
9001                    + android.Manifest.permission.STOP_APP_SWITCHES);
9002        }
9003
9004        synchronized(this) {
9005            // Note that we don't execute any pending app switches... we will
9006            // let those wait until either the timeout, or the next start
9007            // activity request.
9008            mAppSwitchesAllowedTime = 0;
9009        }
9010    }
9011
9012    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9013            String name) {
9014        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9015            return true;
9016        }
9017
9018        final int perm = checkComponentPermission(
9019                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9020                callingUid, -1, true);
9021        if (perm == PackageManager.PERMISSION_GRANTED) {
9022            return true;
9023        }
9024
9025        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9026        return false;
9027    }
9028
9029    public void setDebugApp(String packageName, boolean waitForDebugger,
9030            boolean persistent) {
9031        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9032                "setDebugApp()");
9033
9034        long ident = Binder.clearCallingIdentity();
9035        try {
9036            // Note that this is not really thread safe if there are multiple
9037            // callers into it at the same time, but that's not a situation we
9038            // care about.
9039            if (persistent) {
9040                final ContentResolver resolver = mContext.getContentResolver();
9041                Settings.Global.putString(
9042                    resolver, Settings.Global.DEBUG_APP,
9043                    packageName);
9044                Settings.Global.putInt(
9045                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9046                    waitForDebugger ? 1 : 0);
9047            }
9048
9049            synchronized (this) {
9050                if (!persistent) {
9051                    mOrigDebugApp = mDebugApp;
9052                    mOrigWaitForDebugger = mWaitForDebugger;
9053                }
9054                mDebugApp = packageName;
9055                mWaitForDebugger = waitForDebugger;
9056                mDebugTransient = !persistent;
9057                if (packageName != null) {
9058                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9059                            false, UserHandle.USER_ALL, "set debug app");
9060                }
9061            }
9062        } finally {
9063            Binder.restoreCallingIdentity(ident);
9064        }
9065    }
9066
9067    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9068        synchronized (this) {
9069            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9070            if (!isDebuggable) {
9071                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9072                    throw new SecurityException("Process not debuggable: " + app.packageName);
9073                }
9074            }
9075
9076            mOpenGlTraceApp = processName;
9077        }
9078    }
9079
9080    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9081            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9082        synchronized (this) {
9083            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9084            if (!isDebuggable) {
9085                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9086                    throw new SecurityException("Process not debuggable: " + app.packageName);
9087                }
9088            }
9089            mProfileApp = processName;
9090            mProfileFile = profileFile;
9091            if (mProfileFd != null) {
9092                try {
9093                    mProfileFd.close();
9094                } catch (IOException e) {
9095                }
9096                mProfileFd = null;
9097            }
9098            mProfileFd = profileFd;
9099            mProfileType = 0;
9100            mAutoStopProfiler = autoStopProfiler;
9101        }
9102    }
9103
9104    @Override
9105    public void setAlwaysFinish(boolean enabled) {
9106        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9107                "setAlwaysFinish()");
9108
9109        Settings.Global.putInt(
9110                mContext.getContentResolver(),
9111                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9112
9113        synchronized (this) {
9114            mAlwaysFinishActivities = enabled;
9115        }
9116    }
9117
9118    @Override
9119    public void setActivityController(IActivityController controller) {
9120        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9121                "setActivityController()");
9122        synchronized (this) {
9123            mController = controller;
9124            Watchdog.getInstance().setActivityController(controller);
9125        }
9126    }
9127
9128    @Override
9129    public void setUserIsMonkey(boolean userIsMonkey) {
9130        synchronized (this) {
9131            synchronized (mPidsSelfLocked) {
9132                final int callingPid = Binder.getCallingPid();
9133                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9134                if (precessRecord == null) {
9135                    throw new SecurityException("Unknown process: " + callingPid);
9136                }
9137                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9138                    throw new SecurityException("Only an instrumentation process "
9139                            + "with a UiAutomation can call setUserIsMonkey");
9140                }
9141            }
9142            mUserIsMonkey = userIsMonkey;
9143        }
9144    }
9145
9146    @Override
9147    public boolean isUserAMonkey() {
9148        synchronized (this) {
9149            // If there is a controller also implies the user is a monkey.
9150            return (mUserIsMonkey || mController != null);
9151        }
9152    }
9153
9154    public void requestBugReport() {
9155        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9156        SystemProperties.set("ctl.start", "bugreport");
9157    }
9158
9159    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9160        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9161    }
9162
9163    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9164        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9165            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9166        }
9167        return KEY_DISPATCHING_TIMEOUT;
9168    }
9169
9170    @Override
9171    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9172        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9173                != PackageManager.PERMISSION_GRANTED) {
9174            throw new SecurityException("Requires permission "
9175                    + android.Manifest.permission.FILTER_EVENTS);
9176        }
9177        ProcessRecord proc;
9178        long timeout;
9179        synchronized (this) {
9180            synchronized (mPidsSelfLocked) {
9181                proc = mPidsSelfLocked.get(pid);
9182            }
9183            timeout = getInputDispatchingTimeoutLocked(proc);
9184        }
9185
9186        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9187            return -1;
9188        }
9189
9190        return timeout;
9191    }
9192
9193    /**
9194     * Handle input dispatching timeouts.
9195     * Returns whether input dispatching should be aborted or not.
9196     */
9197    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9198            final ActivityRecord activity, final ActivityRecord parent,
9199            final boolean aboveSystem, String reason) {
9200        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9201                != PackageManager.PERMISSION_GRANTED) {
9202            throw new SecurityException("Requires permission "
9203                    + android.Manifest.permission.FILTER_EVENTS);
9204        }
9205
9206        final String annotation;
9207        if (reason == null) {
9208            annotation = "Input dispatching timed out";
9209        } else {
9210            annotation = "Input dispatching timed out (" + reason + ")";
9211        }
9212
9213        if (proc != null) {
9214            synchronized (this) {
9215                if (proc.debugging) {
9216                    return false;
9217                }
9218
9219                if (mDidDexOpt) {
9220                    // Give more time since we were dexopting.
9221                    mDidDexOpt = false;
9222                    return false;
9223                }
9224
9225                if (proc.instrumentationClass != null) {
9226                    Bundle info = new Bundle();
9227                    info.putString("shortMsg", "keyDispatchingTimedOut");
9228                    info.putString("longMsg", annotation);
9229                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9230                    return true;
9231                }
9232            }
9233            mHandler.post(new Runnable() {
9234                @Override
9235                public void run() {
9236                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9237                }
9238            });
9239        }
9240
9241        return true;
9242    }
9243
9244    public Bundle getAssistContextExtras(int requestType) {
9245        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9246                "getAssistContextExtras()");
9247        PendingAssistExtras pae;
9248        Bundle extras = new Bundle();
9249        synchronized (this) {
9250            ActivityRecord activity = getFocusedStack().mResumedActivity;
9251            if (activity == null) {
9252                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9253                return null;
9254            }
9255            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9256            if (activity.app == null || activity.app.thread == null) {
9257                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9258                return extras;
9259            }
9260            if (activity.app.pid == Binder.getCallingPid()) {
9261                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9262                return extras;
9263            }
9264            pae = new PendingAssistExtras(activity);
9265            try {
9266                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9267                        requestType);
9268                mPendingAssistExtras.add(pae);
9269                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9270            } catch (RemoteException e) {
9271                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9272                return extras;
9273            }
9274        }
9275        synchronized (pae) {
9276            while (!pae.haveResult) {
9277                try {
9278                    pae.wait();
9279                } catch (InterruptedException e) {
9280                }
9281            }
9282            if (pae.result != null) {
9283                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9284            }
9285        }
9286        synchronized (this) {
9287            mPendingAssistExtras.remove(pae);
9288            mHandler.removeCallbacks(pae);
9289        }
9290        return extras;
9291    }
9292
9293    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9294        PendingAssistExtras pae = (PendingAssistExtras)token;
9295        synchronized (pae) {
9296            pae.result = extras;
9297            pae.haveResult = true;
9298            pae.notifyAll();
9299        }
9300    }
9301
9302    public void registerProcessObserver(IProcessObserver observer) {
9303        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9304                "registerProcessObserver()");
9305        synchronized (this) {
9306            mProcessObservers.register(observer);
9307        }
9308    }
9309
9310    @Override
9311    public void unregisterProcessObserver(IProcessObserver observer) {
9312        synchronized (this) {
9313            mProcessObservers.unregister(observer);
9314        }
9315    }
9316
9317    @Override
9318    public boolean convertFromTranslucent(IBinder token) {
9319        final long origId = Binder.clearCallingIdentity();
9320        try {
9321            synchronized (this) {
9322                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9323                if (r == null) {
9324                    return false;
9325                }
9326                if (r.changeWindowTranslucency(true)) {
9327                    mWindowManager.setAppFullscreen(token, true);
9328                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9329                    return true;
9330                }
9331                return false;
9332            }
9333        } finally {
9334            Binder.restoreCallingIdentity(origId);
9335        }
9336    }
9337
9338    @Override
9339    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9340        final long origId = Binder.clearCallingIdentity();
9341        try {
9342            synchronized (this) {
9343                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9344                if (r == null) {
9345                    return false;
9346                }
9347                if (r.changeWindowTranslucency(false)) {
9348                    r.task.stack.convertToTranslucent(r, options);
9349                    mWindowManager.setAppFullscreen(token, false);
9350                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9351                    return true;
9352                }
9353                return false;
9354            }
9355        } finally {
9356            Binder.restoreCallingIdentity(origId);
9357        }
9358    }
9359
9360    @Override
9361    public ActivityOptions getActivityOptions(IBinder token) {
9362        final long origId = Binder.clearCallingIdentity();
9363        try {
9364            synchronized (this) {
9365                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9366                if (r != null) {
9367                    final ActivityOptions activityOptions = r.pendingOptions;
9368                    r.pendingOptions = null;
9369                    return activityOptions;
9370                }
9371                return null;
9372            }
9373        } finally {
9374            Binder.restoreCallingIdentity(origId);
9375        }
9376    }
9377
9378    @Override
9379    public void setImmersive(IBinder token, boolean immersive) {
9380        synchronized(this) {
9381            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9382            if (r == null) {
9383                throw new IllegalArgumentException();
9384            }
9385            r.immersive = immersive;
9386
9387            // update associated state if we're frontmost
9388            if (r == mFocusedActivity) {
9389                if (DEBUG_IMMERSIVE) {
9390                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9391                }
9392                applyUpdateLockStateLocked(r);
9393            }
9394        }
9395    }
9396
9397    @Override
9398    public boolean isImmersive(IBinder token) {
9399        synchronized (this) {
9400            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9401            if (r == null) {
9402                throw new IllegalArgumentException();
9403            }
9404            return r.immersive;
9405        }
9406    }
9407
9408    public boolean isTopActivityImmersive() {
9409        enforceNotIsolatedCaller("startActivity");
9410        synchronized (this) {
9411            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9412            return (r != null) ? r.immersive : false;
9413        }
9414    }
9415
9416    public final void enterSafeMode() {
9417        synchronized(this) {
9418            // It only makes sense to do this before the system is ready
9419            // and started launching other packages.
9420            if (!mSystemReady) {
9421                try {
9422                    AppGlobals.getPackageManager().enterSafeMode();
9423                } catch (RemoteException e) {
9424                }
9425            }
9426
9427            mSafeMode = true;
9428        }
9429    }
9430
9431    public final void showSafeModeOverlay() {
9432        View v = LayoutInflater.from(mContext).inflate(
9433                com.android.internal.R.layout.safe_mode, null);
9434        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9435        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9436        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9437        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9438        lp.gravity = Gravity.BOTTOM | Gravity.START;
9439        lp.format = v.getBackground().getOpacity();
9440        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9441                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9442        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9443        ((WindowManager)mContext.getSystemService(
9444                Context.WINDOW_SERVICE)).addView(v, lp);
9445    }
9446
9447    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9448        if (!(sender instanceof PendingIntentRecord)) {
9449            return;
9450        }
9451        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9452        synchronized (stats) {
9453            if (mBatteryStatsService.isOnBattery()) {
9454                mBatteryStatsService.enforceCallingPermission();
9455                PendingIntentRecord rec = (PendingIntentRecord)sender;
9456                int MY_UID = Binder.getCallingUid();
9457                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9458                BatteryStatsImpl.Uid.Pkg pkg =
9459                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9460                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9461                pkg.incWakeupsLocked();
9462            }
9463        }
9464    }
9465
9466    public boolean killPids(int[] pids, String pReason, boolean secure) {
9467        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9468            throw new SecurityException("killPids only available to the system");
9469        }
9470        String reason = (pReason == null) ? "Unknown" : pReason;
9471        // XXX Note: don't acquire main activity lock here, because the window
9472        // manager calls in with its locks held.
9473
9474        boolean killed = false;
9475        synchronized (mPidsSelfLocked) {
9476            int[] types = new int[pids.length];
9477            int worstType = 0;
9478            for (int i=0; i<pids.length; i++) {
9479                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9480                if (proc != null) {
9481                    int type = proc.setAdj;
9482                    types[i] = type;
9483                    if (type > worstType) {
9484                        worstType = type;
9485                    }
9486                }
9487            }
9488
9489            // If the worst oom_adj is somewhere in the cached proc LRU range,
9490            // then constrain it so we will kill all cached procs.
9491            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9492                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9493                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9494            }
9495
9496            // If this is not a secure call, don't let it kill processes that
9497            // are important.
9498            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9499                worstType = ProcessList.SERVICE_ADJ;
9500            }
9501
9502            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9503            for (int i=0; i<pids.length; i++) {
9504                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9505                if (proc == null) {
9506                    continue;
9507                }
9508                int adj = proc.setAdj;
9509                if (adj >= worstType && !proc.killedByAm) {
9510                    killUnneededProcessLocked(proc, reason);
9511                    killed = true;
9512                }
9513            }
9514        }
9515        return killed;
9516    }
9517
9518    @Override
9519    public void killUid(int uid, String reason) {
9520        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9521            throw new SecurityException("killUid only available to the system");
9522        }
9523        synchronized (this) {
9524            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9525                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9526                    reason != null ? reason : "kill uid");
9527        }
9528    }
9529
9530    @Override
9531    public boolean killProcessesBelowForeground(String reason) {
9532        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9533            throw new SecurityException("killProcessesBelowForeground() only available to system");
9534        }
9535
9536        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9537    }
9538
9539    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9540        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9541            throw new SecurityException("killProcessesBelowAdj() only available to system");
9542        }
9543
9544        boolean killed = false;
9545        synchronized (mPidsSelfLocked) {
9546            final int size = mPidsSelfLocked.size();
9547            for (int i = 0; i < size; i++) {
9548                final int pid = mPidsSelfLocked.keyAt(i);
9549                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9550                if (proc == null) continue;
9551
9552                final int adj = proc.setAdj;
9553                if (adj > belowAdj && !proc.killedByAm) {
9554                    killUnneededProcessLocked(proc, reason);
9555                    killed = true;
9556                }
9557            }
9558        }
9559        return killed;
9560    }
9561
9562    @Override
9563    public void hang(final IBinder who, boolean allowRestart) {
9564        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9565                != PackageManager.PERMISSION_GRANTED) {
9566            throw new SecurityException("Requires permission "
9567                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9568        }
9569
9570        final IBinder.DeathRecipient death = new DeathRecipient() {
9571            @Override
9572            public void binderDied() {
9573                synchronized (this) {
9574                    notifyAll();
9575                }
9576            }
9577        };
9578
9579        try {
9580            who.linkToDeath(death, 0);
9581        } catch (RemoteException e) {
9582            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9583            return;
9584        }
9585
9586        synchronized (this) {
9587            Watchdog.getInstance().setAllowRestart(allowRestart);
9588            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9589            synchronized (death) {
9590                while (who.isBinderAlive()) {
9591                    try {
9592                        death.wait();
9593                    } catch (InterruptedException e) {
9594                    }
9595                }
9596            }
9597            Watchdog.getInstance().setAllowRestart(true);
9598        }
9599    }
9600
9601    @Override
9602    public void restart() {
9603        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9604                != PackageManager.PERMISSION_GRANTED) {
9605            throw new SecurityException("Requires permission "
9606                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9607        }
9608
9609        Log.i(TAG, "Sending shutdown broadcast...");
9610
9611        BroadcastReceiver br = new BroadcastReceiver() {
9612            @Override public void onReceive(Context context, Intent intent) {
9613                // Now the broadcast is done, finish up the low-level shutdown.
9614                Log.i(TAG, "Shutting down activity manager...");
9615                shutdown(10000);
9616                Log.i(TAG, "Shutdown complete, restarting!");
9617                Process.killProcess(Process.myPid());
9618                System.exit(10);
9619            }
9620        };
9621
9622        // First send the high-level shut down broadcast.
9623        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9624        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9625        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9626        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9627        mContext.sendOrderedBroadcastAsUser(intent,
9628                UserHandle.ALL, null, br, mHandler, 0, null, null);
9629        */
9630        br.onReceive(mContext, intent);
9631    }
9632
9633    private long getLowRamTimeSinceIdle(long now) {
9634        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9635    }
9636
9637    @Override
9638    public void performIdleMaintenance() {
9639        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9640                != PackageManager.PERMISSION_GRANTED) {
9641            throw new SecurityException("Requires permission "
9642                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9643        }
9644
9645        synchronized (this) {
9646            final long now = SystemClock.uptimeMillis();
9647            final long timeSinceLastIdle = now - mLastIdleTime;
9648            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9649            mLastIdleTime = now;
9650            mLowRamTimeSinceLastIdle = 0;
9651            if (mLowRamStartTime != 0) {
9652                mLowRamStartTime = now;
9653            }
9654
9655            StringBuilder sb = new StringBuilder(128);
9656            sb.append("Idle maintenance over ");
9657            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9658            sb.append(" low RAM for ");
9659            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9660            Slog.i(TAG, sb.toString());
9661
9662            // If at least 1/3 of our time since the last idle period has been spent
9663            // with RAM low, then we want to kill processes.
9664            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9665
9666            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9667                ProcessRecord proc = mLruProcesses.get(i);
9668                if (proc.notCachedSinceIdle) {
9669                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9670                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9671                        if (doKilling && proc.initialIdlePss != 0
9672                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9673                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9674                                    + " from " + proc.initialIdlePss + ")");
9675                        }
9676                    }
9677                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9678                    proc.notCachedSinceIdle = true;
9679                    proc.initialIdlePss = 0;
9680                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9681                            isSleeping(), now);
9682                }
9683            }
9684
9685            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9686            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9687        }
9688    }
9689
9690    private void retrieveSettings() {
9691        final ContentResolver resolver = mContext.getContentResolver();
9692        String debugApp = Settings.Global.getString(
9693            resolver, Settings.Global.DEBUG_APP);
9694        boolean waitForDebugger = Settings.Global.getInt(
9695            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9696        boolean alwaysFinishActivities = Settings.Global.getInt(
9697            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9698        boolean forceRtl = Settings.Global.getInt(
9699                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9700        // Transfer any global setting for forcing RTL layout, into a System Property
9701        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9702
9703        Configuration configuration = new Configuration();
9704        Settings.System.getConfiguration(resolver, configuration);
9705        if (forceRtl) {
9706            // This will take care of setting the correct layout direction flags
9707            configuration.setLayoutDirection(configuration.locale);
9708        }
9709
9710        synchronized (this) {
9711            mDebugApp = mOrigDebugApp = debugApp;
9712            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9713            mAlwaysFinishActivities = alwaysFinishActivities;
9714            // This happens before any activities are started, so we can
9715            // change mConfiguration in-place.
9716            updateConfigurationLocked(configuration, null, false, true);
9717            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9718        }
9719    }
9720
9721    public boolean testIsSystemReady() {
9722        // no need to synchronize(this) just to read & return the value
9723        return mSystemReady;
9724    }
9725
9726    private static File getCalledPreBootReceiversFile() {
9727        File dataDir = Environment.getDataDirectory();
9728        File systemDir = new File(dataDir, "system");
9729        File fname = new File(systemDir, "called_pre_boots.dat");
9730        return fname;
9731    }
9732
9733    static final int LAST_DONE_VERSION = 10000;
9734
9735    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9736        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9737        File file = getCalledPreBootReceiversFile();
9738        FileInputStream fis = null;
9739        try {
9740            fis = new FileInputStream(file);
9741            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9742            int fvers = dis.readInt();
9743            if (fvers == LAST_DONE_VERSION) {
9744                String vers = dis.readUTF();
9745                String codename = dis.readUTF();
9746                String build = dis.readUTF();
9747                if (android.os.Build.VERSION.RELEASE.equals(vers)
9748                        && android.os.Build.VERSION.CODENAME.equals(codename)
9749                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9750                    int num = dis.readInt();
9751                    while (num > 0) {
9752                        num--;
9753                        String pkg = dis.readUTF();
9754                        String cls = dis.readUTF();
9755                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9756                    }
9757                }
9758            }
9759        } catch (FileNotFoundException e) {
9760        } catch (IOException e) {
9761            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9762        } finally {
9763            if (fis != null) {
9764                try {
9765                    fis.close();
9766                } catch (IOException e) {
9767                }
9768            }
9769        }
9770        return lastDoneReceivers;
9771    }
9772
9773    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9774        File file = getCalledPreBootReceiversFile();
9775        FileOutputStream fos = null;
9776        DataOutputStream dos = null;
9777        try {
9778            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9779            fos = new FileOutputStream(file);
9780            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9781            dos.writeInt(LAST_DONE_VERSION);
9782            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9783            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9784            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9785            dos.writeInt(list.size());
9786            for (int i=0; i<list.size(); i++) {
9787                dos.writeUTF(list.get(i).getPackageName());
9788                dos.writeUTF(list.get(i).getClassName());
9789            }
9790        } catch (IOException e) {
9791            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9792            file.delete();
9793        } finally {
9794            FileUtils.sync(fos);
9795            if (dos != null) {
9796                try {
9797                    dos.close();
9798                } catch (IOException e) {
9799                    // TODO Auto-generated catch block
9800                    e.printStackTrace();
9801                }
9802            }
9803        }
9804    }
9805
9806    public void systemReady(final Runnable goingCallback) {
9807        synchronized(this) {
9808            if (mSystemReady) {
9809                if (goingCallback != null) goingCallback.run();
9810                return;
9811            }
9812
9813            if (mRecentTasks == null) {
9814                mRecentTasks = mTaskPersister.restoreTasksLocked();
9815                if (!mRecentTasks.isEmpty()) {
9816                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9817                }
9818                mTaskPersister.startPersisting();
9819            }
9820
9821            // Check to see if there are any update receivers to run.
9822            if (!mDidUpdate) {
9823                if (mWaitingUpdate) {
9824                    return;
9825                }
9826                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9827                List<ResolveInfo> ris = null;
9828                try {
9829                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9830                            intent, null, 0, 0);
9831                } catch (RemoteException e) {
9832                }
9833                if (ris != null) {
9834                    for (int i=ris.size()-1; i>=0; i--) {
9835                        if ((ris.get(i).activityInfo.applicationInfo.flags
9836                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9837                            ris.remove(i);
9838                        }
9839                    }
9840                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9841
9842                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9843
9844                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9845                    for (int i=0; i<ris.size(); i++) {
9846                        ActivityInfo ai = ris.get(i).activityInfo;
9847                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9848                        if (lastDoneReceivers.contains(comp)) {
9849                            // We already did the pre boot receiver for this app with the current
9850                            // platform version, so don't do it again...
9851                            ris.remove(i);
9852                            i--;
9853                            // ...however, do keep it as one that has been done, so we don't
9854                            // forget about it when rewriting the file of last done receivers.
9855                            doneReceivers.add(comp);
9856                        }
9857                    }
9858
9859                    final int[] users = getUsersLocked();
9860                    for (int i=0; i<ris.size(); i++) {
9861                        ActivityInfo ai = ris.get(i).activityInfo;
9862                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9863                        doneReceivers.add(comp);
9864                        intent.setComponent(comp);
9865                        for (int j=0; j<users.length; j++) {
9866                            IIntentReceiver finisher = null;
9867                            if (i == ris.size()-1 && j == users.length-1) {
9868                                finisher = new IIntentReceiver.Stub() {
9869                                    public void performReceive(Intent intent, int resultCode,
9870                                            String data, Bundle extras, boolean ordered,
9871                                            boolean sticky, int sendingUser) {
9872                                        // The raw IIntentReceiver interface is called
9873                                        // with the AM lock held, so redispatch to
9874                                        // execute our code without the lock.
9875                                        mHandler.post(new Runnable() {
9876                                            public void run() {
9877                                                synchronized (ActivityManagerService.this) {
9878                                                    mDidUpdate = true;
9879                                                }
9880                                                writeLastDonePreBootReceivers(doneReceivers);
9881                                                showBootMessage(mContext.getText(
9882                                                        R.string.android_upgrading_complete),
9883                                                        false);
9884                                                systemReady(goingCallback);
9885                                            }
9886                                        });
9887                                    }
9888                                };
9889                            }
9890                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9891                                    + " for user " + users[j]);
9892                            broadcastIntentLocked(null, null, intent, null, finisher,
9893                                    0, null, null, null, AppOpsManager.OP_NONE,
9894                                    true, false, MY_PID, Process.SYSTEM_UID,
9895                                    users[j]);
9896                            if (finisher != null) {
9897                                mWaitingUpdate = true;
9898                            }
9899                        }
9900                    }
9901                }
9902                if (mWaitingUpdate) {
9903                    return;
9904                }
9905                mDidUpdate = true;
9906            }
9907
9908            mAppOpsService.systemReady();
9909            mUsageStatsService.systemReady();
9910            mSystemReady = true;
9911        }
9912
9913        ArrayList<ProcessRecord> procsToKill = null;
9914        synchronized(mPidsSelfLocked) {
9915            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9916                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9917                if (!isAllowedWhileBooting(proc.info)){
9918                    if (procsToKill == null) {
9919                        procsToKill = new ArrayList<ProcessRecord>();
9920                    }
9921                    procsToKill.add(proc);
9922                }
9923            }
9924        }
9925
9926        synchronized(this) {
9927            if (procsToKill != null) {
9928                for (int i=procsToKill.size()-1; i>=0; i--) {
9929                    ProcessRecord proc = procsToKill.get(i);
9930                    Slog.i(TAG, "Removing system update proc: " + proc);
9931                    removeProcessLocked(proc, true, false, "system update done");
9932                }
9933            }
9934
9935            // Now that we have cleaned up any update processes, we
9936            // are ready to start launching real processes and know that
9937            // we won't trample on them any more.
9938            mProcessesReady = true;
9939        }
9940
9941        Slog.i(TAG, "System now ready");
9942        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9943            SystemClock.uptimeMillis());
9944
9945        synchronized(this) {
9946            // Make sure we have no pre-ready processes sitting around.
9947
9948            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9949                ResolveInfo ri = mContext.getPackageManager()
9950                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9951                                STOCK_PM_FLAGS);
9952                CharSequence errorMsg = null;
9953                if (ri != null) {
9954                    ActivityInfo ai = ri.activityInfo;
9955                    ApplicationInfo app = ai.applicationInfo;
9956                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9957                        mTopAction = Intent.ACTION_FACTORY_TEST;
9958                        mTopData = null;
9959                        mTopComponent = new ComponentName(app.packageName,
9960                                ai.name);
9961                    } else {
9962                        errorMsg = mContext.getResources().getText(
9963                                com.android.internal.R.string.factorytest_not_system);
9964                    }
9965                } else {
9966                    errorMsg = mContext.getResources().getText(
9967                            com.android.internal.R.string.factorytest_no_action);
9968                }
9969                if (errorMsg != null) {
9970                    mTopAction = null;
9971                    mTopData = null;
9972                    mTopComponent = null;
9973                    Message msg = Message.obtain();
9974                    msg.what = SHOW_FACTORY_ERROR_MSG;
9975                    msg.getData().putCharSequence("msg", errorMsg);
9976                    mHandler.sendMessage(msg);
9977                }
9978            }
9979        }
9980
9981        retrieveSettings();
9982
9983        synchronized (this) {
9984            readGrantedUriPermissionsLocked();
9985        }
9986
9987        if (goingCallback != null) goingCallback.run();
9988
9989        mSystemServiceManager.startUser(mCurrentUserId);
9990
9991        synchronized (this) {
9992            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9993                try {
9994                    List apps = AppGlobals.getPackageManager().
9995                        getPersistentApplications(STOCK_PM_FLAGS);
9996                    if (apps != null) {
9997                        int N = apps.size();
9998                        int i;
9999                        for (i=0; i<N; i++) {
10000                            ApplicationInfo info
10001                                = (ApplicationInfo)apps.get(i);
10002                            if (info != null &&
10003                                    !info.packageName.equals("android")) {
10004                                addAppLocked(info, false, null /* ABI override */);
10005                            }
10006                        }
10007                    }
10008                } catch (RemoteException ex) {
10009                    // pm is in same process, this will never happen.
10010                }
10011            }
10012
10013            // Start up initial activity.
10014            mBooting = true;
10015
10016            try {
10017                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10018                    Message msg = Message.obtain();
10019                    msg.what = SHOW_UID_ERROR_MSG;
10020                    mHandler.sendMessage(msg);
10021                }
10022            } catch (RemoteException e) {
10023            }
10024
10025            long ident = Binder.clearCallingIdentity();
10026            try {
10027                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10028                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10029                        | Intent.FLAG_RECEIVER_FOREGROUND);
10030                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10031                broadcastIntentLocked(null, null, intent,
10032                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10033                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10034                intent = new Intent(Intent.ACTION_USER_STARTING);
10035                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10036                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10037                broadcastIntentLocked(null, null, intent,
10038                        null, new IIntentReceiver.Stub() {
10039                            @Override
10040                            public void performReceive(Intent intent, int resultCode, String data,
10041                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10042                                    throws RemoteException {
10043                            }
10044                        }, 0, null, null,
10045                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10046                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10047            } catch (Throwable t) {
10048                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10049            } finally {
10050                Binder.restoreCallingIdentity(ident);
10051            }
10052            mStackSupervisor.resumeTopActivitiesLocked();
10053            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10054        }
10055    }
10056
10057    private boolean makeAppCrashingLocked(ProcessRecord app,
10058            String shortMsg, String longMsg, String stackTrace) {
10059        app.crashing = true;
10060        app.crashingReport = generateProcessError(app,
10061                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10062        startAppProblemLocked(app);
10063        app.stopFreezingAllLocked();
10064        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10065    }
10066
10067    private void makeAppNotRespondingLocked(ProcessRecord app,
10068            String activity, String shortMsg, String longMsg) {
10069        app.notResponding = true;
10070        app.notRespondingReport = generateProcessError(app,
10071                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10072                activity, shortMsg, longMsg, null);
10073        startAppProblemLocked(app);
10074        app.stopFreezingAllLocked();
10075    }
10076
10077    /**
10078     * Generate a process error record, suitable for attachment to a ProcessRecord.
10079     *
10080     * @param app The ProcessRecord in which the error occurred.
10081     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10082     *                      ActivityManager.AppErrorStateInfo
10083     * @param activity The activity associated with the crash, if known.
10084     * @param shortMsg Short message describing the crash.
10085     * @param longMsg Long message describing the crash.
10086     * @param stackTrace Full crash stack trace, may be null.
10087     *
10088     * @return Returns a fully-formed AppErrorStateInfo record.
10089     */
10090    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10091            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10092        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10093
10094        report.condition = condition;
10095        report.processName = app.processName;
10096        report.pid = app.pid;
10097        report.uid = app.info.uid;
10098        report.tag = activity;
10099        report.shortMsg = shortMsg;
10100        report.longMsg = longMsg;
10101        report.stackTrace = stackTrace;
10102
10103        return report;
10104    }
10105
10106    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10107        synchronized (this) {
10108            app.crashing = false;
10109            app.crashingReport = null;
10110            app.notResponding = false;
10111            app.notRespondingReport = null;
10112            if (app.anrDialog == fromDialog) {
10113                app.anrDialog = null;
10114            }
10115            if (app.waitDialog == fromDialog) {
10116                app.waitDialog = null;
10117            }
10118            if (app.pid > 0 && app.pid != MY_PID) {
10119                handleAppCrashLocked(app, null, null, null);
10120                killUnneededProcessLocked(app, "user request after error");
10121            }
10122        }
10123    }
10124
10125    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10126            String stackTrace) {
10127        long now = SystemClock.uptimeMillis();
10128
10129        Long crashTime;
10130        if (!app.isolated) {
10131            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10132        } else {
10133            crashTime = null;
10134        }
10135        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10136            // This process loses!
10137            Slog.w(TAG, "Process " + app.info.processName
10138                    + " has crashed too many times: killing!");
10139            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10140                    app.userId, app.info.processName, app.uid);
10141            mStackSupervisor.handleAppCrashLocked(app);
10142            if (!app.persistent) {
10143                // We don't want to start this process again until the user
10144                // explicitly does so...  but for persistent process, we really
10145                // need to keep it running.  If a persistent process is actually
10146                // repeatedly crashing, then badness for everyone.
10147                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10148                        app.info.processName);
10149                if (!app.isolated) {
10150                    // XXX We don't have a way to mark isolated processes
10151                    // as bad, since they don't have a peristent identity.
10152                    mBadProcesses.put(app.info.processName, app.uid,
10153                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10154                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10155                }
10156                app.bad = true;
10157                app.removed = true;
10158                // Don't let services in this process be restarted and potentially
10159                // annoy the user repeatedly.  Unless it is persistent, since those
10160                // processes run critical code.
10161                removeProcessLocked(app, false, false, "crash");
10162                mStackSupervisor.resumeTopActivitiesLocked();
10163                return false;
10164            }
10165            mStackSupervisor.resumeTopActivitiesLocked();
10166        } else {
10167            mStackSupervisor.finishTopRunningActivityLocked(app);
10168        }
10169
10170        // Bump up the crash count of any services currently running in the proc.
10171        for (int i=app.services.size()-1; i>=0; i--) {
10172            // Any services running in the application need to be placed
10173            // back in the pending list.
10174            ServiceRecord sr = app.services.valueAt(i);
10175            sr.crashCount++;
10176        }
10177
10178        // If the crashing process is what we consider to be the "home process" and it has been
10179        // replaced by a third-party app, clear the package preferred activities from packages
10180        // with a home activity running in the process to prevent a repeatedly crashing app
10181        // from blocking the user to manually clear the list.
10182        final ArrayList<ActivityRecord> activities = app.activities;
10183        if (app == mHomeProcess && activities.size() > 0
10184                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10185            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10186                final ActivityRecord r = activities.get(activityNdx);
10187                if (r.isHomeActivity()) {
10188                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10189                    try {
10190                        ActivityThread.getPackageManager()
10191                                .clearPackagePreferredActivities(r.packageName);
10192                    } catch (RemoteException c) {
10193                        // pm is in same process, this will never happen.
10194                    }
10195                }
10196            }
10197        }
10198
10199        if (!app.isolated) {
10200            // XXX Can't keep track of crash times for isolated processes,
10201            // because they don't have a perisistent identity.
10202            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10203        }
10204
10205        return true;
10206    }
10207
10208    void startAppProblemLocked(ProcessRecord app) {
10209        if (app.userId == mCurrentUserId) {
10210            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10211                    mContext, app.info.packageName, app.info.flags);
10212        } else {
10213            // If this app is not running under the current user, then we
10214            // can't give it a report button because that would require
10215            // launching the report UI under a different user.
10216            app.errorReportReceiver = null;
10217        }
10218        skipCurrentReceiverLocked(app);
10219    }
10220
10221    void skipCurrentReceiverLocked(ProcessRecord app) {
10222        for (BroadcastQueue queue : mBroadcastQueues) {
10223            queue.skipCurrentReceiverLocked(app);
10224        }
10225    }
10226
10227    /**
10228     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10229     * The application process will exit immediately after this call returns.
10230     * @param app object of the crashing app, null for the system server
10231     * @param crashInfo describing the exception
10232     */
10233    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10234        ProcessRecord r = findAppProcess(app, "Crash");
10235        final String processName = app == null ? "system_server"
10236                : (r == null ? "unknown" : r.processName);
10237
10238        handleApplicationCrashInner("crash", r, processName, crashInfo);
10239    }
10240
10241    /* Native crash reporting uses this inner version because it needs to be somewhat
10242     * decoupled from the AM-managed cleanup lifecycle
10243     */
10244    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10245            ApplicationErrorReport.CrashInfo crashInfo) {
10246        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10247                UserHandle.getUserId(Binder.getCallingUid()), processName,
10248                r == null ? -1 : r.info.flags,
10249                crashInfo.exceptionClassName,
10250                crashInfo.exceptionMessage,
10251                crashInfo.throwFileName,
10252                crashInfo.throwLineNumber);
10253
10254        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10255
10256        crashApplication(r, crashInfo);
10257    }
10258
10259    public void handleApplicationStrictModeViolation(
10260            IBinder app,
10261            int violationMask,
10262            StrictMode.ViolationInfo info) {
10263        ProcessRecord r = findAppProcess(app, "StrictMode");
10264        if (r == null) {
10265            return;
10266        }
10267
10268        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10269            Integer stackFingerprint = info.hashCode();
10270            boolean logIt = true;
10271            synchronized (mAlreadyLoggedViolatedStacks) {
10272                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10273                    logIt = false;
10274                    // TODO: sub-sample into EventLog for these, with
10275                    // the info.durationMillis?  Then we'd get
10276                    // the relative pain numbers, without logging all
10277                    // the stack traces repeatedly.  We'd want to do
10278                    // likewise in the client code, which also does
10279                    // dup suppression, before the Binder call.
10280                } else {
10281                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10282                        mAlreadyLoggedViolatedStacks.clear();
10283                    }
10284                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10285                }
10286            }
10287            if (logIt) {
10288                logStrictModeViolationToDropBox(r, info);
10289            }
10290        }
10291
10292        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10293            AppErrorResult result = new AppErrorResult();
10294            synchronized (this) {
10295                final long origId = Binder.clearCallingIdentity();
10296
10297                Message msg = Message.obtain();
10298                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10299                HashMap<String, Object> data = new HashMap<String, Object>();
10300                data.put("result", result);
10301                data.put("app", r);
10302                data.put("violationMask", violationMask);
10303                data.put("info", info);
10304                msg.obj = data;
10305                mHandler.sendMessage(msg);
10306
10307                Binder.restoreCallingIdentity(origId);
10308            }
10309            int res = result.get();
10310            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10311        }
10312    }
10313
10314    // Depending on the policy in effect, there could be a bunch of
10315    // these in quick succession so we try to batch these together to
10316    // minimize disk writes, number of dropbox entries, and maximize
10317    // compression, by having more fewer, larger records.
10318    private void logStrictModeViolationToDropBox(
10319            ProcessRecord process,
10320            StrictMode.ViolationInfo info) {
10321        if (info == null) {
10322            return;
10323        }
10324        final boolean isSystemApp = process == null ||
10325                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10326                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10327        final String processName = process == null ? "unknown" : process.processName;
10328        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10329        final DropBoxManager dbox = (DropBoxManager)
10330                mContext.getSystemService(Context.DROPBOX_SERVICE);
10331
10332        // Exit early if the dropbox isn't configured to accept this report type.
10333        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10334
10335        boolean bufferWasEmpty;
10336        boolean needsFlush;
10337        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10338        synchronized (sb) {
10339            bufferWasEmpty = sb.length() == 0;
10340            appendDropBoxProcessHeaders(process, processName, sb);
10341            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10342            sb.append("System-App: ").append(isSystemApp).append("\n");
10343            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10344            if (info.violationNumThisLoop != 0) {
10345                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10346            }
10347            if (info.numAnimationsRunning != 0) {
10348                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10349            }
10350            if (info.broadcastIntentAction != null) {
10351                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10352            }
10353            if (info.durationMillis != -1) {
10354                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10355            }
10356            if (info.numInstances != -1) {
10357                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10358            }
10359            if (info.tags != null) {
10360                for (String tag : info.tags) {
10361                    sb.append("Span-Tag: ").append(tag).append("\n");
10362                }
10363            }
10364            sb.append("\n");
10365            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10366                sb.append(info.crashInfo.stackTrace);
10367            }
10368            sb.append("\n");
10369
10370            // Only buffer up to ~64k.  Various logging bits truncate
10371            // things at 128k.
10372            needsFlush = (sb.length() > 64 * 1024);
10373        }
10374
10375        // Flush immediately if the buffer's grown too large, or this
10376        // is a non-system app.  Non-system apps are isolated with a
10377        // different tag & policy and not batched.
10378        //
10379        // Batching is useful during internal testing with
10380        // StrictMode settings turned up high.  Without batching,
10381        // thousands of separate files could be created on boot.
10382        if (!isSystemApp || needsFlush) {
10383            new Thread("Error dump: " + dropboxTag) {
10384                @Override
10385                public void run() {
10386                    String report;
10387                    synchronized (sb) {
10388                        report = sb.toString();
10389                        sb.delete(0, sb.length());
10390                        sb.trimToSize();
10391                    }
10392                    if (report.length() != 0) {
10393                        dbox.addText(dropboxTag, report);
10394                    }
10395                }
10396            }.start();
10397            return;
10398        }
10399
10400        // System app batching:
10401        if (!bufferWasEmpty) {
10402            // An existing dropbox-writing thread is outstanding, so
10403            // we don't need to start it up.  The existing thread will
10404            // catch the buffer appends we just did.
10405            return;
10406        }
10407
10408        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10409        // (After this point, we shouldn't access AMS internal data structures.)
10410        new Thread("Error dump: " + dropboxTag) {
10411            @Override
10412            public void run() {
10413                // 5 second sleep to let stacks arrive and be batched together
10414                try {
10415                    Thread.sleep(5000);  // 5 seconds
10416                } catch (InterruptedException e) {}
10417
10418                String errorReport;
10419                synchronized (mStrictModeBuffer) {
10420                    errorReport = mStrictModeBuffer.toString();
10421                    if (errorReport.length() == 0) {
10422                        return;
10423                    }
10424                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10425                    mStrictModeBuffer.trimToSize();
10426                }
10427                dbox.addText(dropboxTag, errorReport);
10428            }
10429        }.start();
10430    }
10431
10432    /**
10433     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10434     * @param app object of the crashing app, null for the system server
10435     * @param tag reported by the caller
10436     * @param crashInfo describing the context of the error
10437     * @return true if the process should exit immediately (WTF is fatal)
10438     */
10439    public boolean handleApplicationWtf(IBinder app, String tag,
10440            ApplicationErrorReport.CrashInfo crashInfo) {
10441        ProcessRecord r = findAppProcess(app, "WTF");
10442        final String processName = app == null ? "system_server"
10443                : (r == null ? "unknown" : r.processName);
10444
10445        EventLog.writeEvent(EventLogTags.AM_WTF,
10446                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10447                processName,
10448                r == null ? -1 : r.info.flags,
10449                tag, crashInfo.exceptionMessage);
10450
10451        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10452
10453        if (r != null && r.pid != Process.myPid() &&
10454                Settings.Global.getInt(mContext.getContentResolver(),
10455                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10456            crashApplication(r, crashInfo);
10457            return true;
10458        } else {
10459            return false;
10460        }
10461    }
10462
10463    /**
10464     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10465     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10466     */
10467    private ProcessRecord findAppProcess(IBinder app, String reason) {
10468        if (app == null) {
10469            return null;
10470        }
10471
10472        synchronized (this) {
10473            final int NP = mProcessNames.getMap().size();
10474            for (int ip=0; ip<NP; ip++) {
10475                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10476                final int NA = apps.size();
10477                for (int ia=0; ia<NA; ia++) {
10478                    ProcessRecord p = apps.valueAt(ia);
10479                    if (p.thread != null && p.thread.asBinder() == app) {
10480                        return p;
10481                    }
10482                }
10483            }
10484
10485            Slog.w(TAG, "Can't find mystery application for " + reason
10486                    + " from pid=" + Binder.getCallingPid()
10487                    + " uid=" + Binder.getCallingUid() + ": " + app);
10488            return null;
10489        }
10490    }
10491
10492    /**
10493     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10494     * to append various headers to the dropbox log text.
10495     */
10496    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10497            StringBuilder sb) {
10498        // Watchdog thread ends up invoking this function (with
10499        // a null ProcessRecord) to add the stack file to dropbox.
10500        // Do not acquire a lock on this (am) in such cases, as it
10501        // could cause a potential deadlock, if and when watchdog
10502        // is invoked due to unavailability of lock on am and it
10503        // would prevent watchdog from killing system_server.
10504        if (process == null) {
10505            sb.append("Process: ").append(processName).append("\n");
10506            return;
10507        }
10508        // Note: ProcessRecord 'process' is guarded by the service
10509        // instance.  (notably process.pkgList, which could otherwise change
10510        // concurrently during execution of this method)
10511        synchronized (this) {
10512            sb.append("Process: ").append(processName).append("\n");
10513            int flags = process.info.flags;
10514            IPackageManager pm = AppGlobals.getPackageManager();
10515            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10516            for (int ip=0; ip<process.pkgList.size(); ip++) {
10517                String pkg = process.pkgList.keyAt(ip);
10518                sb.append("Package: ").append(pkg);
10519                try {
10520                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10521                    if (pi != null) {
10522                        sb.append(" v").append(pi.versionCode);
10523                        if (pi.versionName != null) {
10524                            sb.append(" (").append(pi.versionName).append(")");
10525                        }
10526                    }
10527                } catch (RemoteException e) {
10528                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10529                }
10530                sb.append("\n");
10531            }
10532        }
10533    }
10534
10535    private static String processClass(ProcessRecord process) {
10536        if (process == null || process.pid == MY_PID) {
10537            return "system_server";
10538        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10539            return "system_app";
10540        } else {
10541            return "data_app";
10542        }
10543    }
10544
10545    /**
10546     * Write a description of an error (crash, WTF, ANR) to the drop box.
10547     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10548     * @param process which caused the error, null means the system server
10549     * @param activity which triggered the error, null if unknown
10550     * @param parent activity related to the error, null if unknown
10551     * @param subject line related to the error, null if absent
10552     * @param report in long form describing the error, null if absent
10553     * @param logFile to include in the report, null if none
10554     * @param crashInfo giving an application stack trace, null if absent
10555     */
10556    public void addErrorToDropBox(String eventType,
10557            ProcessRecord process, String processName, ActivityRecord activity,
10558            ActivityRecord parent, String subject,
10559            final String report, final File logFile,
10560            final ApplicationErrorReport.CrashInfo crashInfo) {
10561        // NOTE -- this must never acquire the ActivityManagerService lock,
10562        // otherwise the watchdog may be prevented from resetting the system.
10563
10564        final String dropboxTag = processClass(process) + "_" + eventType;
10565        final DropBoxManager dbox = (DropBoxManager)
10566                mContext.getSystemService(Context.DROPBOX_SERVICE);
10567
10568        // Exit early if the dropbox isn't configured to accept this report type.
10569        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10570
10571        final StringBuilder sb = new StringBuilder(1024);
10572        appendDropBoxProcessHeaders(process, processName, sb);
10573        if (activity != null) {
10574            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10575        }
10576        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10577            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10578        }
10579        if (parent != null && parent != activity) {
10580            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10581        }
10582        if (subject != null) {
10583            sb.append("Subject: ").append(subject).append("\n");
10584        }
10585        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10586        if (Debug.isDebuggerConnected()) {
10587            sb.append("Debugger: Connected\n");
10588        }
10589        sb.append("\n");
10590
10591        // Do the rest in a worker thread to avoid blocking the caller on I/O
10592        // (After this point, we shouldn't access AMS internal data structures.)
10593        Thread worker = new Thread("Error dump: " + dropboxTag) {
10594            @Override
10595            public void run() {
10596                if (report != null) {
10597                    sb.append(report);
10598                }
10599                if (logFile != null) {
10600                    try {
10601                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10602                                    "\n\n[[TRUNCATED]]"));
10603                    } catch (IOException e) {
10604                        Slog.e(TAG, "Error reading " + logFile, e);
10605                    }
10606                }
10607                if (crashInfo != null && crashInfo.stackTrace != null) {
10608                    sb.append(crashInfo.stackTrace);
10609                }
10610
10611                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10612                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10613                if (lines > 0) {
10614                    sb.append("\n");
10615
10616                    // Merge several logcat streams, and take the last N lines
10617                    InputStreamReader input = null;
10618                    try {
10619                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10620                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10621                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10622
10623                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10624                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10625                        input = new InputStreamReader(logcat.getInputStream());
10626
10627                        int num;
10628                        char[] buf = new char[8192];
10629                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10630                    } catch (IOException e) {
10631                        Slog.e(TAG, "Error running logcat", e);
10632                    } finally {
10633                        if (input != null) try { input.close(); } catch (IOException e) {}
10634                    }
10635                }
10636
10637                dbox.addText(dropboxTag, sb.toString());
10638            }
10639        };
10640
10641        if (process == null) {
10642            // If process is null, we are being called from some internal code
10643            // and may be about to die -- run this synchronously.
10644            worker.run();
10645        } else {
10646            worker.start();
10647        }
10648    }
10649
10650    /**
10651     * Bring up the "unexpected error" dialog box for a crashing app.
10652     * Deal with edge cases (intercepts from instrumented applications,
10653     * ActivityController, error intent receivers, that sort of thing).
10654     * @param r the application crashing
10655     * @param crashInfo describing the failure
10656     */
10657    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10658        long timeMillis = System.currentTimeMillis();
10659        String shortMsg = crashInfo.exceptionClassName;
10660        String longMsg = crashInfo.exceptionMessage;
10661        String stackTrace = crashInfo.stackTrace;
10662        if (shortMsg != null && longMsg != null) {
10663            longMsg = shortMsg + ": " + longMsg;
10664        } else if (shortMsg != null) {
10665            longMsg = shortMsg;
10666        }
10667
10668        AppErrorResult result = new AppErrorResult();
10669        synchronized (this) {
10670            if (mController != null) {
10671                try {
10672                    String name = r != null ? r.processName : null;
10673                    int pid = r != null ? r.pid : Binder.getCallingPid();
10674                    if (!mController.appCrashed(name, pid,
10675                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10676                        Slog.w(TAG, "Force-killing crashed app " + name
10677                                + " at watcher's request");
10678                        Process.killProcess(pid);
10679                        return;
10680                    }
10681                } catch (RemoteException e) {
10682                    mController = null;
10683                    Watchdog.getInstance().setActivityController(null);
10684                }
10685            }
10686
10687            final long origId = Binder.clearCallingIdentity();
10688
10689            // If this process is running instrumentation, finish it.
10690            if (r != null && r.instrumentationClass != null) {
10691                Slog.w(TAG, "Error in app " + r.processName
10692                      + " running instrumentation " + r.instrumentationClass + ":");
10693                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10694                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10695                Bundle info = new Bundle();
10696                info.putString("shortMsg", shortMsg);
10697                info.putString("longMsg", longMsg);
10698                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10699                Binder.restoreCallingIdentity(origId);
10700                return;
10701            }
10702
10703            // If we can't identify the process or it's already exceeded its crash quota,
10704            // quit right away without showing a crash dialog.
10705            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10706                Binder.restoreCallingIdentity(origId);
10707                return;
10708            }
10709
10710            Message msg = Message.obtain();
10711            msg.what = SHOW_ERROR_MSG;
10712            HashMap data = new HashMap();
10713            data.put("result", result);
10714            data.put("app", r);
10715            msg.obj = data;
10716            mHandler.sendMessage(msg);
10717
10718            Binder.restoreCallingIdentity(origId);
10719        }
10720
10721        int res = result.get();
10722
10723        Intent appErrorIntent = null;
10724        synchronized (this) {
10725            if (r != null && !r.isolated) {
10726                // XXX Can't keep track of crash time for isolated processes,
10727                // since they don't have a persistent identity.
10728                mProcessCrashTimes.put(r.info.processName, r.uid,
10729                        SystemClock.uptimeMillis());
10730            }
10731            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10732                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10733            }
10734        }
10735
10736        if (appErrorIntent != null) {
10737            try {
10738                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10739            } catch (ActivityNotFoundException e) {
10740                Slog.w(TAG, "bug report receiver dissappeared", e);
10741            }
10742        }
10743    }
10744
10745    Intent createAppErrorIntentLocked(ProcessRecord r,
10746            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10747        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10748        if (report == null) {
10749            return null;
10750        }
10751        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10752        result.setComponent(r.errorReportReceiver);
10753        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10754        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10755        return result;
10756    }
10757
10758    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10759            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10760        if (r.errorReportReceiver == null) {
10761            return null;
10762        }
10763
10764        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10765            return null;
10766        }
10767
10768        ApplicationErrorReport report = new ApplicationErrorReport();
10769        report.packageName = r.info.packageName;
10770        report.installerPackageName = r.errorReportReceiver.getPackageName();
10771        report.processName = r.processName;
10772        report.time = timeMillis;
10773        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10774
10775        if (r.crashing || r.forceCrashReport) {
10776            report.type = ApplicationErrorReport.TYPE_CRASH;
10777            report.crashInfo = crashInfo;
10778        } else if (r.notResponding) {
10779            report.type = ApplicationErrorReport.TYPE_ANR;
10780            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10781
10782            report.anrInfo.activity = r.notRespondingReport.tag;
10783            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10784            report.anrInfo.info = r.notRespondingReport.longMsg;
10785        }
10786
10787        return report;
10788    }
10789
10790    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10791        enforceNotIsolatedCaller("getProcessesInErrorState");
10792        // assume our apps are happy - lazy create the list
10793        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10794
10795        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10796                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10797        int userId = UserHandle.getUserId(Binder.getCallingUid());
10798
10799        synchronized (this) {
10800
10801            // iterate across all processes
10802            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10803                ProcessRecord app = mLruProcesses.get(i);
10804                if (!allUsers && app.userId != userId) {
10805                    continue;
10806                }
10807                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10808                    // This one's in trouble, so we'll generate a report for it
10809                    // crashes are higher priority (in case there's a crash *and* an anr)
10810                    ActivityManager.ProcessErrorStateInfo report = null;
10811                    if (app.crashing) {
10812                        report = app.crashingReport;
10813                    } else if (app.notResponding) {
10814                        report = app.notRespondingReport;
10815                    }
10816
10817                    if (report != null) {
10818                        if (errList == null) {
10819                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10820                        }
10821                        errList.add(report);
10822                    } else {
10823                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10824                                " crashing = " + app.crashing +
10825                                " notResponding = " + app.notResponding);
10826                    }
10827                }
10828            }
10829        }
10830
10831        return errList;
10832    }
10833
10834    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10835        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10836            if (currApp != null) {
10837                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10838            }
10839            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10840        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10841            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10842        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10843            if (currApp != null) {
10844                currApp.lru = 0;
10845            }
10846            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10847        } else if (adj >= ProcessList.SERVICE_ADJ) {
10848            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10849        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10850            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10851        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10852            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10853        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10854            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10855        } else {
10856            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10857        }
10858    }
10859
10860    private void fillInProcMemInfo(ProcessRecord app,
10861            ActivityManager.RunningAppProcessInfo outInfo) {
10862        outInfo.pid = app.pid;
10863        outInfo.uid = app.info.uid;
10864        if (mHeavyWeightProcess == app) {
10865            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10866        }
10867        if (app.persistent) {
10868            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10869        }
10870        if (app.activities.size() > 0) {
10871            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10872        }
10873        outInfo.lastTrimLevel = app.trimMemoryLevel;
10874        int adj = app.curAdj;
10875        outInfo.importance = oomAdjToImportance(adj, outInfo);
10876        outInfo.importanceReasonCode = app.adjTypeCode;
10877        outInfo.processState = app.curProcState;
10878    }
10879
10880    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10881        enforceNotIsolatedCaller("getRunningAppProcesses");
10882        // Lazy instantiation of list
10883        List<ActivityManager.RunningAppProcessInfo> runList = null;
10884        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10885                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10886        int userId = UserHandle.getUserId(Binder.getCallingUid());
10887        synchronized (this) {
10888            // Iterate across all processes
10889            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10890                ProcessRecord app = mLruProcesses.get(i);
10891                if (!allUsers && app.userId != userId) {
10892                    continue;
10893                }
10894                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10895                    // Generate process state info for running application
10896                    ActivityManager.RunningAppProcessInfo currApp =
10897                        new ActivityManager.RunningAppProcessInfo(app.processName,
10898                                app.pid, app.getPackageList());
10899                    fillInProcMemInfo(app, currApp);
10900                    if (app.adjSource instanceof ProcessRecord) {
10901                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10902                        currApp.importanceReasonImportance = oomAdjToImportance(
10903                                app.adjSourceOom, null);
10904                    } else if (app.adjSource instanceof ActivityRecord) {
10905                        ActivityRecord r = (ActivityRecord)app.adjSource;
10906                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10907                    }
10908                    if (app.adjTarget instanceof ComponentName) {
10909                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10910                    }
10911                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10912                    //        + " lru=" + currApp.lru);
10913                    if (runList == null) {
10914                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10915                    }
10916                    runList.add(currApp);
10917                }
10918            }
10919        }
10920        return runList;
10921    }
10922
10923    public List<ApplicationInfo> getRunningExternalApplications() {
10924        enforceNotIsolatedCaller("getRunningExternalApplications");
10925        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10926        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10927        if (runningApps != null && runningApps.size() > 0) {
10928            Set<String> extList = new HashSet<String>();
10929            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10930                if (app.pkgList != null) {
10931                    for (String pkg : app.pkgList) {
10932                        extList.add(pkg);
10933                    }
10934                }
10935            }
10936            IPackageManager pm = AppGlobals.getPackageManager();
10937            for (String pkg : extList) {
10938                try {
10939                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10940                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10941                        retList.add(info);
10942                    }
10943                } catch (RemoteException e) {
10944                }
10945            }
10946        }
10947        return retList;
10948    }
10949
10950    @Override
10951    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10952        enforceNotIsolatedCaller("getMyMemoryState");
10953        synchronized (this) {
10954            ProcessRecord proc;
10955            synchronized (mPidsSelfLocked) {
10956                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10957            }
10958            fillInProcMemInfo(proc, outInfo);
10959        }
10960    }
10961
10962    @Override
10963    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10964        if (checkCallingPermission(android.Manifest.permission.DUMP)
10965                != PackageManager.PERMISSION_GRANTED) {
10966            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10967                    + Binder.getCallingPid()
10968                    + ", uid=" + Binder.getCallingUid()
10969                    + " without permission "
10970                    + android.Manifest.permission.DUMP);
10971            return;
10972        }
10973
10974        boolean dumpAll = false;
10975        boolean dumpClient = false;
10976        String dumpPackage = null;
10977
10978        int opti = 0;
10979        while (opti < args.length) {
10980            String opt = args[opti];
10981            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10982                break;
10983            }
10984            opti++;
10985            if ("-a".equals(opt)) {
10986                dumpAll = true;
10987            } else if ("-c".equals(opt)) {
10988                dumpClient = true;
10989            } else if ("-h".equals(opt)) {
10990                pw.println("Activity manager dump options:");
10991                pw.println("  [-a] [-c] [-h] [cmd] ...");
10992                pw.println("  cmd may be one of:");
10993                pw.println("    a[ctivities]: activity stack state");
10994                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10995                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10996                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10997                pw.println("    o[om]: out of memory management");
10998                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10999                pw.println("    provider [COMP_SPEC]: provider client-side state");
11000                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11001                pw.println("    service [COMP_SPEC]: service client-side state");
11002                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11003                pw.println("    all: dump all activities");
11004                pw.println("    top: dump the top activity");
11005                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11006                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11007                pw.println("    a partial substring in a component name, a");
11008                pw.println("    hex object identifier.");
11009                pw.println("  -a: include all available server state.");
11010                pw.println("  -c: include client state.");
11011                return;
11012            } else {
11013                pw.println("Unknown argument: " + opt + "; use -h for help");
11014            }
11015        }
11016
11017        long origId = Binder.clearCallingIdentity();
11018        boolean more = false;
11019        // Is the caller requesting to dump a particular piece of data?
11020        if (opti < args.length) {
11021            String cmd = args[opti];
11022            opti++;
11023            if ("activities".equals(cmd) || "a".equals(cmd)) {
11024                synchronized (this) {
11025                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11026                }
11027            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11028                String[] newArgs;
11029                String name;
11030                if (opti >= args.length) {
11031                    name = null;
11032                    newArgs = EMPTY_STRING_ARRAY;
11033                } else {
11034                    name = args[opti];
11035                    opti++;
11036                    newArgs = new String[args.length - opti];
11037                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11038                            args.length - opti);
11039                }
11040                synchronized (this) {
11041                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11042                }
11043            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11044                String[] newArgs;
11045                String name;
11046                if (opti >= args.length) {
11047                    name = null;
11048                    newArgs = EMPTY_STRING_ARRAY;
11049                } else {
11050                    name = args[opti];
11051                    opti++;
11052                    newArgs = new String[args.length - opti];
11053                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11054                            args.length - opti);
11055                }
11056                synchronized (this) {
11057                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11058                }
11059            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11060                String[] newArgs;
11061                String name;
11062                if (opti >= args.length) {
11063                    name = null;
11064                    newArgs = EMPTY_STRING_ARRAY;
11065                } else {
11066                    name = args[opti];
11067                    opti++;
11068                    newArgs = new String[args.length - opti];
11069                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11070                            args.length - opti);
11071                }
11072                synchronized (this) {
11073                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11074                }
11075            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11076                synchronized (this) {
11077                    dumpOomLocked(fd, pw, args, opti, true);
11078                }
11079            } else if ("provider".equals(cmd)) {
11080                String[] newArgs;
11081                String name;
11082                if (opti >= args.length) {
11083                    name = null;
11084                    newArgs = EMPTY_STRING_ARRAY;
11085                } else {
11086                    name = args[opti];
11087                    opti++;
11088                    newArgs = new String[args.length - opti];
11089                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11090                }
11091                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11092                    pw.println("No providers match: " + name);
11093                    pw.println("Use -h for help.");
11094                }
11095            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11096                synchronized (this) {
11097                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11098                }
11099            } else if ("service".equals(cmd)) {
11100                String[] newArgs;
11101                String name;
11102                if (opti >= args.length) {
11103                    name = null;
11104                    newArgs = EMPTY_STRING_ARRAY;
11105                } else {
11106                    name = args[opti];
11107                    opti++;
11108                    newArgs = new String[args.length - opti];
11109                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11110                            args.length - opti);
11111                }
11112                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11113                    pw.println("No services match: " + name);
11114                    pw.println("Use -h for help.");
11115                }
11116            } else if ("package".equals(cmd)) {
11117                String[] newArgs;
11118                if (opti >= args.length) {
11119                    pw.println("package: no package name specified");
11120                    pw.println("Use -h for help.");
11121                } else {
11122                    dumpPackage = args[opti];
11123                    opti++;
11124                    newArgs = new String[args.length - opti];
11125                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11126                            args.length - opti);
11127                    args = newArgs;
11128                    opti = 0;
11129                    more = true;
11130                }
11131            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11132                synchronized (this) {
11133                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11134                }
11135            } else {
11136                // Dumping a single activity?
11137                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11138                    pw.println("Bad activity command, or no activities match: " + cmd);
11139                    pw.println("Use -h for help.");
11140                }
11141            }
11142            if (!more) {
11143                Binder.restoreCallingIdentity(origId);
11144                return;
11145            }
11146        }
11147
11148        // No piece of data specified, dump everything.
11149        synchronized (this) {
11150            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11151            pw.println();
11152            if (dumpAll) {
11153                pw.println("-------------------------------------------------------------------------------");
11154            }
11155            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11156            pw.println();
11157            if (dumpAll) {
11158                pw.println("-------------------------------------------------------------------------------");
11159            }
11160            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11161            pw.println();
11162            if (dumpAll) {
11163                pw.println("-------------------------------------------------------------------------------");
11164            }
11165            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11166            pw.println();
11167            if (dumpAll) {
11168                pw.println("-------------------------------------------------------------------------------");
11169            }
11170            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11171            pw.println();
11172            if (dumpAll) {
11173                pw.println("-------------------------------------------------------------------------------");
11174            }
11175            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11176        }
11177        Binder.restoreCallingIdentity(origId);
11178    }
11179
11180    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11181            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11182        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11183
11184        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11185                dumpPackage);
11186        boolean needSep = printedAnything;
11187
11188        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11189                dumpPackage, needSep, "  mFocusedActivity: ");
11190        if (printed) {
11191            printedAnything = true;
11192            needSep = false;
11193        }
11194
11195        if (dumpPackage == null) {
11196            if (needSep) {
11197                pw.println();
11198            }
11199            needSep = true;
11200            printedAnything = true;
11201            mStackSupervisor.dump(pw, "  ");
11202        }
11203
11204        if (mRecentTasks.size() > 0) {
11205            boolean printedHeader = false;
11206
11207            final int N = mRecentTasks.size();
11208            for (int i=0; i<N; i++) {
11209                TaskRecord tr = mRecentTasks.get(i);
11210                if (dumpPackage != null) {
11211                    if (tr.realActivity == null ||
11212                            !dumpPackage.equals(tr.realActivity)) {
11213                        continue;
11214                    }
11215                }
11216                if (!printedHeader) {
11217                    if (needSep) {
11218                        pw.println();
11219                    }
11220                    pw.println("  Recent tasks:");
11221                    printedHeader = true;
11222                    printedAnything = true;
11223                }
11224                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11225                        pw.println(tr);
11226                if (dumpAll) {
11227                    mRecentTasks.get(i).dump(pw, "    ");
11228                }
11229            }
11230        }
11231
11232        if (!printedAnything) {
11233            pw.println("  (nothing)");
11234        }
11235    }
11236
11237    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11238            int opti, boolean dumpAll, String dumpPackage) {
11239        boolean needSep = false;
11240        boolean printedAnything = false;
11241        int numPers = 0;
11242
11243        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11244
11245        if (dumpAll) {
11246            final int NP = mProcessNames.getMap().size();
11247            for (int ip=0; ip<NP; ip++) {
11248                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11249                final int NA = procs.size();
11250                for (int ia=0; ia<NA; ia++) {
11251                    ProcessRecord r = procs.valueAt(ia);
11252                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11253                        continue;
11254                    }
11255                    if (!needSep) {
11256                        pw.println("  All known processes:");
11257                        needSep = true;
11258                        printedAnything = true;
11259                    }
11260                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11261                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11262                        pw.print(" "); pw.println(r);
11263                    r.dump(pw, "    ");
11264                    if (r.persistent) {
11265                        numPers++;
11266                    }
11267                }
11268            }
11269        }
11270
11271        if (mIsolatedProcesses.size() > 0) {
11272            boolean printed = false;
11273            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11274                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11275                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11276                    continue;
11277                }
11278                if (!printed) {
11279                    if (needSep) {
11280                        pw.println();
11281                    }
11282                    pw.println("  Isolated process list (sorted by uid):");
11283                    printedAnything = true;
11284                    printed = true;
11285                    needSep = true;
11286                }
11287                pw.println(String.format("%sIsolated #%2d: %s",
11288                        "    ", i, r.toString()));
11289            }
11290        }
11291
11292        if (mLruProcesses.size() > 0) {
11293            if (needSep) {
11294                pw.println();
11295            }
11296            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11297                    pw.print(" total, non-act at ");
11298                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11299                    pw.print(", non-svc at ");
11300                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11301                    pw.println("):");
11302            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11303            needSep = true;
11304            printedAnything = true;
11305        }
11306
11307        if (dumpAll || dumpPackage != null) {
11308            synchronized (mPidsSelfLocked) {
11309                boolean printed = false;
11310                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11311                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11312                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11313                        continue;
11314                    }
11315                    if (!printed) {
11316                        if (needSep) pw.println();
11317                        needSep = true;
11318                        pw.println("  PID mappings:");
11319                        printed = true;
11320                        printedAnything = true;
11321                    }
11322                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11323                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11324                }
11325            }
11326        }
11327
11328        if (mForegroundProcesses.size() > 0) {
11329            synchronized (mPidsSelfLocked) {
11330                boolean printed = false;
11331                for (int i=0; i<mForegroundProcesses.size(); i++) {
11332                    ProcessRecord r = mPidsSelfLocked.get(
11333                            mForegroundProcesses.valueAt(i).pid);
11334                    if (dumpPackage != null && (r == null
11335                            || !r.pkgList.containsKey(dumpPackage))) {
11336                        continue;
11337                    }
11338                    if (!printed) {
11339                        if (needSep) pw.println();
11340                        needSep = true;
11341                        pw.println("  Foreground Processes:");
11342                        printed = true;
11343                        printedAnything = true;
11344                    }
11345                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11346                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11347                }
11348            }
11349        }
11350
11351        if (mPersistentStartingProcesses.size() > 0) {
11352            if (needSep) pw.println();
11353            needSep = true;
11354            printedAnything = true;
11355            pw.println("  Persisent processes that are starting:");
11356            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11357                    "Starting Norm", "Restarting PERS", dumpPackage);
11358        }
11359
11360        if (mRemovedProcesses.size() > 0) {
11361            if (needSep) pw.println();
11362            needSep = true;
11363            printedAnything = true;
11364            pw.println("  Processes that are being removed:");
11365            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11366                    "Removed Norm", "Removed PERS", dumpPackage);
11367        }
11368
11369        if (mProcessesOnHold.size() > 0) {
11370            if (needSep) pw.println();
11371            needSep = true;
11372            printedAnything = true;
11373            pw.println("  Processes that are on old until the system is ready:");
11374            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11375                    "OnHold Norm", "OnHold PERS", dumpPackage);
11376        }
11377
11378        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11379
11380        if (mProcessCrashTimes.getMap().size() > 0) {
11381            boolean printed = false;
11382            long now = SystemClock.uptimeMillis();
11383            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11384            final int NP = pmap.size();
11385            for (int ip=0; ip<NP; ip++) {
11386                String pname = pmap.keyAt(ip);
11387                SparseArray<Long> uids = pmap.valueAt(ip);
11388                final int N = uids.size();
11389                for (int i=0; i<N; i++) {
11390                    int puid = uids.keyAt(i);
11391                    ProcessRecord r = mProcessNames.get(pname, puid);
11392                    if (dumpPackage != null && (r == null
11393                            || !r.pkgList.containsKey(dumpPackage))) {
11394                        continue;
11395                    }
11396                    if (!printed) {
11397                        if (needSep) pw.println();
11398                        needSep = true;
11399                        pw.println("  Time since processes crashed:");
11400                        printed = true;
11401                        printedAnything = true;
11402                    }
11403                    pw.print("    Process "); pw.print(pname);
11404                            pw.print(" uid "); pw.print(puid);
11405                            pw.print(": last crashed ");
11406                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11407                            pw.println(" ago");
11408                }
11409            }
11410        }
11411
11412        if (mBadProcesses.getMap().size() > 0) {
11413            boolean printed = false;
11414            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11415            final int NP = pmap.size();
11416            for (int ip=0; ip<NP; ip++) {
11417                String pname = pmap.keyAt(ip);
11418                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11419                final int N = uids.size();
11420                for (int i=0; i<N; i++) {
11421                    int puid = uids.keyAt(i);
11422                    ProcessRecord r = mProcessNames.get(pname, puid);
11423                    if (dumpPackage != null && (r == null
11424                            || !r.pkgList.containsKey(dumpPackage))) {
11425                        continue;
11426                    }
11427                    if (!printed) {
11428                        if (needSep) pw.println();
11429                        needSep = true;
11430                        pw.println("  Bad processes:");
11431                        printedAnything = true;
11432                    }
11433                    BadProcessInfo info = uids.valueAt(i);
11434                    pw.print("    Bad process "); pw.print(pname);
11435                            pw.print(" uid "); pw.print(puid);
11436                            pw.print(": crashed at time "); pw.println(info.time);
11437                    if (info.shortMsg != null) {
11438                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11439                    }
11440                    if (info.longMsg != null) {
11441                        pw.print("      Long msg: "); pw.println(info.longMsg);
11442                    }
11443                    if (info.stack != null) {
11444                        pw.println("      Stack:");
11445                        int lastPos = 0;
11446                        for (int pos=0; pos<info.stack.length(); pos++) {
11447                            if (info.stack.charAt(pos) == '\n') {
11448                                pw.print("        ");
11449                                pw.write(info.stack, lastPos, pos-lastPos);
11450                                pw.println();
11451                                lastPos = pos+1;
11452                            }
11453                        }
11454                        if (lastPos < info.stack.length()) {
11455                            pw.print("        ");
11456                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11457                            pw.println();
11458                        }
11459                    }
11460                }
11461            }
11462        }
11463
11464        if (dumpPackage == null) {
11465            pw.println();
11466            needSep = false;
11467            pw.println("  mStartedUsers:");
11468            for (int i=0; i<mStartedUsers.size(); i++) {
11469                UserStartedState uss = mStartedUsers.valueAt(i);
11470                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11471                        pw.print(": "); uss.dump("", pw);
11472            }
11473            pw.print("  mStartedUserArray: [");
11474            for (int i=0; i<mStartedUserArray.length; i++) {
11475                if (i > 0) pw.print(", ");
11476                pw.print(mStartedUserArray[i]);
11477            }
11478            pw.println("]");
11479            pw.print("  mUserLru: [");
11480            for (int i=0; i<mUserLru.size(); i++) {
11481                if (i > 0) pw.print(", ");
11482                pw.print(mUserLru.get(i));
11483            }
11484            pw.println("]");
11485            if (dumpAll) {
11486                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11487            }
11488        }
11489        if (mHomeProcess != null && (dumpPackage == null
11490                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11491            if (needSep) {
11492                pw.println();
11493                needSep = false;
11494            }
11495            pw.println("  mHomeProcess: " + mHomeProcess);
11496        }
11497        if (mPreviousProcess != null && (dumpPackage == null
11498                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11499            if (needSep) {
11500                pw.println();
11501                needSep = false;
11502            }
11503            pw.println("  mPreviousProcess: " + mPreviousProcess);
11504        }
11505        if (dumpAll) {
11506            StringBuilder sb = new StringBuilder(128);
11507            sb.append("  mPreviousProcessVisibleTime: ");
11508            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11509            pw.println(sb);
11510        }
11511        if (mHeavyWeightProcess != null && (dumpPackage == null
11512                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11513            if (needSep) {
11514                pw.println();
11515                needSep = false;
11516            }
11517            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11518        }
11519        if (dumpPackage == null) {
11520            pw.println("  mConfiguration: " + mConfiguration);
11521        }
11522        if (dumpAll) {
11523            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11524            if (mCompatModePackages.getPackages().size() > 0) {
11525                boolean printed = false;
11526                for (Map.Entry<String, Integer> entry
11527                        : mCompatModePackages.getPackages().entrySet()) {
11528                    String pkg = entry.getKey();
11529                    int mode = entry.getValue();
11530                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11531                        continue;
11532                    }
11533                    if (!printed) {
11534                        pw.println("  mScreenCompatPackages:");
11535                        printed = true;
11536                    }
11537                    pw.print("    "); pw.print(pkg); pw.print(": ");
11538                            pw.print(mode); pw.println();
11539                }
11540            }
11541        }
11542        if (dumpPackage == null) {
11543            if (mSleeping || mWentToSleep || mLockScreenShown) {
11544                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11545                        + " mLockScreenShown " + mLockScreenShown);
11546            }
11547            if (mShuttingDown || mRunningVoice) {
11548                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11549            }
11550        }
11551        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11552                || mOrigWaitForDebugger) {
11553            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11554                    || dumpPackage.equals(mOrigDebugApp)) {
11555                if (needSep) {
11556                    pw.println();
11557                    needSep = false;
11558                }
11559                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11560                        + " mDebugTransient=" + mDebugTransient
11561                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11562            }
11563        }
11564        if (mOpenGlTraceApp != null) {
11565            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11566                if (needSep) {
11567                    pw.println();
11568                    needSep = false;
11569                }
11570                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11571            }
11572        }
11573        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11574                || mProfileFd != null) {
11575            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11576                if (needSep) {
11577                    pw.println();
11578                    needSep = false;
11579                }
11580                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11581                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11582                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11583                        + mAutoStopProfiler);
11584            }
11585        }
11586        if (dumpPackage == null) {
11587            if (mAlwaysFinishActivities || mController != null) {
11588                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11589                        + " mController=" + mController);
11590            }
11591            if (dumpAll) {
11592                pw.println("  Total persistent processes: " + numPers);
11593                pw.println("  mProcessesReady=" + mProcessesReady
11594                        + " mSystemReady=" + mSystemReady);
11595                pw.println("  mBooting=" + mBooting
11596                        + " mBooted=" + mBooted
11597                        + " mFactoryTest=" + mFactoryTest);
11598                pw.print("  mLastPowerCheckRealtime=");
11599                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11600                        pw.println("");
11601                pw.print("  mLastPowerCheckUptime=");
11602                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11603                        pw.println("");
11604                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11605                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11606                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11607                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11608                        + " (" + mLruProcesses.size() + " total)"
11609                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11610                        + " mNumServiceProcs=" + mNumServiceProcs
11611                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11612                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11613                        + " mLastMemoryLevel" + mLastMemoryLevel
11614                        + " mLastNumProcesses" + mLastNumProcesses);
11615                long now = SystemClock.uptimeMillis();
11616                pw.print("  mLastIdleTime=");
11617                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11618                        pw.print(" mLowRamSinceLastIdle=");
11619                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11620                        pw.println();
11621            }
11622        }
11623
11624        if (!printedAnything) {
11625            pw.println("  (nothing)");
11626        }
11627    }
11628
11629    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11630            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11631        if (mProcessesToGc.size() > 0) {
11632            boolean printed = false;
11633            long now = SystemClock.uptimeMillis();
11634            for (int i=0; i<mProcessesToGc.size(); i++) {
11635                ProcessRecord proc = mProcessesToGc.get(i);
11636                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11637                    continue;
11638                }
11639                if (!printed) {
11640                    if (needSep) pw.println();
11641                    needSep = true;
11642                    pw.println("  Processes that are waiting to GC:");
11643                    printed = true;
11644                }
11645                pw.print("    Process "); pw.println(proc);
11646                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11647                        pw.print(", last gced=");
11648                        pw.print(now-proc.lastRequestedGc);
11649                        pw.print(" ms ago, last lowMem=");
11650                        pw.print(now-proc.lastLowMemory);
11651                        pw.println(" ms ago");
11652
11653            }
11654        }
11655        return needSep;
11656    }
11657
11658    void printOomLevel(PrintWriter pw, String name, int adj) {
11659        pw.print("    ");
11660        if (adj >= 0) {
11661            pw.print(' ');
11662            if (adj < 10) pw.print(' ');
11663        } else {
11664            if (adj > -10) pw.print(' ');
11665        }
11666        pw.print(adj);
11667        pw.print(": ");
11668        pw.print(name);
11669        pw.print(" (");
11670        pw.print(mProcessList.getMemLevel(adj)/1024);
11671        pw.println(" kB)");
11672    }
11673
11674    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11675            int opti, boolean dumpAll) {
11676        boolean needSep = false;
11677
11678        if (mLruProcesses.size() > 0) {
11679            if (needSep) pw.println();
11680            needSep = true;
11681            pw.println("  OOM levels:");
11682            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11683            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11684            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11685            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11686            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11687            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11688            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11689            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11690            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11691            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11692            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11693            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11694            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11695
11696            if (needSep) pw.println();
11697            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11698                    pw.print(" total, non-act at ");
11699                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11700                    pw.print(", non-svc at ");
11701                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11702                    pw.println("):");
11703            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11704            needSep = true;
11705        }
11706
11707        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11708
11709        pw.println();
11710        pw.println("  mHomeProcess: " + mHomeProcess);
11711        pw.println("  mPreviousProcess: " + mPreviousProcess);
11712        if (mHeavyWeightProcess != null) {
11713            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11714        }
11715
11716        return true;
11717    }
11718
11719    /**
11720     * There are three ways to call this:
11721     *  - no provider specified: dump all the providers
11722     *  - a flattened component name that matched an existing provider was specified as the
11723     *    first arg: dump that one provider
11724     *  - the first arg isn't the flattened component name of an existing provider:
11725     *    dump all providers whose component contains the first arg as a substring
11726     */
11727    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11728            int opti, boolean dumpAll) {
11729        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11730    }
11731
11732    static class ItemMatcher {
11733        ArrayList<ComponentName> components;
11734        ArrayList<String> strings;
11735        ArrayList<Integer> objects;
11736        boolean all;
11737
11738        ItemMatcher() {
11739            all = true;
11740        }
11741
11742        void build(String name) {
11743            ComponentName componentName = ComponentName.unflattenFromString(name);
11744            if (componentName != null) {
11745                if (components == null) {
11746                    components = new ArrayList<ComponentName>();
11747                }
11748                components.add(componentName);
11749                all = false;
11750            } else {
11751                int objectId = 0;
11752                // Not a '/' separated full component name; maybe an object ID?
11753                try {
11754                    objectId = Integer.parseInt(name, 16);
11755                    if (objects == null) {
11756                        objects = new ArrayList<Integer>();
11757                    }
11758                    objects.add(objectId);
11759                    all = false;
11760                } catch (RuntimeException e) {
11761                    // Not an integer; just do string match.
11762                    if (strings == null) {
11763                        strings = new ArrayList<String>();
11764                    }
11765                    strings.add(name);
11766                    all = false;
11767                }
11768            }
11769        }
11770
11771        int build(String[] args, int opti) {
11772            for (; opti<args.length; opti++) {
11773                String name = args[opti];
11774                if ("--".equals(name)) {
11775                    return opti+1;
11776                }
11777                build(name);
11778            }
11779            return opti;
11780        }
11781
11782        boolean match(Object object, ComponentName comp) {
11783            if (all) {
11784                return true;
11785            }
11786            if (components != null) {
11787                for (int i=0; i<components.size(); i++) {
11788                    if (components.get(i).equals(comp)) {
11789                        return true;
11790                    }
11791                }
11792            }
11793            if (objects != null) {
11794                for (int i=0; i<objects.size(); i++) {
11795                    if (System.identityHashCode(object) == objects.get(i)) {
11796                        return true;
11797                    }
11798                }
11799            }
11800            if (strings != null) {
11801                String flat = comp.flattenToString();
11802                for (int i=0; i<strings.size(); i++) {
11803                    if (flat.contains(strings.get(i))) {
11804                        return true;
11805                    }
11806                }
11807            }
11808            return false;
11809        }
11810    }
11811
11812    /**
11813     * There are three things that cmd can be:
11814     *  - a flattened component name that matches an existing activity
11815     *  - the cmd arg isn't the flattened component name of an existing activity:
11816     *    dump all activity whose component contains the cmd as a substring
11817     *  - A hex number of the ActivityRecord object instance.
11818     */
11819    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11820            int opti, boolean dumpAll) {
11821        ArrayList<ActivityRecord> activities;
11822
11823        synchronized (this) {
11824            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11825        }
11826
11827        if (activities.size() <= 0) {
11828            return false;
11829        }
11830
11831        String[] newArgs = new String[args.length - opti];
11832        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11833
11834        TaskRecord lastTask = null;
11835        boolean needSep = false;
11836        for (int i=activities.size()-1; i>=0; i--) {
11837            ActivityRecord r = activities.get(i);
11838            if (needSep) {
11839                pw.println();
11840            }
11841            needSep = true;
11842            synchronized (this) {
11843                if (lastTask != r.task) {
11844                    lastTask = r.task;
11845                    pw.print("TASK "); pw.print(lastTask.affinity);
11846                            pw.print(" id="); pw.println(lastTask.taskId);
11847                    if (dumpAll) {
11848                        lastTask.dump(pw, "  ");
11849                    }
11850                }
11851            }
11852            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11853        }
11854        return true;
11855    }
11856
11857    /**
11858     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11859     * there is a thread associated with the activity.
11860     */
11861    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11862            final ActivityRecord r, String[] args, boolean dumpAll) {
11863        String innerPrefix = prefix + "  ";
11864        synchronized (this) {
11865            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11866                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11867                    pw.print(" pid=");
11868                    if (r.app != null) pw.println(r.app.pid);
11869                    else pw.println("(not running)");
11870            if (dumpAll) {
11871                r.dump(pw, innerPrefix);
11872            }
11873        }
11874        if (r.app != null && r.app.thread != null) {
11875            // flush anything that is already in the PrintWriter since the thread is going
11876            // to write to the file descriptor directly
11877            pw.flush();
11878            try {
11879                TransferPipe tp = new TransferPipe();
11880                try {
11881                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11882                            r.appToken, innerPrefix, args);
11883                    tp.go(fd);
11884                } finally {
11885                    tp.kill();
11886                }
11887            } catch (IOException e) {
11888                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11889            } catch (RemoteException e) {
11890                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11891            }
11892        }
11893    }
11894
11895    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11896            int opti, boolean dumpAll, String dumpPackage) {
11897        boolean needSep = false;
11898        boolean onlyHistory = false;
11899        boolean printedAnything = false;
11900
11901        if ("history".equals(dumpPackage)) {
11902            if (opti < args.length && "-s".equals(args[opti])) {
11903                dumpAll = false;
11904            }
11905            onlyHistory = true;
11906            dumpPackage = null;
11907        }
11908
11909        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11910        if (!onlyHistory && dumpAll) {
11911            if (mRegisteredReceivers.size() > 0) {
11912                boolean printed = false;
11913                Iterator it = mRegisteredReceivers.values().iterator();
11914                while (it.hasNext()) {
11915                    ReceiverList r = (ReceiverList)it.next();
11916                    if (dumpPackage != null && (r.app == null ||
11917                            !dumpPackage.equals(r.app.info.packageName))) {
11918                        continue;
11919                    }
11920                    if (!printed) {
11921                        pw.println("  Registered Receivers:");
11922                        needSep = true;
11923                        printed = true;
11924                        printedAnything = true;
11925                    }
11926                    pw.print("  * "); pw.println(r);
11927                    r.dump(pw, "    ");
11928                }
11929            }
11930
11931            if (mReceiverResolver.dump(pw, needSep ?
11932                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11933                    "    ", dumpPackage, false)) {
11934                needSep = true;
11935                printedAnything = true;
11936            }
11937        }
11938
11939        for (BroadcastQueue q : mBroadcastQueues) {
11940            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11941            printedAnything |= needSep;
11942        }
11943
11944        needSep = true;
11945
11946        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11947            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11948                if (needSep) {
11949                    pw.println();
11950                }
11951                needSep = true;
11952                printedAnything = true;
11953                pw.print("  Sticky broadcasts for user ");
11954                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11955                StringBuilder sb = new StringBuilder(128);
11956                for (Map.Entry<String, ArrayList<Intent>> ent
11957                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11958                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11959                    if (dumpAll) {
11960                        pw.println(":");
11961                        ArrayList<Intent> intents = ent.getValue();
11962                        final int N = intents.size();
11963                        for (int i=0; i<N; i++) {
11964                            sb.setLength(0);
11965                            sb.append("    Intent: ");
11966                            intents.get(i).toShortString(sb, false, true, false, false);
11967                            pw.println(sb.toString());
11968                            Bundle bundle = intents.get(i).getExtras();
11969                            if (bundle != null) {
11970                                pw.print("      ");
11971                                pw.println(bundle.toString());
11972                            }
11973                        }
11974                    } else {
11975                        pw.println("");
11976                    }
11977                }
11978            }
11979        }
11980
11981        if (!onlyHistory && dumpAll) {
11982            pw.println();
11983            for (BroadcastQueue queue : mBroadcastQueues) {
11984                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11985                        + queue.mBroadcastsScheduled);
11986            }
11987            pw.println("  mHandler:");
11988            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11989            needSep = true;
11990            printedAnything = true;
11991        }
11992
11993        if (!printedAnything) {
11994            pw.println("  (nothing)");
11995        }
11996    }
11997
11998    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11999            int opti, boolean dumpAll, String dumpPackage) {
12000        boolean needSep;
12001        boolean printedAnything = false;
12002
12003        ItemMatcher matcher = new ItemMatcher();
12004        matcher.build(args, opti);
12005
12006        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12007
12008        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12009        printedAnything |= needSep;
12010
12011        if (mLaunchingProviders.size() > 0) {
12012            boolean printed = false;
12013            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12014                ContentProviderRecord r = mLaunchingProviders.get(i);
12015                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12016                    continue;
12017                }
12018                if (!printed) {
12019                    if (needSep) pw.println();
12020                    needSep = true;
12021                    pw.println("  Launching content providers:");
12022                    printed = true;
12023                    printedAnything = true;
12024                }
12025                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12026                        pw.println(r);
12027            }
12028        }
12029
12030        if (mGrantedUriPermissions.size() > 0) {
12031            boolean printed = false;
12032            int dumpUid = -2;
12033            if (dumpPackage != null) {
12034                try {
12035                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12036                } catch (NameNotFoundException e) {
12037                    dumpUid = -1;
12038                }
12039            }
12040            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12041                int uid = mGrantedUriPermissions.keyAt(i);
12042                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12043                    continue;
12044                }
12045                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12046                if (!printed) {
12047                    if (needSep) pw.println();
12048                    needSep = true;
12049                    pw.println("  Granted Uri Permissions:");
12050                    printed = true;
12051                    printedAnything = true;
12052                }
12053                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12054                for (UriPermission perm : perms.values()) {
12055                    pw.print("    "); pw.println(perm);
12056                    if (dumpAll) {
12057                        perm.dump(pw, "      ");
12058                    }
12059                }
12060            }
12061        }
12062
12063        if (!printedAnything) {
12064            pw.println("  (nothing)");
12065        }
12066    }
12067
12068    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12069            int opti, boolean dumpAll, String dumpPackage) {
12070        boolean printed = false;
12071
12072        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12073
12074        if (mIntentSenderRecords.size() > 0) {
12075            Iterator<WeakReference<PendingIntentRecord>> it
12076                    = mIntentSenderRecords.values().iterator();
12077            while (it.hasNext()) {
12078                WeakReference<PendingIntentRecord> ref = it.next();
12079                PendingIntentRecord rec = ref != null ? ref.get(): null;
12080                if (dumpPackage != null && (rec == null
12081                        || !dumpPackage.equals(rec.key.packageName))) {
12082                    continue;
12083                }
12084                printed = true;
12085                if (rec != null) {
12086                    pw.print("  * "); pw.println(rec);
12087                    if (dumpAll) {
12088                        rec.dump(pw, "    ");
12089                    }
12090                } else {
12091                    pw.print("  * "); pw.println(ref);
12092                }
12093            }
12094        }
12095
12096        if (!printed) {
12097            pw.println("  (nothing)");
12098        }
12099    }
12100
12101    private static final int dumpProcessList(PrintWriter pw,
12102            ActivityManagerService service, List list,
12103            String prefix, String normalLabel, String persistentLabel,
12104            String dumpPackage) {
12105        int numPers = 0;
12106        final int N = list.size()-1;
12107        for (int i=N; i>=0; i--) {
12108            ProcessRecord r = (ProcessRecord)list.get(i);
12109            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12110                continue;
12111            }
12112            pw.println(String.format("%s%s #%2d: %s",
12113                    prefix, (r.persistent ? persistentLabel : normalLabel),
12114                    i, r.toString()));
12115            if (r.persistent) {
12116                numPers++;
12117            }
12118        }
12119        return numPers;
12120    }
12121
12122    private static final boolean dumpProcessOomList(PrintWriter pw,
12123            ActivityManagerService service, List<ProcessRecord> origList,
12124            String prefix, String normalLabel, String persistentLabel,
12125            boolean inclDetails, String dumpPackage) {
12126
12127        ArrayList<Pair<ProcessRecord, Integer>> list
12128                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12129        for (int i=0; i<origList.size(); i++) {
12130            ProcessRecord r = origList.get(i);
12131            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12132                continue;
12133            }
12134            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12135        }
12136
12137        if (list.size() <= 0) {
12138            return false;
12139        }
12140
12141        Comparator<Pair<ProcessRecord, Integer>> comparator
12142                = new Comparator<Pair<ProcessRecord, Integer>>() {
12143            @Override
12144            public int compare(Pair<ProcessRecord, Integer> object1,
12145                    Pair<ProcessRecord, Integer> object2) {
12146                if (object1.first.setAdj != object2.first.setAdj) {
12147                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12148                }
12149                if (object1.second.intValue() != object2.second.intValue()) {
12150                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12151                }
12152                return 0;
12153            }
12154        };
12155
12156        Collections.sort(list, comparator);
12157
12158        final long curRealtime = SystemClock.elapsedRealtime();
12159        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12160        final long curUptime = SystemClock.uptimeMillis();
12161        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12162
12163        for (int i=list.size()-1; i>=0; i--) {
12164            ProcessRecord r = list.get(i).first;
12165            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12166            char schedGroup;
12167            switch (r.setSchedGroup) {
12168                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12169                    schedGroup = 'B';
12170                    break;
12171                case Process.THREAD_GROUP_DEFAULT:
12172                    schedGroup = 'F';
12173                    break;
12174                default:
12175                    schedGroup = '?';
12176                    break;
12177            }
12178            char foreground;
12179            if (r.foregroundActivities) {
12180                foreground = 'A';
12181            } else if (r.foregroundServices) {
12182                foreground = 'S';
12183            } else {
12184                foreground = ' ';
12185            }
12186            String procState = ProcessList.makeProcStateString(r.curProcState);
12187            pw.print(prefix);
12188            pw.print(r.persistent ? persistentLabel : normalLabel);
12189            pw.print(" #");
12190            int num = (origList.size()-1)-list.get(i).second;
12191            if (num < 10) pw.print(' ');
12192            pw.print(num);
12193            pw.print(": ");
12194            pw.print(oomAdj);
12195            pw.print(' ');
12196            pw.print(schedGroup);
12197            pw.print('/');
12198            pw.print(foreground);
12199            pw.print('/');
12200            pw.print(procState);
12201            pw.print(" trm:");
12202            if (r.trimMemoryLevel < 10) pw.print(' ');
12203            pw.print(r.trimMemoryLevel);
12204            pw.print(' ');
12205            pw.print(r.toShortString());
12206            pw.print(" (");
12207            pw.print(r.adjType);
12208            pw.println(')');
12209            if (r.adjSource != null || r.adjTarget != null) {
12210                pw.print(prefix);
12211                pw.print("    ");
12212                if (r.adjTarget instanceof ComponentName) {
12213                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12214                } else if (r.adjTarget != null) {
12215                    pw.print(r.adjTarget.toString());
12216                } else {
12217                    pw.print("{null}");
12218                }
12219                pw.print("<=");
12220                if (r.adjSource instanceof ProcessRecord) {
12221                    pw.print("Proc{");
12222                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12223                    pw.println("}");
12224                } else if (r.adjSource != null) {
12225                    pw.println(r.adjSource.toString());
12226                } else {
12227                    pw.println("{null}");
12228                }
12229            }
12230            if (inclDetails) {
12231                pw.print(prefix);
12232                pw.print("    ");
12233                pw.print("oom: max="); pw.print(r.maxAdj);
12234                pw.print(" curRaw="); pw.print(r.curRawAdj);
12235                pw.print(" setRaw="); pw.print(r.setRawAdj);
12236                pw.print(" cur="); pw.print(r.curAdj);
12237                pw.print(" set="); pw.println(r.setAdj);
12238                pw.print(prefix);
12239                pw.print("    ");
12240                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12241                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12242                pw.print(" lastPss="); pw.print(r.lastPss);
12243                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12244                pw.print(prefix);
12245                pw.print("    ");
12246                pw.print("keeping="); pw.print(r.keeping);
12247                pw.print(" cached="); pw.print(r.cached);
12248                pw.print(" empty="); pw.print(r.empty);
12249                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12250
12251                if (!r.keeping) {
12252                    if (r.lastWakeTime != 0) {
12253                        long wtime;
12254                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12255                        synchronized (stats) {
12256                            wtime = stats.getProcessWakeTime(r.info.uid,
12257                                    r.pid, curRealtime);
12258                        }
12259                        long timeUsed = wtime - r.lastWakeTime;
12260                        pw.print(prefix);
12261                        pw.print("    ");
12262                        pw.print("keep awake over ");
12263                        TimeUtils.formatDuration(realtimeSince, pw);
12264                        pw.print(" used ");
12265                        TimeUtils.formatDuration(timeUsed, pw);
12266                        pw.print(" (");
12267                        pw.print((timeUsed*100)/realtimeSince);
12268                        pw.println("%)");
12269                    }
12270                    if (r.lastCpuTime != 0) {
12271                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12272                        pw.print(prefix);
12273                        pw.print("    ");
12274                        pw.print("run cpu over ");
12275                        TimeUtils.formatDuration(uptimeSince, pw);
12276                        pw.print(" used ");
12277                        TimeUtils.formatDuration(timeUsed, pw);
12278                        pw.print(" (");
12279                        pw.print((timeUsed*100)/uptimeSince);
12280                        pw.println("%)");
12281                    }
12282                }
12283            }
12284        }
12285        return true;
12286    }
12287
12288    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12289        ArrayList<ProcessRecord> procs;
12290        synchronized (this) {
12291            if (args != null && args.length > start
12292                    && args[start].charAt(0) != '-') {
12293                procs = new ArrayList<ProcessRecord>();
12294                int pid = -1;
12295                try {
12296                    pid = Integer.parseInt(args[start]);
12297                } catch (NumberFormatException e) {
12298                }
12299                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12300                    ProcessRecord proc = mLruProcesses.get(i);
12301                    if (proc.pid == pid) {
12302                        procs.add(proc);
12303                    } else if (proc.processName.equals(args[start])) {
12304                        procs.add(proc);
12305                    }
12306                }
12307                if (procs.size() <= 0) {
12308                    return null;
12309                }
12310            } else {
12311                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12312            }
12313        }
12314        return procs;
12315    }
12316
12317    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12318            PrintWriter pw, String[] args) {
12319        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12320        if (procs == null) {
12321            pw.println("No process found for: " + args[0]);
12322            return;
12323        }
12324
12325        long uptime = SystemClock.uptimeMillis();
12326        long realtime = SystemClock.elapsedRealtime();
12327        pw.println("Applications Graphics Acceleration Info:");
12328        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12329
12330        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12331            ProcessRecord r = procs.get(i);
12332            if (r.thread != null) {
12333                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12334                pw.flush();
12335                try {
12336                    TransferPipe tp = new TransferPipe();
12337                    try {
12338                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12339                        tp.go(fd);
12340                    } finally {
12341                        tp.kill();
12342                    }
12343                } catch (IOException e) {
12344                    pw.println("Failure while dumping the app: " + r);
12345                    pw.flush();
12346                } catch (RemoteException e) {
12347                    pw.println("Got a RemoteException while dumping the app " + r);
12348                    pw.flush();
12349                }
12350            }
12351        }
12352    }
12353
12354    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12355        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12356        if (procs == null) {
12357            pw.println("No process found for: " + args[0]);
12358            return;
12359        }
12360
12361        pw.println("Applications Database Info:");
12362
12363        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12364            ProcessRecord r = procs.get(i);
12365            if (r.thread != null) {
12366                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12367                pw.flush();
12368                try {
12369                    TransferPipe tp = new TransferPipe();
12370                    try {
12371                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12372                        tp.go(fd);
12373                    } finally {
12374                        tp.kill();
12375                    }
12376                } catch (IOException e) {
12377                    pw.println("Failure while dumping the app: " + r);
12378                    pw.flush();
12379                } catch (RemoteException e) {
12380                    pw.println("Got a RemoteException while dumping the app " + r);
12381                    pw.flush();
12382                }
12383            }
12384        }
12385    }
12386
12387    final static class MemItem {
12388        final boolean isProc;
12389        final String label;
12390        final String shortLabel;
12391        final long pss;
12392        final int id;
12393        final boolean hasActivities;
12394        ArrayList<MemItem> subitems;
12395
12396        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12397                boolean _hasActivities) {
12398            isProc = true;
12399            label = _label;
12400            shortLabel = _shortLabel;
12401            pss = _pss;
12402            id = _id;
12403            hasActivities = _hasActivities;
12404        }
12405
12406        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12407            isProc = false;
12408            label = _label;
12409            shortLabel = _shortLabel;
12410            pss = _pss;
12411            id = _id;
12412            hasActivities = false;
12413        }
12414    }
12415
12416    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12417            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12418        if (sort && !isCompact) {
12419            Collections.sort(items, new Comparator<MemItem>() {
12420                @Override
12421                public int compare(MemItem lhs, MemItem rhs) {
12422                    if (lhs.pss < rhs.pss) {
12423                        return 1;
12424                    } else if (lhs.pss > rhs.pss) {
12425                        return -1;
12426                    }
12427                    return 0;
12428                }
12429            });
12430        }
12431
12432        for (int i=0; i<items.size(); i++) {
12433            MemItem mi = items.get(i);
12434            if (!isCompact) {
12435                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12436            } else if (mi.isProc) {
12437                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12438                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12439                pw.println(mi.hasActivities ? ",a" : ",e");
12440            } else {
12441                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12442                pw.println(mi.pss);
12443            }
12444            if (mi.subitems != null) {
12445                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12446                        true, isCompact);
12447            }
12448        }
12449    }
12450
12451    // These are in KB.
12452    static final long[] DUMP_MEM_BUCKETS = new long[] {
12453        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12454        120*1024, 160*1024, 200*1024,
12455        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12456        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12457    };
12458
12459    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12460            boolean stackLike) {
12461        int start = label.lastIndexOf('.');
12462        if (start >= 0) start++;
12463        else start = 0;
12464        int end = label.length();
12465        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12466            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12467                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12468                out.append(bucket);
12469                out.append(stackLike ? "MB." : "MB ");
12470                out.append(label, start, end);
12471                return;
12472            }
12473        }
12474        out.append(memKB/1024);
12475        out.append(stackLike ? "MB." : "MB ");
12476        out.append(label, start, end);
12477    }
12478
12479    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12480            ProcessList.NATIVE_ADJ,
12481            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12482            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12483            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12484            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12485            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12486    };
12487    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12488            "Native",
12489            "System", "Persistent", "Foreground",
12490            "Visible", "Perceptible",
12491            "Heavy Weight", "Backup",
12492            "A Services", "Home",
12493            "Previous", "B Services", "Cached"
12494    };
12495    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12496            "native",
12497            "sys", "pers", "fore",
12498            "vis", "percept",
12499            "heavy", "backup",
12500            "servicea", "home",
12501            "prev", "serviceb", "cached"
12502    };
12503
12504    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12505            long realtime, boolean isCheckinRequest, boolean isCompact) {
12506        if (isCheckinRequest || isCompact) {
12507            // short checkin version
12508            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12509        } else {
12510            pw.println("Applications Memory Usage (kB):");
12511            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12512        }
12513    }
12514
12515    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12516            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12517        boolean dumpDetails = false;
12518        boolean dumpFullDetails = false;
12519        boolean dumpDalvik = false;
12520        boolean oomOnly = false;
12521        boolean isCompact = false;
12522        boolean localOnly = false;
12523
12524        int opti = 0;
12525        while (opti < args.length) {
12526            String opt = args[opti];
12527            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12528                break;
12529            }
12530            opti++;
12531            if ("-a".equals(opt)) {
12532                dumpDetails = true;
12533                dumpFullDetails = true;
12534                dumpDalvik = true;
12535            } else if ("-d".equals(opt)) {
12536                dumpDalvik = true;
12537            } else if ("-c".equals(opt)) {
12538                isCompact = true;
12539            } else if ("--oom".equals(opt)) {
12540                oomOnly = true;
12541            } else if ("--local".equals(opt)) {
12542                localOnly = true;
12543            } else if ("-h".equals(opt)) {
12544                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12545                pw.println("  -a: include all available information for each process.");
12546                pw.println("  -d: include dalvik details when dumping process details.");
12547                pw.println("  -c: dump in a compact machine-parseable representation.");
12548                pw.println("  --oom: only show processes organized by oom adj.");
12549                pw.println("  --local: only collect details locally, don't call process.");
12550                pw.println("If [process] is specified it can be the name or ");
12551                pw.println("pid of a specific process to dump.");
12552                return;
12553            } else {
12554                pw.println("Unknown argument: " + opt + "; use -h for help");
12555            }
12556        }
12557
12558        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12559        long uptime = SystemClock.uptimeMillis();
12560        long realtime = SystemClock.elapsedRealtime();
12561        final long[] tmpLong = new long[1];
12562
12563        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12564        if (procs == null) {
12565            // No Java processes.  Maybe they want to print a native process.
12566            if (args != null && args.length > opti
12567                    && args[opti].charAt(0) != '-') {
12568                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12569                        = new ArrayList<ProcessCpuTracker.Stats>();
12570                updateCpuStatsNow();
12571                int findPid = -1;
12572                try {
12573                    findPid = Integer.parseInt(args[opti]);
12574                } catch (NumberFormatException e) {
12575                }
12576                synchronized (mProcessCpuThread) {
12577                    final int N = mProcessCpuTracker.countStats();
12578                    for (int i=0; i<N; i++) {
12579                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12580                        if (st.pid == findPid || (st.baseName != null
12581                                && st.baseName.equals(args[opti]))) {
12582                            nativeProcs.add(st);
12583                        }
12584                    }
12585                }
12586                if (nativeProcs.size() > 0) {
12587                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12588                            isCompact);
12589                    Debug.MemoryInfo mi = null;
12590                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12591                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12592                        final int pid = r.pid;
12593                        if (!isCheckinRequest && dumpDetails) {
12594                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12595                        }
12596                        if (mi == null) {
12597                            mi = new Debug.MemoryInfo();
12598                        }
12599                        if (dumpDetails || (!brief && !oomOnly)) {
12600                            Debug.getMemoryInfo(pid, mi);
12601                        } else {
12602                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12603                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12604                        }
12605                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12606                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12607                        if (isCheckinRequest) {
12608                            pw.println();
12609                        }
12610                    }
12611                    return;
12612                }
12613            }
12614            pw.println("No process found for: " + args[opti]);
12615            return;
12616        }
12617
12618        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12619            dumpDetails = true;
12620        }
12621
12622        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12623
12624        String[] innerArgs = new String[args.length-opti];
12625        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12626
12627        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12628        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12629        long nativePss=0, dalvikPss=0, otherPss=0;
12630        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12631
12632        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12633        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12634                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12635
12636        long totalPss = 0;
12637        long cachedPss = 0;
12638
12639        Debug.MemoryInfo mi = null;
12640        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12641            final ProcessRecord r = procs.get(i);
12642            final IApplicationThread thread;
12643            final int pid;
12644            final int oomAdj;
12645            final boolean hasActivities;
12646            synchronized (this) {
12647                thread = r.thread;
12648                pid = r.pid;
12649                oomAdj = r.getSetAdjWithServices();
12650                hasActivities = r.activities.size() > 0;
12651            }
12652            if (thread != null) {
12653                if (!isCheckinRequest && dumpDetails) {
12654                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12655                }
12656                if (mi == null) {
12657                    mi = new Debug.MemoryInfo();
12658                }
12659                if (dumpDetails || (!brief && !oomOnly)) {
12660                    Debug.getMemoryInfo(pid, mi);
12661                } else {
12662                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12663                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12664                }
12665                if (dumpDetails) {
12666                    if (localOnly) {
12667                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12668                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12669                        if (isCheckinRequest) {
12670                            pw.println();
12671                        }
12672                    } else {
12673                        try {
12674                            pw.flush();
12675                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12676                                    dumpDalvik, innerArgs);
12677                        } catch (RemoteException e) {
12678                            if (!isCheckinRequest) {
12679                                pw.println("Got RemoteException!");
12680                                pw.flush();
12681                            }
12682                        }
12683                    }
12684                }
12685
12686                final long myTotalPss = mi.getTotalPss();
12687                final long myTotalUss = mi.getTotalUss();
12688
12689                synchronized (this) {
12690                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12691                        // Record this for posterity if the process has been stable.
12692                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12693                    }
12694                }
12695
12696                if (!isCheckinRequest && mi != null) {
12697                    totalPss += myTotalPss;
12698                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12699                            (hasActivities ? " / activities)" : ")"),
12700                            r.processName, myTotalPss, pid, hasActivities);
12701                    procMems.add(pssItem);
12702                    procMemsMap.put(pid, pssItem);
12703
12704                    nativePss += mi.nativePss;
12705                    dalvikPss += mi.dalvikPss;
12706                    otherPss += mi.otherPss;
12707                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12708                        long mem = mi.getOtherPss(j);
12709                        miscPss[j] += mem;
12710                        otherPss -= mem;
12711                    }
12712
12713                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12714                        cachedPss += myTotalPss;
12715                    }
12716
12717                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12718                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12719                                || oomIndex == (oomPss.length-1)) {
12720                            oomPss[oomIndex] += myTotalPss;
12721                            if (oomProcs[oomIndex] == null) {
12722                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12723                            }
12724                            oomProcs[oomIndex].add(pssItem);
12725                            break;
12726                        }
12727                    }
12728                }
12729            }
12730        }
12731
12732        long nativeProcTotalPss = 0;
12733
12734        if (!isCheckinRequest && procs.size() > 1) {
12735            // If we are showing aggregations, also look for native processes to
12736            // include so that our aggregations are more accurate.
12737            updateCpuStatsNow();
12738            synchronized (mProcessCpuThread) {
12739                final int N = mProcessCpuTracker.countStats();
12740                for (int i=0; i<N; i++) {
12741                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12742                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12743                        if (mi == null) {
12744                            mi = new Debug.MemoryInfo();
12745                        }
12746                        if (!brief && !oomOnly) {
12747                            Debug.getMemoryInfo(st.pid, mi);
12748                        } else {
12749                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12750                            mi.nativePrivateDirty = (int)tmpLong[0];
12751                        }
12752
12753                        final long myTotalPss = mi.getTotalPss();
12754                        totalPss += myTotalPss;
12755                        nativeProcTotalPss += myTotalPss;
12756
12757                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12758                                st.name, myTotalPss, st.pid, false);
12759                        procMems.add(pssItem);
12760
12761                        nativePss += mi.nativePss;
12762                        dalvikPss += mi.dalvikPss;
12763                        otherPss += mi.otherPss;
12764                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12765                            long mem = mi.getOtherPss(j);
12766                            miscPss[j] += mem;
12767                            otherPss -= mem;
12768                        }
12769                        oomPss[0] += myTotalPss;
12770                        if (oomProcs[0] == null) {
12771                            oomProcs[0] = new ArrayList<MemItem>();
12772                        }
12773                        oomProcs[0].add(pssItem);
12774                    }
12775                }
12776            }
12777
12778            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12779
12780            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12781            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12782            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12783            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12784                String label = Debug.MemoryInfo.getOtherLabel(j);
12785                catMems.add(new MemItem(label, label, miscPss[j], j));
12786            }
12787
12788            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12789            for (int j=0; j<oomPss.length; j++) {
12790                if (oomPss[j] != 0) {
12791                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12792                            : DUMP_MEM_OOM_LABEL[j];
12793                    MemItem item = new MemItem(label, label, oomPss[j],
12794                            DUMP_MEM_OOM_ADJ[j]);
12795                    item.subitems = oomProcs[j];
12796                    oomMems.add(item);
12797                }
12798            }
12799
12800            if (!brief && !oomOnly && !isCompact) {
12801                pw.println();
12802                pw.println("Total PSS by process:");
12803                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12804                pw.println();
12805            }
12806            if (!isCompact) {
12807                pw.println("Total PSS by OOM adjustment:");
12808            }
12809            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12810            if (!brief && !oomOnly) {
12811                PrintWriter out = categoryPw != null ? categoryPw : pw;
12812                if (!isCompact) {
12813                    out.println();
12814                    out.println("Total PSS by category:");
12815                }
12816                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12817            }
12818            if (!isCompact) {
12819                pw.println();
12820            }
12821            MemInfoReader memInfo = new MemInfoReader();
12822            memInfo.readMemInfo();
12823            if (nativeProcTotalPss > 0) {
12824                synchronized (this) {
12825                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12826                            memInfo.getFreeSizeKb(),
12827                            memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
12828                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12829                            nativeProcTotalPss);
12830                }
12831            }
12832            if (!brief) {
12833                if (!isCompact) {
12834                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12835                    pw.print(" kB (status ");
12836                    switch (mLastMemoryLevel) {
12837                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12838                            pw.println("normal)");
12839                            break;
12840                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12841                            pw.println("moderate)");
12842                            break;
12843                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12844                            pw.println("low)");
12845                            break;
12846                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12847                            pw.println("critical)");
12848                            break;
12849                        default:
12850                            pw.print(mLastMemoryLevel);
12851                            pw.println(")");
12852                            break;
12853                    }
12854                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12855                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12856                            pw.print(cachedPss); pw.print(" cached pss + ");
12857                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12858                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12859                } else {
12860                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12861                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12862                            + memInfo.getFreeSizeKb()); pw.print(",");
12863                    pw.println(totalPss - cachedPss);
12864                }
12865            }
12866            if (!isCompact) {
12867                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12868                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12869                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12870                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12871                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12872                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12873                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12874                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12875                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12876                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12877                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12878            }
12879            if (!brief) {
12880                if (memInfo.getZramTotalSizeKb() != 0) {
12881                    if (!isCompact) {
12882                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12883                                pw.print(" kB physical used for ");
12884                                pw.print(memInfo.getSwapTotalSizeKb()
12885                                        - memInfo.getSwapFreeSizeKb());
12886                                pw.print(" kB in swap (");
12887                                pw.print(memInfo.getSwapTotalSizeKb());
12888                                pw.println(" kB total swap)");
12889                    } else {
12890                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12891                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12892                                pw.println(memInfo.getSwapFreeSizeKb());
12893                    }
12894                }
12895                final int[] SINGLE_LONG_FORMAT = new int[] {
12896                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12897                };
12898                long[] longOut = new long[1];
12899                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12900                        SINGLE_LONG_FORMAT, null, longOut, null);
12901                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12902                longOut[0] = 0;
12903                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12904                        SINGLE_LONG_FORMAT, null, longOut, null);
12905                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12906                longOut[0] = 0;
12907                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12908                        SINGLE_LONG_FORMAT, null, longOut, null);
12909                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12910                longOut[0] = 0;
12911                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12912                        SINGLE_LONG_FORMAT, null, longOut, null);
12913                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12914                if (!isCompact) {
12915                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12916                        pw.print("      KSM: "); pw.print(sharing);
12917                                pw.print(" kB saved from shared ");
12918                                pw.print(shared); pw.println(" kB");
12919                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12920                                pw.print(voltile); pw.println(" kB volatile");
12921                    }
12922                    pw.print("   Tuning: ");
12923                    pw.print(ActivityManager.staticGetMemoryClass());
12924                    pw.print(" (large ");
12925                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12926                    pw.print("), oom ");
12927                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12928                    pw.print(" kB");
12929                    pw.print(", restore limit ");
12930                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12931                    pw.print(" kB");
12932                    if (ActivityManager.isLowRamDeviceStatic()) {
12933                        pw.print(" (low-ram)");
12934                    }
12935                    if (ActivityManager.isHighEndGfx()) {
12936                        pw.print(" (high-end-gfx)");
12937                    }
12938                    pw.println();
12939                } else {
12940                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12941                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12942                    pw.println(voltile);
12943                    pw.print("tuning,");
12944                    pw.print(ActivityManager.staticGetMemoryClass());
12945                    pw.print(',');
12946                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12947                    pw.print(',');
12948                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12949                    if (ActivityManager.isLowRamDeviceStatic()) {
12950                        pw.print(",low-ram");
12951                    }
12952                    if (ActivityManager.isHighEndGfx()) {
12953                        pw.print(",high-end-gfx");
12954                    }
12955                    pw.println();
12956                }
12957            }
12958        }
12959    }
12960
12961    /**
12962     * Searches array of arguments for the specified string
12963     * @param args array of argument strings
12964     * @param value value to search for
12965     * @return true if the value is contained in the array
12966     */
12967    private static boolean scanArgs(String[] args, String value) {
12968        if (args != null) {
12969            for (String arg : args) {
12970                if (value.equals(arg)) {
12971                    return true;
12972                }
12973            }
12974        }
12975        return false;
12976    }
12977
12978    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12979            ContentProviderRecord cpr, boolean always) {
12980        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12981
12982        if (!inLaunching || always) {
12983            synchronized (cpr) {
12984                cpr.launchingApp = null;
12985                cpr.notifyAll();
12986            }
12987            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12988            String names[] = cpr.info.authority.split(";");
12989            for (int j = 0; j < names.length; j++) {
12990                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12991            }
12992        }
12993
12994        for (int i=0; i<cpr.connections.size(); i++) {
12995            ContentProviderConnection conn = cpr.connections.get(i);
12996            if (conn.waiting) {
12997                // If this connection is waiting for the provider, then we don't
12998                // need to mess with its process unless we are always removing
12999                // or for some reason the provider is not currently launching.
13000                if (inLaunching && !always) {
13001                    continue;
13002                }
13003            }
13004            ProcessRecord capp = conn.client;
13005            conn.dead = true;
13006            if (conn.stableCount > 0) {
13007                if (!capp.persistent && capp.thread != null
13008                        && capp.pid != 0
13009                        && capp.pid != MY_PID) {
13010                    killUnneededProcessLocked(capp, "depends on provider "
13011                            + cpr.name.flattenToShortString()
13012                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13013                }
13014            } else if (capp.thread != null && conn.provider.provider != null) {
13015                try {
13016                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13017                } catch (RemoteException e) {
13018                }
13019                // In the protocol here, we don't expect the client to correctly
13020                // clean up this connection, we'll just remove it.
13021                cpr.connections.remove(i);
13022                conn.client.conProviders.remove(conn);
13023            }
13024        }
13025
13026        if (inLaunching && always) {
13027            mLaunchingProviders.remove(cpr);
13028        }
13029        return inLaunching;
13030    }
13031
13032    /**
13033     * Main code for cleaning up a process when it has gone away.  This is
13034     * called both as a result of the process dying, or directly when stopping
13035     * a process when running in single process mode.
13036     */
13037    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13038            boolean restarting, boolean allowRestart, int index) {
13039        if (index >= 0) {
13040            removeLruProcessLocked(app);
13041            ProcessList.remove(app.pid);
13042        }
13043
13044        mProcessesToGc.remove(app);
13045        mPendingPssProcesses.remove(app);
13046
13047        // Dismiss any open dialogs.
13048        if (app.crashDialog != null && !app.forceCrashReport) {
13049            app.crashDialog.dismiss();
13050            app.crashDialog = null;
13051        }
13052        if (app.anrDialog != null) {
13053            app.anrDialog.dismiss();
13054            app.anrDialog = null;
13055        }
13056        if (app.waitDialog != null) {
13057            app.waitDialog.dismiss();
13058            app.waitDialog = null;
13059        }
13060
13061        app.crashing = false;
13062        app.notResponding = false;
13063
13064        app.resetPackageList(mProcessStats);
13065        app.unlinkDeathRecipient();
13066        app.makeInactive(mProcessStats);
13067        app.forcingToForeground = null;
13068        updateProcessForegroundLocked(app, false, false);
13069        app.foregroundActivities = false;
13070        app.hasShownUi = false;
13071        app.treatLikeActivity = false;
13072        app.hasAboveClient = false;
13073        app.hasClientActivities = false;
13074
13075        mServices.killServicesLocked(app, allowRestart);
13076
13077        boolean restart = false;
13078
13079        // Remove published content providers.
13080        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13081            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13082            final boolean always = app.bad || !allowRestart;
13083            if (removeDyingProviderLocked(app, cpr, always) || always) {
13084                // We left the provider in the launching list, need to
13085                // restart it.
13086                restart = true;
13087            }
13088
13089            cpr.provider = null;
13090            cpr.proc = null;
13091        }
13092        app.pubProviders.clear();
13093
13094        // Take care of any launching providers waiting for this process.
13095        if (checkAppInLaunchingProvidersLocked(app, false)) {
13096            restart = true;
13097        }
13098
13099        // Unregister from connected content providers.
13100        if (!app.conProviders.isEmpty()) {
13101            for (int i=0; i<app.conProviders.size(); i++) {
13102                ContentProviderConnection conn = app.conProviders.get(i);
13103                conn.provider.connections.remove(conn);
13104            }
13105            app.conProviders.clear();
13106        }
13107
13108        // At this point there may be remaining entries in mLaunchingProviders
13109        // where we were the only one waiting, so they are no longer of use.
13110        // Look for these and clean up if found.
13111        // XXX Commented out for now.  Trying to figure out a way to reproduce
13112        // the actual situation to identify what is actually going on.
13113        if (false) {
13114            for (int i=0; i<mLaunchingProviders.size(); i++) {
13115                ContentProviderRecord cpr = (ContentProviderRecord)
13116                        mLaunchingProviders.get(i);
13117                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13118                    synchronized (cpr) {
13119                        cpr.launchingApp = null;
13120                        cpr.notifyAll();
13121                    }
13122                }
13123            }
13124        }
13125
13126        skipCurrentReceiverLocked(app);
13127
13128        // Unregister any receivers.
13129        for (int i=app.receivers.size()-1; i>=0; i--) {
13130            removeReceiverLocked(app.receivers.valueAt(i));
13131        }
13132        app.receivers.clear();
13133
13134        // If the app is undergoing backup, tell the backup manager about it
13135        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13136            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13137                    + mBackupTarget.appInfo + " died during backup");
13138            try {
13139                IBackupManager bm = IBackupManager.Stub.asInterface(
13140                        ServiceManager.getService(Context.BACKUP_SERVICE));
13141                bm.agentDisconnected(app.info.packageName);
13142            } catch (RemoteException e) {
13143                // can't happen; backup manager is local
13144            }
13145        }
13146
13147        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13148            ProcessChangeItem item = mPendingProcessChanges.get(i);
13149            if (item.pid == app.pid) {
13150                mPendingProcessChanges.remove(i);
13151                mAvailProcessChanges.add(item);
13152            }
13153        }
13154        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13155
13156        // If the caller is restarting this app, then leave it in its
13157        // current lists and let the caller take care of it.
13158        if (restarting) {
13159            return;
13160        }
13161
13162        if (!app.persistent || app.isolated) {
13163            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13164                    "Removing non-persistent process during cleanup: " + app);
13165            mProcessNames.remove(app.processName, app.uid);
13166            mIsolatedProcesses.remove(app.uid);
13167            if (mHeavyWeightProcess == app) {
13168                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13169                        mHeavyWeightProcess.userId, 0));
13170                mHeavyWeightProcess = null;
13171            }
13172        } else if (!app.removed) {
13173            // This app is persistent, so we need to keep its record around.
13174            // If it is not already on the pending app list, add it there
13175            // and start a new process for it.
13176            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13177                mPersistentStartingProcesses.add(app);
13178                restart = true;
13179            }
13180        }
13181        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13182                "Clean-up removing on hold: " + app);
13183        mProcessesOnHold.remove(app);
13184
13185        if (app == mHomeProcess) {
13186            mHomeProcess = null;
13187        }
13188        if (app == mPreviousProcess) {
13189            mPreviousProcess = null;
13190        }
13191
13192        if (restart && !app.isolated) {
13193            // We have components that still need to be running in the
13194            // process, so re-launch it.
13195            mProcessNames.put(app.processName, app.uid, app);
13196            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13197        } else if (app.pid > 0 && app.pid != MY_PID) {
13198            // Goodbye!
13199            boolean removed;
13200            synchronized (mPidsSelfLocked) {
13201                mPidsSelfLocked.remove(app.pid);
13202                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13203            }
13204            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13205                    app.processName, app.info.uid);
13206            if (app.isolated) {
13207                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13208            }
13209            app.setPid(0);
13210        }
13211    }
13212
13213    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13214        // Look through the content providers we are waiting to have launched,
13215        // and if any run in this process then either schedule a restart of
13216        // the process or kill the client waiting for it if this process has
13217        // gone bad.
13218        int NL = mLaunchingProviders.size();
13219        boolean restart = false;
13220        for (int i=0; i<NL; i++) {
13221            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13222            if (cpr.launchingApp == app) {
13223                if (!alwaysBad && !app.bad) {
13224                    restart = true;
13225                } else {
13226                    removeDyingProviderLocked(app, cpr, true);
13227                    // cpr should have been removed from mLaunchingProviders
13228                    NL = mLaunchingProviders.size();
13229                    i--;
13230                }
13231            }
13232        }
13233        return restart;
13234    }
13235
13236    // =========================================================
13237    // SERVICES
13238    // =========================================================
13239
13240    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13241            int flags) {
13242        enforceNotIsolatedCaller("getServices");
13243        synchronized (this) {
13244            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13245        }
13246    }
13247
13248    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13249        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13250        synchronized (this) {
13251            return mServices.getRunningServiceControlPanelLocked(name);
13252        }
13253    }
13254
13255    public ComponentName startService(IApplicationThread caller, Intent service,
13256            String resolvedType, int userId) {
13257        enforceNotIsolatedCaller("startService");
13258        // Refuse possible leaked file descriptors
13259        if (service != null && service.hasFileDescriptors() == true) {
13260            throw new IllegalArgumentException("File descriptors passed in Intent");
13261        }
13262
13263        if (DEBUG_SERVICE)
13264            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13265        synchronized(this) {
13266            final int callingPid = Binder.getCallingPid();
13267            final int callingUid = Binder.getCallingUid();
13268            final long origId = Binder.clearCallingIdentity();
13269            ComponentName res = mServices.startServiceLocked(caller, service,
13270                    resolvedType, callingPid, callingUid, userId);
13271            Binder.restoreCallingIdentity(origId);
13272            return res;
13273        }
13274    }
13275
13276    ComponentName startServiceInPackage(int uid,
13277            Intent service, String resolvedType, int userId) {
13278        synchronized(this) {
13279            if (DEBUG_SERVICE)
13280                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13281            final long origId = Binder.clearCallingIdentity();
13282            ComponentName res = mServices.startServiceLocked(null, service,
13283                    resolvedType, -1, uid, userId);
13284            Binder.restoreCallingIdentity(origId);
13285            return res;
13286        }
13287    }
13288
13289    public int stopService(IApplicationThread caller, Intent service,
13290            String resolvedType, int userId) {
13291        enforceNotIsolatedCaller("stopService");
13292        // Refuse possible leaked file descriptors
13293        if (service != null && service.hasFileDescriptors() == true) {
13294            throw new IllegalArgumentException("File descriptors passed in Intent");
13295        }
13296
13297        synchronized(this) {
13298            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13299        }
13300    }
13301
13302    public IBinder peekService(Intent service, String resolvedType) {
13303        enforceNotIsolatedCaller("peekService");
13304        // Refuse possible leaked file descriptors
13305        if (service != null && service.hasFileDescriptors() == true) {
13306            throw new IllegalArgumentException("File descriptors passed in Intent");
13307        }
13308        synchronized(this) {
13309            return mServices.peekServiceLocked(service, resolvedType);
13310        }
13311    }
13312
13313    public boolean stopServiceToken(ComponentName className, IBinder token,
13314            int startId) {
13315        synchronized(this) {
13316            return mServices.stopServiceTokenLocked(className, token, startId);
13317        }
13318    }
13319
13320    public void setServiceForeground(ComponentName className, IBinder token,
13321            int id, Notification notification, boolean removeNotification) {
13322        synchronized(this) {
13323            mServices.setServiceForegroundLocked(className, token, id, notification,
13324                    removeNotification);
13325        }
13326    }
13327
13328    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13329            boolean requireFull, String name, String callerPackage) {
13330        final int callingUserId = UserHandle.getUserId(callingUid);
13331        if (callingUserId != userId) {
13332            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13333                if ((requireFull || checkComponentPermission(
13334                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13335                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13336                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13337                                callingPid, callingUid, -1, true)
13338                                != PackageManager.PERMISSION_GRANTED) {
13339                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13340                        // In this case, they would like to just execute as their
13341                        // owner user instead of failing.
13342                        userId = callingUserId;
13343                    } else {
13344                        StringBuilder builder = new StringBuilder(128);
13345                        builder.append("Permission Denial: ");
13346                        builder.append(name);
13347                        if (callerPackage != null) {
13348                            builder.append(" from ");
13349                            builder.append(callerPackage);
13350                        }
13351                        builder.append(" asks to run as user ");
13352                        builder.append(userId);
13353                        builder.append(" but is calling from user ");
13354                        builder.append(UserHandle.getUserId(callingUid));
13355                        builder.append("; this requires ");
13356                        builder.append(INTERACT_ACROSS_USERS_FULL);
13357                        if (!requireFull) {
13358                            builder.append(" or ");
13359                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13360                        }
13361                        String msg = builder.toString();
13362                        Slog.w(TAG, msg);
13363                        throw new SecurityException(msg);
13364                    }
13365                }
13366            }
13367            if (userId == UserHandle.USER_CURRENT
13368                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13369                // Note that we may be accessing this outside of a lock...
13370                // shouldn't be a big deal, if this is being called outside
13371                // of a locked context there is intrinsically a race with
13372                // the value the caller will receive and someone else changing it.
13373                userId = mCurrentUserId;
13374            }
13375            if (!allowAll && userId < 0) {
13376                throw new IllegalArgumentException(
13377                        "Call does not support special user #" + userId);
13378            }
13379        }
13380        return userId;
13381    }
13382
13383    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13384            String className, int flags) {
13385        boolean result = false;
13386        // For apps that don't have pre-defined UIDs, check for permission
13387        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13388            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13389                if (ActivityManager.checkUidPermission(
13390                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13391                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13392                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13393                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13394                            + " requests FLAG_SINGLE_USER, but app does not hold "
13395                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13396                    Slog.w(TAG, msg);
13397                    throw new SecurityException(msg);
13398                }
13399                // Permission passed
13400                result = true;
13401            }
13402        } else if ("system".equals(componentProcessName)) {
13403            result = true;
13404        } else {
13405            // App with pre-defined UID, check if it's a persistent app
13406            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13407        }
13408        if (DEBUG_MU) {
13409            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13410                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13411        }
13412        return result;
13413    }
13414
13415    /**
13416     * Checks to see if the caller is in the same app as the singleton
13417     * component, or the component is in a special app. It allows special apps
13418     * to export singleton components but prevents exporting singleton
13419     * components for regular apps.
13420     */
13421    boolean isValidSingletonCall(int callingUid, int componentUid) {
13422        int componentAppId = UserHandle.getAppId(componentUid);
13423        return UserHandle.isSameApp(callingUid, componentUid)
13424                || componentAppId == Process.SYSTEM_UID
13425                || componentAppId == Process.PHONE_UID
13426                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13427                        == PackageManager.PERMISSION_GRANTED;
13428    }
13429
13430    public int bindService(IApplicationThread caller, IBinder token,
13431            Intent service, String resolvedType,
13432            IServiceConnection connection, int flags, int userId) {
13433        enforceNotIsolatedCaller("bindService");
13434        // Refuse possible leaked file descriptors
13435        if (service != null && service.hasFileDescriptors() == true) {
13436            throw new IllegalArgumentException("File descriptors passed in Intent");
13437        }
13438
13439        synchronized(this) {
13440            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13441                    connection, flags, userId);
13442        }
13443    }
13444
13445    public boolean unbindService(IServiceConnection connection) {
13446        synchronized (this) {
13447            return mServices.unbindServiceLocked(connection);
13448        }
13449    }
13450
13451    public void publishService(IBinder token, Intent intent, IBinder service) {
13452        // Refuse possible leaked file descriptors
13453        if (intent != null && intent.hasFileDescriptors() == true) {
13454            throw new IllegalArgumentException("File descriptors passed in Intent");
13455        }
13456
13457        synchronized(this) {
13458            if (!(token instanceof ServiceRecord)) {
13459                throw new IllegalArgumentException("Invalid service token");
13460            }
13461            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13462        }
13463    }
13464
13465    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13466        // Refuse possible leaked file descriptors
13467        if (intent != null && intent.hasFileDescriptors() == true) {
13468            throw new IllegalArgumentException("File descriptors passed in Intent");
13469        }
13470
13471        synchronized(this) {
13472            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13473        }
13474    }
13475
13476    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13477        synchronized(this) {
13478            if (!(token instanceof ServiceRecord)) {
13479                throw new IllegalArgumentException("Invalid service token");
13480            }
13481            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13482        }
13483    }
13484
13485    // =========================================================
13486    // BACKUP AND RESTORE
13487    // =========================================================
13488
13489    // Cause the target app to be launched if necessary and its backup agent
13490    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13491    // activity manager to announce its creation.
13492    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13493        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13494        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13495
13496        synchronized(this) {
13497            // !!! TODO: currently no check here that we're already bound
13498            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13499            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13500            synchronized (stats) {
13501                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13502            }
13503
13504            // Backup agent is now in use, its package can't be stopped.
13505            try {
13506                AppGlobals.getPackageManager().setPackageStoppedState(
13507                        app.packageName, false, UserHandle.getUserId(app.uid));
13508            } catch (RemoteException e) {
13509            } catch (IllegalArgumentException e) {
13510                Slog.w(TAG, "Failed trying to unstop package "
13511                        + app.packageName + ": " + e);
13512            }
13513
13514            BackupRecord r = new BackupRecord(ss, app, backupMode);
13515            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13516                    ? new ComponentName(app.packageName, app.backupAgentName)
13517                    : new ComponentName("android", "FullBackupAgent");
13518            // startProcessLocked() returns existing proc's record if it's already running
13519            ProcessRecord proc = startProcessLocked(app.processName, app,
13520                    false, 0, "backup", hostingName, false, false, false);
13521            if (proc == null) {
13522                Slog.e(TAG, "Unable to start backup agent process " + r);
13523                return false;
13524            }
13525
13526            r.app = proc;
13527            mBackupTarget = r;
13528            mBackupAppName = app.packageName;
13529
13530            // Try not to kill the process during backup
13531            updateOomAdjLocked(proc);
13532
13533            // If the process is already attached, schedule the creation of the backup agent now.
13534            // If it is not yet live, this will be done when it attaches to the framework.
13535            if (proc.thread != null) {
13536                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13537                try {
13538                    proc.thread.scheduleCreateBackupAgent(app,
13539                            compatibilityInfoForPackageLocked(app), backupMode);
13540                } catch (RemoteException e) {
13541                    // Will time out on the backup manager side
13542                }
13543            } else {
13544                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13545            }
13546            // Invariants: at this point, the target app process exists and the application
13547            // is either already running or in the process of coming up.  mBackupTarget and
13548            // mBackupAppName describe the app, so that when it binds back to the AM we
13549            // know that it's scheduled for a backup-agent operation.
13550        }
13551
13552        return true;
13553    }
13554
13555    @Override
13556    public void clearPendingBackup() {
13557        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13558        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13559
13560        synchronized (this) {
13561            mBackupTarget = null;
13562            mBackupAppName = null;
13563        }
13564    }
13565
13566    // A backup agent has just come up
13567    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13568        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13569                + " = " + agent);
13570
13571        synchronized(this) {
13572            if (!agentPackageName.equals(mBackupAppName)) {
13573                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13574                return;
13575            }
13576        }
13577
13578        long oldIdent = Binder.clearCallingIdentity();
13579        try {
13580            IBackupManager bm = IBackupManager.Stub.asInterface(
13581                    ServiceManager.getService(Context.BACKUP_SERVICE));
13582            bm.agentConnected(agentPackageName, agent);
13583        } catch (RemoteException e) {
13584            // can't happen; the backup manager service is local
13585        } catch (Exception e) {
13586            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13587            e.printStackTrace();
13588        } finally {
13589            Binder.restoreCallingIdentity(oldIdent);
13590        }
13591    }
13592
13593    // done with this agent
13594    public void unbindBackupAgent(ApplicationInfo appInfo) {
13595        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13596        if (appInfo == null) {
13597            Slog.w(TAG, "unbind backup agent for null app");
13598            return;
13599        }
13600
13601        synchronized(this) {
13602            try {
13603                if (mBackupAppName == null) {
13604                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13605                    return;
13606                }
13607
13608                if (!mBackupAppName.equals(appInfo.packageName)) {
13609                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13610                    return;
13611                }
13612
13613                // Not backing this app up any more; reset its OOM adjustment
13614                final ProcessRecord proc = mBackupTarget.app;
13615                updateOomAdjLocked(proc);
13616
13617                // If the app crashed during backup, 'thread' will be null here
13618                if (proc.thread != null) {
13619                    try {
13620                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13621                                compatibilityInfoForPackageLocked(appInfo));
13622                    } catch (Exception e) {
13623                        Slog.e(TAG, "Exception when unbinding backup agent:");
13624                        e.printStackTrace();
13625                    }
13626                }
13627            } finally {
13628                mBackupTarget = null;
13629                mBackupAppName = null;
13630            }
13631        }
13632    }
13633    // =========================================================
13634    // BROADCASTS
13635    // =========================================================
13636
13637    private final List getStickiesLocked(String action, IntentFilter filter,
13638            List cur, int userId) {
13639        final ContentResolver resolver = mContext.getContentResolver();
13640        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13641        if (stickies == null) {
13642            return cur;
13643        }
13644        final ArrayList<Intent> list = stickies.get(action);
13645        if (list == null) {
13646            return cur;
13647        }
13648        int N = list.size();
13649        for (int i=0; i<N; i++) {
13650            Intent intent = list.get(i);
13651            if (filter.match(resolver, intent, true, TAG) >= 0) {
13652                if (cur == null) {
13653                    cur = new ArrayList<Intent>();
13654                }
13655                cur.add(intent);
13656            }
13657        }
13658        return cur;
13659    }
13660
13661    boolean isPendingBroadcastProcessLocked(int pid) {
13662        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13663                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13664    }
13665
13666    void skipPendingBroadcastLocked(int pid) {
13667            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13668            for (BroadcastQueue queue : mBroadcastQueues) {
13669                queue.skipPendingBroadcastLocked(pid);
13670            }
13671    }
13672
13673    // The app just attached; send any pending broadcasts that it should receive
13674    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13675        boolean didSomething = false;
13676        for (BroadcastQueue queue : mBroadcastQueues) {
13677            didSomething |= queue.sendPendingBroadcastsLocked(app);
13678        }
13679        return didSomething;
13680    }
13681
13682    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13683            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13684        enforceNotIsolatedCaller("registerReceiver");
13685        int callingUid;
13686        int callingPid;
13687        synchronized(this) {
13688            ProcessRecord callerApp = null;
13689            if (caller != null) {
13690                callerApp = getRecordForAppLocked(caller);
13691                if (callerApp == null) {
13692                    throw new SecurityException(
13693                            "Unable to find app for caller " + caller
13694                            + " (pid=" + Binder.getCallingPid()
13695                            + ") when registering receiver " + receiver);
13696                }
13697                if (callerApp.info.uid != Process.SYSTEM_UID &&
13698                        !callerApp.pkgList.containsKey(callerPackage) &&
13699                        !"android".equals(callerPackage)) {
13700                    throw new SecurityException("Given caller package " + callerPackage
13701                            + " is not running in process " + callerApp);
13702                }
13703                callingUid = callerApp.info.uid;
13704                callingPid = callerApp.pid;
13705            } else {
13706                callerPackage = null;
13707                callingUid = Binder.getCallingUid();
13708                callingPid = Binder.getCallingPid();
13709            }
13710
13711            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13712                    true, true, "registerReceiver", callerPackage);
13713
13714            List allSticky = null;
13715
13716            // Look for any matching sticky broadcasts...
13717            Iterator actions = filter.actionsIterator();
13718            if (actions != null) {
13719                while (actions.hasNext()) {
13720                    String action = (String)actions.next();
13721                    allSticky = getStickiesLocked(action, filter, allSticky,
13722                            UserHandle.USER_ALL);
13723                    allSticky = getStickiesLocked(action, filter, allSticky,
13724                            UserHandle.getUserId(callingUid));
13725                }
13726            } else {
13727                allSticky = getStickiesLocked(null, filter, allSticky,
13728                        UserHandle.USER_ALL);
13729                allSticky = getStickiesLocked(null, filter, allSticky,
13730                        UserHandle.getUserId(callingUid));
13731            }
13732
13733            // The first sticky in the list is returned directly back to
13734            // the client.
13735            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13736
13737            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13738                    + ": " + sticky);
13739
13740            if (receiver == null) {
13741                return sticky;
13742            }
13743
13744            ReceiverList rl
13745                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13746            if (rl == null) {
13747                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13748                        userId, receiver);
13749                if (rl.app != null) {
13750                    rl.app.receivers.add(rl);
13751                } else {
13752                    try {
13753                        receiver.asBinder().linkToDeath(rl, 0);
13754                    } catch (RemoteException e) {
13755                        return sticky;
13756                    }
13757                    rl.linkedToDeath = true;
13758                }
13759                mRegisteredReceivers.put(receiver.asBinder(), rl);
13760            } else if (rl.uid != callingUid) {
13761                throw new IllegalArgumentException(
13762                        "Receiver requested to register for uid " + callingUid
13763                        + " was previously registered for uid " + rl.uid);
13764            } else if (rl.pid != callingPid) {
13765                throw new IllegalArgumentException(
13766                        "Receiver requested to register for pid " + callingPid
13767                        + " was previously registered for pid " + rl.pid);
13768            } else if (rl.userId != userId) {
13769                throw new IllegalArgumentException(
13770                        "Receiver requested to register for user " + userId
13771                        + " was previously registered for user " + rl.userId);
13772            }
13773            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13774                    permission, callingUid, userId);
13775            rl.add(bf);
13776            if (!bf.debugCheck()) {
13777                Slog.w(TAG, "==> For Dynamic broadast");
13778            }
13779            mReceiverResolver.addFilter(bf);
13780
13781            // Enqueue broadcasts for all existing stickies that match
13782            // this filter.
13783            if (allSticky != null) {
13784                ArrayList receivers = new ArrayList();
13785                receivers.add(bf);
13786
13787                int N = allSticky.size();
13788                for (int i=0; i<N; i++) {
13789                    Intent intent = (Intent)allSticky.get(i);
13790                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13791                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13792                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13793                            null, null, false, true, true, -1);
13794                    queue.enqueueParallelBroadcastLocked(r);
13795                    queue.scheduleBroadcastsLocked();
13796                }
13797            }
13798
13799            return sticky;
13800        }
13801    }
13802
13803    public void unregisterReceiver(IIntentReceiver receiver) {
13804        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13805
13806        final long origId = Binder.clearCallingIdentity();
13807        try {
13808            boolean doTrim = false;
13809
13810            synchronized(this) {
13811                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13812                if (rl != null) {
13813                    if (rl.curBroadcast != null) {
13814                        BroadcastRecord r = rl.curBroadcast;
13815                        final boolean doNext = finishReceiverLocked(
13816                                receiver.asBinder(), r.resultCode, r.resultData,
13817                                r.resultExtras, r.resultAbort);
13818                        if (doNext) {
13819                            doTrim = true;
13820                            r.queue.processNextBroadcast(false);
13821                        }
13822                    }
13823
13824                    if (rl.app != null) {
13825                        rl.app.receivers.remove(rl);
13826                    }
13827                    removeReceiverLocked(rl);
13828                    if (rl.linkedToDeath) {
13829                        rl.linkedToDeath = false;
13830                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13831                    }
13832                }
13833            }
13834
13835            // If we actually concluded any broadcasts, we might now be able
13836            // to trim the recipients' apps from our working set
13837            if (doTrim) {
13838                trimApplications();
13839                return;
13840            }
13841
13842        } finally {
13843            Binder.restoreCallingIdentity(origId);
13844        }
13845    }
13846
13847    void removeReceiverLocked(ReceiverList rl) {
13848        mRegisteredReceivers.remove(rl.receiver.asBinder());
13849        int N = rl.size();
13850        for (int i=0; i<N; i++) {
13851            mReceiverResolver.removeFilter(rl.get(i));
13852        }
13853    }
13854
13855    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13856        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13857            ProcessRecord r = mLruProcesses.get(i);
13858            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13859                try {
13860                    r.thread.dispatchPackageBroadcast(cmd, packages);
13861                } catch (RemoteException ex) {
13862                }
13863            }
13864        }
13865    }
13866
13867    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13868            int[] users) {
13869        List<ResolveInfo> receivers = null;
13870        try {
13871            HashSet<ComponentName> singleUserReceivers = null;
13872            boolean scannedFirstReceivers = false;
13873            for (int user : users) {
13874                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13875                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13876                if (user != 0 && newReceivers != null) {
13877                    // If this is not the primary user, we need to check for
13878                    // any receivers that should be filtered out.
13879                    for (int i=0; i<newReceivers.size(); i++) {
13880                        ResolveInfo ri = newReceivers.get(i);
13881                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13882                            newReceivers.remove(i);
13883                            i--;
13884                        }
13885                    }
13886                }
13887                if (newReceivers != null && newReceivers.size() == 0) {
13888                    newReceivers = null;
13889                }
13890                if (receivers == null) {
13891                    receivers = newReceivers;
13892                } else if (newReceivers != null) {
13893                    // We need to concatenate the additional receivers
13894                    // found with what we have do far.  This would be easy,
13895                    // but we also need to de-dup any receivers that are
13896                    // singleUser.
13897                    if (!scannedFirstReceivers) {
13898                        // Collect any single user receivers we had already retrieved.
13899                        scannedFirstReceivers = true;
13900                        for (int i=0; i<receivers.size(); i++) {
13901                            ResolveInfo ri = receivers.get(i);
13902                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13903                                ComponentName cn = new ComponentName(
13904                                        ri.activityInfo.packageName, ri.activityInfo.name);
13905                                if (singleUserReceivers == null) {
13906                                    singleUserReceivers = new HashSet<ComponentName>();
13907                                }
13908                                singleUserReceivers.add(cn);
13909                            }
13910                        }
13911                    }
13912                    // Add the new results to the existing results, tracking
13913                    // and de-dupping single user receivers.
13914                    for (int i=0; i<newReceivers.size(); i++) {
13915                        ResolveInfo ri = newReceivers.get(i);
13916                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13917                            ComponentName cn = new ComponentName(
13918                                    ri.activityInfo.packageName, ri.activityInfo.name);
13919                            if (singleUserReceivers == null) {
13920                                singleUserReceivers = new HashSet<ComponentName>();
13921                            }
13922                            if (!singleUserReceivers.contains(cn)) {
13923                                singleUserReceivers.add(cn);
13924                                receivers.add(ri);
13925                            }
13926                        } else {
13927                            receivers.add(ri);
13928                        }
13929                    }
13930                }
13931            }
13932        } catch (RemoteException ex) {
13933            // pm is in same process, this will never happen.
13934        }
13935        return receivers;
13936    }
13937
13938    private final int broadcastIntentLocked(ProcessRecord callerApp,
13939            String callerPackage, Intent intent, String resolvedType,
13940            IIntentReceiver resultTo, int resultCode, String resultData,
13941            Bundle map, String requiredPermission, int appOp,
13942            boolean ordered, boolean sticky, int callingPid, int callingUid,
13943            int userId) {
13944        intent = new Intent(intent);
13945
13946        // By default broadcasts do not go to stopped apps.
13947        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13948
13949        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13950            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13951            + " ordered=" + ordered + " userid=" + userId);
13952        if ((resultTo != null) && !ordered) {
13953            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13954        }
13955
13956        userId = handleIncomingUser(callingPid, callingUid, userId,
13957                true, false, "broadcast", callerPackage);
13958
13959        // Make sure that the user who is receiving this broadcast is started.
13960        // If not, we will just skip it.
13961        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13962            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13963                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13964                Slog.w(TAG, "Skipping broadcast of " + intent
13965                        + ": user " + userId + " is stopped");
13966                return ActivityManager.BROADCAST_SUCCESS;
13967            }
13968        }
13969
13970        /*
13971         * Prevent non-system code (defined here to be non-persistent
13972         * processes) from sending protected broadcasts.
13973         */
13974        int callingAppId = UserHandle.getAppId(callingUid);
13975        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13976                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13977                || callingUid == 0) {
13978            // Always okay.
13979        } else if (callerApp == null || !callerApp.persistent) {
13980            try {
13981                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13982                        intent.getAction())) {
13983                    String msg = "Permission Denial: not allowed to send broadcast "
13984                            + intent.getAction() + " from pid="
13985                            + callingPid + ", uid=" + callingUid;
13986                    Slog.w(TAG, msg);
13987                    throw new SecurityException(msg);
13988                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13989                    // Special case for compatibility: we don't want apps to send this,
13990                    // but historically it has not been protected and apps may be using it
13991                    // to poke their own app widget.  So, instead of making it protected,
13992                    // just limit it to the caller.
13993                    if (callerApp == null) {
13994                        String msg = "Permission Denial: not allowed to send broadcast "
13995                                + intent.getAction() + " from unknown caller.";
13996                        Slog.w(TAG, msg);
13997                        throw new SecurityException(msg);
13998                    } else if (intent.getComponent() != null) {
13999                        // They are good enough to send to an explicit component...  verify
14000                        // it is being sent to the calling app.
14001                        if (!intent.getComponent().getPackageName().equals(
14002                                callerApp.info.packageName)) {
14003                            String msg = "Permission Denial: not allowed to send broadcast "
14004                                    + intent.getAction() + " to "
14005                                    + intent.getComponent().getPackageName() + " from "
14006                                    + callerApp.info.packageName;
14007                            Slog.w(TAG, msg);
14008                            throw new SecurityException(msg);
14009                        }
14010                    } else {
14011                        // Limit broadcast to their own package.
14012                        intent.setPackage(callerApp.info.packageName);
14013                    }
14014                }
14015            } catch (RemoteException e) {
14016                Slog.w(TAG, "Remote exception", e);
14017                return ActivityManager.BROADCAST_SUCCESS;
14018            }
14019        }
14020
14021        // Handle special intents: if this broadcast is from the package
14022        // manager about a package being removed, we need to remove all of
14023        // its activities from the history stack.
14024        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14025                intent.getAction());
14026        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14027                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14028                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14029                || uidRemoved) {
14030            if (checkComponentPermission(
14031                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14032                    callingPid, callingUid, -1, true)
14033                    == PackageManager.PERMISSION_GRANTED) {
14034                if (uidRemoved) {
14035                    final Bundle intentExtras = intent.getExtras();
14036                    final int uid = intentExtras != null
14037                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14038                    if (uid >= 0) {
14039                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14040                        synchronized (bs) {
14041                            bs.removeUidStatsLocked(uid);
14042                        }
14043                        mAppOpsService.uidRemoved(uid);
14044                    }
14045                } else {
14046                    // If resources are unavailable just force stop all
14047                    // those packages and flush the attribute cache as well.
14048                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14049                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14050                        if (list != null && (list.length > 0)) {
14051                            for (String pkg : list) {
14052                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14053                                        "storage unmount");
14054                            }
14055                            sendPackageBroadcastLocked(
14056                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14057                        }
14058                    } else {
14059                        Uri data = intent.getData();
14060                        String ssp;
14061                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14062                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14063                                    intent.getAction());
14064                            boolean fullUninstall = removed &&
14065                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14066                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14067                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14068                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14069                                        false, fullUninstall, userId,
14070                                        removed ? "pkg removed" : "pkg changed");
14071                            }
14072                            if (removed) {
14073                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14074                                        new String[] {ssp}, userId);
14075                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14076                                    mAppOpsService.packageRemoved(
14077                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14078
14079                                    // Remove all permissions granted from/to this package
14080                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14081                                }
14082                            }
14083                        }
14084                    }
14085                }
14086            } else {
14087                String msg = "Permission Denial: " + intent.getAction()
14088                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14089                        + ", uid=" + callingUid + ")"
14090                        + " requires "
14091                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14092                Slog.w(TAG, msg);
14093                throw new SecurityException(msg);
14094            }
14095
14096        // Special case for adding a package: by default turn on compatibility
14097        // mode.
14098        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14099            Uri data = intent.getData();
14100            String ssp;
14101            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14102                mCompatModePackages.handlePackageAddedLocked(ssp,
14103                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14104            }
14105        }
14106
14107        /*
14108         * If this is the time zone changed action, queue up a message that will reset the timezone
14109         * of all currently running processes. This message will get queued up before the broadcast
14110         * happens.
14111         */
14112        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14113            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14114        }
14115
14116        /*
14117         * If the user set the time, let all running processes know.
14118         */
14119        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14120            final int is24Hour = intent.getBooleanExtra(
14121                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14122            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14123        }
14124
14125        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14126            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14127        }
14128
14129        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14130            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14131            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14132        }
14133
14134        // Add to the sticky list if requested.
14135        if (sticky) {
14136            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14137                    callingPid, callingUid)
14138                    != PackageManager.PERMISSION_GRANTED) {
14139                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14140                        + callingPid + ", uid=" + callingUid
14141                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14142                Slog.w(TAG, msg);
14143                throw new SecurityException(msg);
14144            }
14145            if (requiredPermission != null) {
14146                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14147                        + " and enforce permission " + requiredPermission);
14148                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14149            }
14150            if (intent.getComponent() != null) {
14151                throw new SecurityException(
14152                        "Sticky broadcasts can't target a specific component");
14153            }
14154            // We use userId directly here, since the "all" target is maintained
14155            // as a separate set of sticky broadcasts.
14156            if (userId != UserHandle.USER_ALL) {
14157                // But first, if this is not a broadcast to all users, then
14158                // make sure it doesn't conflict with an existing broadcast to
14159                // all users.
14160                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14161                        UserHandle.USER_ALL);
14162                if (stickies != null) {
14163                    ArrayList<Intent> list = stickies.get(intent.getAction());
14164                    if (list != null) {
14165                        int N = list.size();
14166                        int i;
14167                        for (i=0; i<N; i++) {
14168                            if (intent.filterEquals(list.get(i))) {
14169                                throw new IllegalArgumentException(
14170                                        "Sticky broadcast " + intent + " for user "
14171                                        + userId + " conflicts with existing global broadcast");
14172                            }
14173                        }
14174                    }
14175                }
14176            }
14177            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14178            if (stickies == null) {
14179                stickies = new ArrayMap<String, ArrayList<Intent>>();
14180                mStickyBroadcasts.put(userId, stickies);
14181            }
14182            ArrayList<Intent> list = stickies.get(intent.getAction());
14183            if (list == null) {
14184                list = new ArrayList<Intent>();
14185                stickies.put(intent.getAction(), list);
14186            }
14187            int N = list.size();
14188            int i;
14189            for (i=0; i<N; i++) {
14190                if (intent.filterEquals(list.get(i))) {
14191                    // This sticky already exists, replace it.
14192                    list.set(i, new Intent(intent));
14193                    break;
14194                }
14195            }
14196            if (i >= N) {
14197                list.add(new Intent(intent));
14198            }
14199        }
14200
14201        int[] users;
14202        if (userId == UserHandle.USER_ALL) {
14203            // Caller wants broadcast to go to all started users.
14204            users = mStartedUserArray;
14205        } else {
14206            // Caller wants broadcast to go to one specific user.
14207            users = new int[] {userId};
14208        }
14209
14210        // Figure out who all will receive this broadcast.
14211        List receivers = null;
14212        List<BroadcastFilter> registeredReceivers = null;
14213        // Need to resolve the intent to interested receivers...
14214        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14215                 == 0) {
14216            receivers = collectReceiverComponents(intent, resolvedType, users);
14217        }
14218        if (intent.getComponent() == null) {
14219            registeredReceivers = mReceiverResolver.queryIntent(intent,
14220                    resolvedType, false, userId);
14221        }
14222
14223        final boolean replacePending =
14224                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14225
14226        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14227                + " replacePending=" + replacePending);
14228
14229        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14230        if (!ordered && NR > 0) {
14231            // If we are not serializing this broadcast, then send the
14232            // registered receivers separately so they don't wait for the
14233            // components to be launched.
14234            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14235            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14236                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14237                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14238                    ordered, sticky, false, userId);
14239            if (DEBUG_BROADCAST) Slog.v(
14240                    TAG, "Enqueueing parallel broadcast " + r);
14241            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14242            if (!replaced) {
14243                queue.enqueueParallelBroadcastLocked(r);
14244                queue.scheduleBroadcastsLocked();
14245            }
14246            registeredReceivers = null;
14247            NR = 0;
14248        }
14249
14250        // Merge into one list.
14251        int ir = 0;
14252        if (receivers != null) {
14253            // A special case for PACKAGE_ADDED: do not allow the package
14254            // being added to see this broadcast.  This prevents them from
14255            // using this as a back door to get run as soon as they are
14256            // installed.  Maybe in the future we want to have a special install
14257            // broadcast or such for apps, but we'd like to deliberately make
14258            // this decision.
14259            String skipPackages[] = null;
14260            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14261                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14262                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14263                Uri data = intent.getData();
14264                if (data != null) {
14265                    String pkgName = data.getSchemeSpecificPart();
14266                    if (pkgName != null) {
14267                        skipPackages = new String[] { pkgName };
14268                    }
14269                }
14270            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14271                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14272            }
14273            if (skipPackages != null && (skipPackages.length > 0)) {
14274                for (String skipPackage : skipPackages) {
14275                    if (skipPackage != null) {
14276                        int NT = receivers.size();
14277                        for (int it=0; it<NT; it++) {
14278                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14279                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14280                                receivers.remove(it);
14281                                it--;
14282                                NT--;
14283                            }
14284                        }
14285                    }
14286                }
14287            }
14288
14289            int NT = receivers != null ? receivers.size() : 0;
14290            int it = 0;
14291            ResolveInfo curt = null;
14292            BroadcastFilter curr = null;
14293            while (it < NT && ir < NR) {
14294                if (curt == null) {
14295                    curt = (ResolveInfo)receivers.get(it);
14296                }
14297                if (curr == null) {
14298                    curr = registeredReceivers.get(ir);
14299                }
14300                if (curr.getPriority() >= curt.priority) {
14301                    // Insert this broadcast record into the final list.
14302                    receivers.add(it, curr);
14303                    ir++;
14304                    curr = null;
14305                    it++;
14306                    NT++;
14307                } else {
14308                    // Skip to the next ResolveInfo in the final list.
14309                    it++;
14310                    curt = null;
14311                }
14312            }
14313        }
14314        while (ir < NR) {
14315            if (receivers == null) {
14316                receivers = new ArrayList();
14317            }
14318            receivers.add(registeredReceivers.get(ir));
14319            ir++;
14320        }
14321
14322        if ((receivers != null && receivers.size() > 0)
14323                || resultTo != null) {
14324            BroadcastQueue queue = broadcastQueueForIntent(intent);
14325            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14326                    callerPackage, callingPid, callingUid, resolvedType,
14327                    requiredPermission, appOp, receivers, resultTo, resultCode,
14328                    resultData, map, ordered, sticky, false, userId);
14329            if (DEBUG_BROADCAST) Slog.v(
14330                    TAG, "Enqueueing ordered broadcast " + r
14331                    + ": prev had " + queue.mOrderedBroadcasts.size());
14332            if (DEBUG_BROADCAST) {
14333                int seq = r.intent.getIntExtra("seq", -1);
14334                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14335            }
14336            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14337            if (!replaced) {
14338                queue.enqueueOrderedBroadcastLocked(r);
14339                queue.scheduleBroadcastsLocked();
14340            }
14341        }
14342
14343        return ActivityManager.BROADCAST_SUCCESS;
14344    }
14345
14346    final Intent verifyBroadcastLocked(Intent intent) {
14347        // Refuse possible leaked file descriptors
14348        if (intent != null && intent.hasFileDescriptors() == true) {
14349            throw new IllegalArgumentException("File descriptors passed in Intent");
14350        }
14351
14352        int flags = intent.getFlags();
14353
14354        if (!mProcessesReady) {
14355            // if the caller really truly claims to know what they're doing, go
14356            // ahead and allow the broadcast without launching any receivers
14357            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14358                intent = new Intent(intent);
14359                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14360            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14361                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14362                        + " before boot completion");
14363                throw new IllegalStateException("Cannot broadcast before boot completed");
14364            }
14365        }
14366
14367        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14368            throw new IllegalArgumentException(
14369                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14370        }
14371
14372        return intent;
14373    }
14374
14375    public final int broadcastIntent(IApplicationThread caller,
14376            Intent intent, String resolvedType, IIntentReceiver resultTo,
14377            int resultCode, String resultData, Bundle map,
14378            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14379        enforceNotIsolatedCaller("broadcastIntent");
14380        synchronized(this) {
14381            intent = verifyBroadcastLocked(intent);
14382
14383            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14384            final int callingPid = Binder.getCallingPid();
14385            final int callingUid = Binder.getCallingUid();
14386            final long origId = Binder.clearCallingIdentity();
14387            int res = broadcastIntentLocked(callerApp,
14388                    callerApp != null ? callerApp.info.packageName : null,
14389                    intent, resolvedType, resultTo,
14390                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14391                    callingPid, callingUid, userId);
14392            Binder.restoreCallingIdentity(origId);
14393            return res;
14394        }
14395    }
14396
14397    int broadcastIntentInPackage(String packageName, int uid,
14398            Intent intent, String resolvedType, IIntentReceiver resultTo,
14399            int resultCode, String resultData, Bundle map,
14400            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14401        synchronized(this) {
14402            intent = verifyBroadcastLocked(intent);
14403
14404            final long origId = Binder.clearCallingIdentity();
14405            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14406                    resultTo, resultCode, resultData, map, requiredPermission,
14407                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14408            Binder.restoreCallingIdentity(origId);
14409            return res;
14410        }
14411    }
14412
14413    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14414        // Refuse possible leaked file descriptors
14415        if (intent != null && intent.hasFileDescriptors() == true) {
14416            throw new IllegalArgumentException("File descriptors passed in Intent");
14417        }
14418
14419        userId = handleIncomingUser(Binder.getCallingPid(),
14420                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14421
14422        synchronized(this) {
14423            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14424                    != PackageManager.PERMISSION_GRANTED) {
14425                String msg = "Permission Denial: unbroadcastIntent() from pid="
14426                        + Binder.getCallingPid()
14427                        + ", uid=" + Binder.getCallingUid()
14428                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14429                Slog.w(TAG, msg);
14430                throw new SecurityException(msg);
14431            }
14432            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14433            if (stickies != null) {
14434                ArrayList<Intent> list = stickies.get(intent.getAction());
14435                if (list != null) {
14436                    int N = list.size();
14437                    int i;
14438                    for (i=0; i<N; i++) {
14439                        if (intent.filterEquals(list.get(i))) {
14440                            list.remove(i);
14441                            break;
14442                        }
14443                    }
14444                    if (list.size() <= 0) {
14445                        stickies.remove(intent.getAction());
14446                    }
14447                }
14448                if (stickies.size() <= 0) {
14449                    mStickyBroadcasts.remove(userId);
14450                }
14451            }
14452        }
14453    }
14454
14455    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14456            String resultData, Bundle resultExtras, boolean resultAbort) {
14457        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14458        if (r == null) {
14459            Slog.w(TAG, "finishReceiver called but not found on queue");
14460            return false;
14461        }
14462
14463        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14464    }
14465
14466    void backgroundServicesFinishedLocked(int userId) {
14467        for (BroadcastQueue queue : mBroadcastQueues) {
14468            queue.backgroundServicesFinishedLocked(userId);
14469        }
14470    }
14471
14472    public void finishReceiver(IBinder who, int resultCode, String resultData,
14473            Bundle resultExtras, boolean resultAbort) {
14474        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14475
14476        // Refuse possible leaked file descriptors
14477        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14478            throw new IllegalArgumentException("File descriptors passed in Bundle");
14479        }
14480
14481        final long origId = Binder.clearCallingIdentity();
14482        try {
14483            boolean doNext = false;
14484            BroadcastRecord r;
14485
14486            synchronized(this) {
14487                r = broadcastRecordForReceiverLocked(who);
14488                if (r != null) {
14489                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14490                        resultData, resultExtras, resultAbort, true);
14491                }
14492            }
14493
14494            if (doNext) {
14495                r.queue.processNextBroadcast(false);
14496            }
14497            trimApplications();
14498        } finally {
14499            Binder.restoreCallingIdentity(origId);
14500        }
14501    }
14502
14503    // =========================================================
14504    // INSTRUMENTATION
14505    // =========================================================
14506
14507    public boolean startInstrumentation(ComponentName className,
14508            String profileFile, int flags, Bundle arguments,
14509            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14510            int userId, String abiOverride) {
14511        enforceNotIsolatedCaller("startInstrumentation");
14512        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14513                userId, false, true, "startInstrumentation", null);
14514        // Refuse possible leaked file descriptors
14515        if (arguments != null && arguments.hasFileDescriptors()) {
14516            throw new IllegalArgumentException("File descriptors passed in Bundle");
14517        }
14518
14519        synchronized(this) {
14520            InstrumentationInfo ii = null;
14521            ApplicationInfo ai = null;
14522            try {
14523                ii = mContext.getPackageManager().getInstrumentationInfo(
14524                    className, STOCK_PM_FLAGS);
14525                ai = AppGlobals.getPackageManager().getApplicationInfo(
14526                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14527            } catch (PackageManager.NameNotFoundException e) {
14528            } catch (RemoteException e) {
14529            }
14530            if (ii == null) {
14531                reportStartInstrumentationFailure(watcher, className,
14532                        "Unable to find instrumentation info for: " + className);
14533                return false;
14534            }
14535            if (ai == null) {
14536                reportStartInstrumentationFailure(watcher, className,
14537                        "Unable to find instrumentation target package: " + ii.targetPackage);
14538                return false;
14539            }
14540
14541            int match = mContext.getPackageManager().checkSignatures(
14542                    ii.targetPackage, ii.packageName);
14543            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14544                String msg = "Permission Denial: starting instrumentation "
14545                        + className + " from pid="
14546                        + Binder.getCallingPid()
14547                        + ", uid=" + Binder.getCallingPid()
14548                        + " not allowed because package " + ii.packageName
14549                        + " does not have a signature matching the target "
14550                        + ii.targetPackage;
14551                reportStartInstrumentationFailure(watcher, className, msg);
14552                throw new SecurityException(msg);
14553            }
14554
14555            final long origId = Binder.clearCallingIdentity();
14556            // Instrumentation can kill and relaunch even persistent processes
14557            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14558                    "start instr");
14559            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14560            app.instrumentationClass = className;
14561            app.instrumentationInfo = ai;
14562            app.instrumentationProfileFile = profileFile;
14563            app.instrumentationArguments = arguments;
14564            app.instrumentationWatcher = watcher;
14565            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14566            app.instrumentationResultClass = className;
14567            Binder.restoreCallingIdentity(origId);
14568        }
14569
14570        return true;
14571    }
14572
14573    /**
14574     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14575     * error to the logs, but if somebody is watching, send the report there too.  This enables
14576     * the "am" command to report errors with more information.
14577     *
14578     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14579     * @param cn The component name of the instrumentation.
14580     * @param report The error report.
14581     */
14582    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14583            ComponentName cn, String report) {
14584        Slog.w(TAG, report);
14585        try {
14586            if (watcher != null) {
14587                Bundle results = new Bundle();
14588                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14589                results.putString("Error", report);
14590                watcher.instrumentationStatus(cn, -1, results);
14591            }
14592        } catch (RemoteException e) {
14593            Slog.w(TAG, e);
14594        }
14595    }
14596
14597    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14598        if (app.instrumentationWatcher != null) {
14599            try {
14600                // NOTE:  IInstrumentationWatcher *must* be oneway here
14601                app.instrumentationWatcher.instrumentationFinished(
14602                    app.instrumentationClass,
14603                    resultCode,
14604                    results);
14605            } catch (RemoteException e) {
14606            }
14607        }
14608        if (app.instrumentationUiAutomationConnection != null) {
14609            try {
14610                app.instrumentationUiAutomationConnection.shutdown();
14611            } catch (RemoteException re) {
14612                /* ignore */
14613            }
14614            // Only a UiAutomation can set this flag and now that
14615            // it is finished we make sure it is reset to its default.
14616            mUserIsMonkey = false;
14617        }
14618        app.instrumentationWatcher = null;
14619        app.instrumentationUiAutomationConnection = null;
14620        app.instrumentationClass = null;
14621        app.instrumentationInfo = null;
14622        app.instrumentationProfileFile = null;
14623        app.instrumentationArguments = null;
14624
14625        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14626                "finished inst");
14627    }
14628
14629    public void finishInstrumentation(IApplicationThread target,
14630            int resultCode, Bundle results) {
14631        int userId = UserHandle.getCallingUserId();
14632        // Refuse possible leaked file descriptors
14633        if (results != null && results.hasFileDescriptors()) {
14634            throw new IllegalArgumentException("File descriptors passed in Intent");
14635        }
14636
14637        synchronized(this) {
14638            ProcessRecord app = getRecordForAppLocked(target);
14639            if (app == null) {
14640                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14641                return;
14642            }
14643            final long origId = Binder.clearCallingIdentity();
14644            finishInstrumentationLocked(app, resultCode, results);
14645            Binder.restoreCallingIdentity(origId);
14646        }
14647    }
14648
14649    // =========================================================
14650    // CONFIGURATION
14651    // =========================================================
14652
14653    public ConfigurationInfo getDeviceConfigurationInfo() {
14654        ConfigurationInfo config = new ConfigurationInfo();
14655        synchronized (this) {
14656            config.reqTouchScreen = mConfiguration.touchscreen;
14657            config.reqKeyboardType = mConfiguration.keyboard;
14658            config.reqNavigation = mConfiguration.navigation;
14659            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14660                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14661                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14662            }
14663            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14664                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14665                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14666            }
14667            config.reqGlEsVersion = GL_ES_VERSION;
14668        }
14669        return config;
14670    }
14671
14672    ActivityStack getFocusedStack() {
14673        return mStackSupervisor.getFocusedStack();
14674    }
14675
14676    public Configuration getConfiguration() {
14677        Configuration ci;
14678        synchronized(this) {
14679            ci = new Configuration(mConfiguration);
14680        }
14681        return ci;
14682    }
14683
14684    public void updatePersistentConfiguration(Configuration values) {
14685        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14686                "updateConfiguration()");
14687        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14688                "updateConfiguration()");
14689        if (values == null) {
14690            throw new NullPointerException("Configuration must not be null");
14691        }
14692
14693        synchronized(this) {
14694            final long origId = Binder.clearCallingIdentity();
14695            updateConfigurationLocked(values, null, true, false);
14696            Binder.restoreCallingIdentity(origId);
14697        }
14698    }
14699
14700    public void updateConfiguration(Configuration values) {
14701        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14702                "updateConfiguration()");
14703
14704        synchronized(this) {
14705            if (values == null && mWindowManager != null) {
14706                // sentinel: fetch the current configuration from the window manager
14707                values = mWindowManager.computeNewConfiguration();
14708            }
14709
14710            if (mWindowManager != null) {
14711                mProcessList.applyDisplaySize(mWindowManager);
14712            }
14713
14714            final long origId = Binder.clearCallingIdentity();
14715            if (values != null) {
14716                Settings.System.clearConfiguration(values);
14717            }
14718            updateConfigurationLocked(values, null, false, false);
14719            Binder.restoreCallingIdentity(origId);
14720        }
14721    }
14722
14723    /**
14724     * Do either or both things: (1) change the current configuration, and (2)
14725     * make sure the given activity is running with the (now) current
14726     * configuration.  Returns true if the activity has been left running, or
14727     * false if <var>starting</var> is being destroyed to match the new
14728     * configuration.
14729     * @param persistent TODO
14730     */
14731    boolean updateConfigurationLocked(Configuration values,
14732            ActivityRecord starting, boolean persistent, boolean initLocale) {
14733        int changes = 0;
14734
14735        if (values != null) {
14736            Configuration newConfig = new Configuration(mConfiguration);
14737            changes = newConfig.updateFrom(values);
14738            if (changes != 0) {
14739                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14740                    Slog.i(TAG, "Updating configuration to: " + values);
14741                }
14742
14743                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14744
14745                if (values.locale != null && !initLocale) {
14746                    saveLocaleLocked(values.locale,
14747                                     !values.locale.equals(mConfiguration.locale),
14748                                     values.userSetLocale);
14749                }
14750
14751                mConfigurationSeq++;
14752                if (mConfigurationSeq <= 0) {
14753                    mConfigurationSeq = 1;
14754                }
14755                newConfig.seq = mConfigurationSeq;
14756                mConfiguration = newConfig;
14757                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14758                mUsageStatsService.noteStartConfig(newConfig);
14759
14760                final Configuration configCopy = new Configuration(mConfiguration);
14761
14762                // TODO: If our config changes, should we auto dismiss any currently
14763                // showing dialogs?
14764                mShowDialogs = shouldShowDialogs(newConfig);
14765
14766                AttributeCache ac = AttributeCache.instance();
14767                if (ac != null) {
14768                    ac.updateConfiguration(configCopy);
14769                }
14770
14771                // Make sure all resources in our process are updated
14772                // right now, so that anyone who is going to retrieve
14773                // resource values after we return will be sure to get
14774                // the new ones.  This is especially important during
14775                // boot, where the first config change needs to guarantee
14776                // all resources have that config before following boot
14777                // code is executed.
14778                mSystemThread.applyConfigurationToResources(configCopy);
14779
14780                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14781                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14782                    msg.obj = new Configuration(configCopy);
14783                    mHandler.sendMessage(msg);
14784                }
14785
14786                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14787                    ProcessRecord app = mLruProcesses.get(i);
14788                    try {
14789                        if (app.thread != null) {
14790                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14791                                    + app.processName + " new config " + mConfiguration);
14792                            app.thread.scheduleConfigurationChanged(configCopy);
14793                        }
14794                    } catch (Exception e) {
14795                    }
14796                }
14797                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14798                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14799                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14800                        | Intent.FLAG_RECEIVER_FOREGROUND);
14801                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14802                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14803                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14804                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14805                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14806                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14807                    broadcastIntentLocked(null, null, intent,
14808                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14809                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14810                }
14811            }
14812        }
14813
14814        boolean kept = true;
14815        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14816        // mainStack is null during startup.
14817        if (mainStack != null) {
14818            if (changes != 0 && starting == null) {
14819                // If the configuration changed, and the caller is not already
14820                // in the process of starting an activity, then find the top
14821                // activity to check if its configuration needs to change.
14822                starting = mainStack.topRunningActivityLocked(null);
14823            }
14824
14825            if (starting != null) {
14826                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14827                // And we need to make sure at this point that all other activities
14828                // are made visible with the correct configuration.
14829                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14830            }
14831        }
14832
14833        if (values != null && mWindowManager != null) {
14834            mWindowManager.setNewConfiguration(mConfiguration);
14835        }
14836
14837        return kept;
14838    }
14839
14840    /**
14841     * Decide based on the configuration whether we should shouw the ANR,
14842     * crash, etc dialogs.  The idea is that if there is no affordnace to
14843     * press the on-screen buttons, we shouldn't show the dialog.
14844     *
14845     * A thought: SystemUI might also want to get told about this, the Power
14846     * dialog / global actions also might want different behaviors.
14847     */
14848    private static final boolean shouldShowDialogs(Configuration config) {
14849        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14850                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14851    }
14852
14853    /**
14854     * Save the locale.  You must be inside a synchronized (this) block.
14855     */
14856    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14857        if(isDiff) {
14858            SystemProperties.set("user.language", l.getLanguage());
14859            SystemProperties.set("user.region", l.getCountry());
14860        }
14861
14862        if(isPersist) {
14863            SystemProperties.set("persist.sys.language", l.getLanguage());
14864            SystemProperties.set("persist.sys.country", l.getCountry());
14865            SystemProperties.set("persist.sys.localevar", l.getVariant());
14866        }
14867    }
14868
14869    @Override
14870    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14871        ActivityRecord srec = ActivityRecord.forToken(token);
14872        return srec != null && srec.task.affinity != null &&
14873                srec.task.affinity.equals(destAffinity);
14874    }
14875
14876    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14877            Intent resultData) {
14878
14879        synchronized (this) {
14880            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14881            if (stack != null) {
14882                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14883            }
14884            return false;
14885        }
14886    }
14887
14888    public int getLaunchedFromUid(IBinder activityToken) {
14889        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14890        if (srec == null) {
14891            return -1;
14892        }
14893        return srec.launchedFromUid;
14894    }
14895
14896    public String getLaunchedFromPackage(IBinder activityToken) {
14897        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14898        if (srec == null) {
14899            return null;
14900        }
14901        return srec.launchedFromPackage;
14902    }
14903
14904    // =========================================================
14905    // LIFETIME MANAGEMENT
14906    // =========================================================
14907
14908    // Returns which broadcast queue the app is the current [or imminent] receiver
14909    // on, or 'null' if the app is not an active broadcast recipient.
14910    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14911        BroadcastRecord r = app.curReceiver;
14912        if (r != null) {
14913            return r.queue;
14914        }
14915
14916        // It's not the current receiver, but it might be starting up to become one
14917        synchronized (this) {
14918            for (BroadcastQueue queue : mBroadcastQueues) {
14919                r = queue.mPendingBroadcast;
14920                if (r != null && r.curApp == app) {
14921                    // found it; report which queue it's in
14922                    return queue;
14923                }
14924            }
14925        }
14926
14927        return null;
14928    }
14929
14930    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14931            boolean doingAll, long now) {
14932        if (mAdjSeq == app.adjSeq) {
14933            // This adjustment has already been computed.
14934            return app.curRawAdj;
14935        }
14936
14937        if (app.thread == null) {
14938            app.adjSeq = mAdjSeq;
14939            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14940            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14941            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14942        }
14943
14944        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14945        app.adjSource = null;
14946        app.adjTarget = null;
14947        app.empty = false;
14948        app.cached = false;
14949
14950        final int activitiesSize = app.activities.size();
14951
14952        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14953            // The max adjustment doesn't allow this app to be anything
14954            // below foreground, so it is not worth doing work for it.
14955            app.adjType = "fixed";
14956            app.adjSeq = mAdjSeq;
14957            app.curRawAdj = app.maxAdj;
14958            app.foregroundActivities = false;
14959            app.keeping = true;
14960            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14961            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14962            // System processes can do UI, and when they do we want to have
14963            // them trim their memory after the user leaves the UI.  To
14964            // facilitate this, here we need to determine whether or not it
14965            // is currently showing UI.
14966            app.systemNoUi = true;
14967            if (app == TOP_APP) {
14968                app.systemNoUi = false;
14969            } else if (activitiesSize > 0) {
14970                for (int j = 0; j < activitiesSize; j++) {
14971                    final ActivityRecord r = app.activities.get(j);
14972                    if (r.visible) {
14973                        app.systemNoUi = false;
14974                    }
14975                }
14976            }
14977            if (!app.systemNoUi) {
14978                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14979            }
14980            return (app.curAdj=app.maxAdj);
14981        }
14982
14983        app.keeping = false;
14984        app.systemNoUi = false;
14985
14986        // Determine the importance of the process, starting with most
14987        // important to least, and assign an appropriate OOM adjustment.
14988        int adj;
14989        int schedGroup;
14990        int procState;
14991        boolean foregroundActivities = false;
14992        boolean interesting = false;
14993        BroadcastQueue queue;
14994        if (app == TOP_APP) {
14995            // The last app on the list is the foreground app.
14996            adj = ProcessList.FOREGROUND_APP_ADJ;
14997            schedGroup = Process.THREAD_GROUP_DEFAULT;
14998            app.adjType = "top-activity";
14999            foregroundActivities = true;
15000            interesting = true;
15001            procState = ActivityManager.PROCESS_STATE_TOP;
15002        } else if (app.instrumentationClass != null) {
15003            // Don't want to kill running instrumentation.
15004            adj = ProcessList.FOREGROUND_APP_ADJ;
15005            schedGroup = Process.THREAD_GROUP_DEFAULT;
15006            app.adjType = "instrumentation";
15007            interesting = true;
15008            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15009        } else if ((queue = isReceivingBroadcast(app)) != null) {
15010            // An app that is currently receiving a broadcast also
15011            // counts as being in the foreground for OOM killer purposes.
15012            // It's placed in a sched group based on the nature of the
15013            // broadcast as reflected by which queue it's active in.
15014            adj = ProcessList.FOREGROUND_APP_ADJ;
15015            schedGroup = (queue == mFgBroadcastQueue)
15016                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15017            app.adjType = "broadcast";
15018            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15019        } else if (app.executingServices.size() > 0) {
15020            // An app that is currently executing a service callback also
15021            // counts as being in the foreground.
15022            adj = ProcessList.FOREGROUND_APP_ADJ;
15023            schedGroup = app.execServicesFg ?
15024                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15025            app.adjType = "exec-service";
15026            procState = ActivityManager.PROCESS_STATE_SERVICE;
15027            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15028        } else {
15029            // As far as we know the process is empty.  We may change our mind later.
15030            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15031            // At this point we don't actually know the adjustment.  Use the cached adj
15032            // value that the caller wants us to.
15033            adj = cachedAdj;
15034            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15035            app.cached = true;
15036            app.empty = true;
15037            app.adjType = "cch-empty";
15038        }
15039
15040        // Examine all activities if not already foreground.
15041        if (!foregroundActivities && activitiesSize > 0) {
15042            for (int j = 0; j < activitiesSize; j++) {
15043                final ActivityRecord r = app.activities.get(j);
15044                if (r.app != app) {
15045                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15046                            + app + "?!?");
15047                    continue;
15048                }
15049                if (r.visible) {
15050                    // App has a visible activity; only upgrade adjustment.
15051                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15052                        adj = ProcessList.VISIBLE_APP_ADJ;
15053                        app.adjType = "visible";
15054                    }
15055                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15056                        procState = ActivityManager.PROCESS_STATE_TOP;
15057                    }
15058                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15059                    app.cached = false;
15060                    app.empty = false;
15061                    foregroundActivities = true;
15062                    break;
15063                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15064                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15065                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15066                        app.adjType = "pausing";
15067                    }
15068                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15069                        procState = ActivityManager.PROCESS_STATE_TOP;
15070                    }
15071                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15072                    app.cached = false;
15073                    app.empty = false;
15074                    foregroundActivities = true;
15075                } else if (r.state == ActivityState.STOPPING) {
15076                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15077                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15078                        app.adjType = "stopping";
15079                    }
15080                    // For the process state, we will at this point consider the
15081                    // process to be cached.  It will be cached either as an activity
15082                    // or empty depending on whether the activity is finishing.  We do
15083                    // this so that we can treat the process as cached for purposes of
15084                    // memory trimming (determing current memory level, trim command to
15085                    // send to process) since there can be an arbitrary number of stopping
15086                    // processes and they should soon all go into the cached state.
15087                    if (!r.finishing) {
15088                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15089                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15090                        }
15091                    }
15092                    app.cached = false;
15093                    app.empty = false;
15094                    foregroundActivities = true;
15095                } else {
15096                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15097                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15098                        app.adjType = "cch-act";
15099                    }
15100                }
15101            }
15102        }
15103
15104        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15105            if (app.foregroundServices) {
15106                // The user is aware of this app, so make it visible.
15107                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15108                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15109                app.cached = false;
15110                app.adjType = "fg-service";
15111                schedGroup = Process.THREAD_GROUP_DEFAULT;
15112            } else if (app.forcingToForeground != null) {
15113                // The user is aware of this app, so make it visible.
15114                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15115                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15116                app.cached = false;
15117                app.adjType = "force-fg";
15118                app.adjSource = app.forcingToForeground;
15119                schedGroup = Process.THREAD_GROUP_DEFAULT;
15120            }
15121        }
15122
15123        if (app.foregroundServices) {
15124            interesting = true;
15125        }
15126
15127        if (app == mHeavyWeightProcess) {
15128            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15129                // We don't want to kill the current heavy-weight process.
15130                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15131                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15132                app.cached = false;
15133                app.adjType = "heavy";
15134            }
15135            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15136                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15137            }
15138        }
15139
15140        if (app == mHomeProcess) {
15141            if (adj > ProcessList.HOME_APP_ADJ) {
15142                // This process is hosting what we currently consider to be the
15143                // home app, so we don't want to let it go into the background.
15144                adj = ProcessList.HOME_APP_ADJ;
15145                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15146                app.cached = false;
15147                app.adjType = "home";
15148            }
15149            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15150                procState = ActivityManager.PROCESS_STATE_HOME;
15151            }
15152        }
15153
15154        if (app == mPreviousProcess && app.activities.size() > 0) {
15155            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15156                // This was the previous process that showed UI to the user.
15157                // We want to try to keep it around more aggressively, to give
15158                // a good experience around switching between two apps.
15159                adj = ProcessList.PREVIOUS_APP_ADJ;
15160                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15161                app.cached = false;
15162                app.adjType = "previous";
15163            }
15164            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15165                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15166            }
15167        }
15168
15169        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15170                + " reason=" + app.adjType);
15171
15172        // By default, we use the computed adjustment.  It may be changed if
15173        // there are applications dependent on our services or providers, but
15174        // this gives us a baseline and makes sure we don't get into an
15175        // infinite recursion.
15176        app.adjSeq = mAdjSeq;
15177        app.curRawAdj = adj;
15178        app.hasStartedServices = false;
15179
15180        if (mBackupTarget != null && app == mBackupTarget.app) {
15181            // If possible we want to avoid killing apps while they're being backed up
15182            if (adj > ProcessList.BACKUP_APP_ADJ) {
15183                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15184                adj = ProcessList.BACKUP_APP_ADJ;
15185                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15186                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15187                }
15188                app.adjType = "backup";
15189                app.cached = false;
15190            }
15191            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15192                procState = ActivityManager.PROCESS_STATE_BACKUP;
15193            }
15194        }
15195
15196        boolean mayBeTop = false;
15197
15198        for (int is = app.services.size()-1;
15199                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15200                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15201                        || procState > ActivityManager.PROCESS_STATE_TOP);
15202                is--) {
15203            ServiceRecord s = app.services.valueAt(is);
15204            if (s.startRequested) {
15205                app.hasStartedServices = true;
15206                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15207                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15208                }
15209                if (app.hasShownUi && app != mHomeProcess) {
15210                    // If this process has shown some UI, let it immediately
15211                    // go to the LRU list because it may be pretty heavy with
15212                    // UI stuff.  We'll tag it with a label just to help
15213                    // debug and understand what is going on.
15214                    if (adj > ProcessList.SERVICE_ADJ) {
15215                        app.adjType = "cch-started-ui-services";
15216                    }
15217                } else {
15218                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15219                        // This service has seen some activity within
15220                        // recent memory, so we will keep its process ahead
15221                        // of the background processes.
15222                        if (adj > ProcessList.SERVICE_ADJ) {
15223                            adj = ProcessList.SERVICE_ADJ;
15224                            app.adjType = "started-services";
15225                            app.cached = false;
15226                        }
15227                    }
15228                    // If we have let the service slide into the background
15229                    // state, still have some text describing what it is doing
15230                    // even though the service no longer has an impact.
15231                    if (adj > ProcessList.SERVICE_ADJ) {
15232                        app.adjType = "cch-started-services";
15233                    }
15234                }
15235                // Don't kill this process because it is doing work; it
15236                // has said it is doing work.
15237                app.keeping = true;
15238            }
15239            for (int conni = s.connections.size()-1;
15240                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15241                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15242                            || procState > ActivityManager.PROCESS_STATE_TOP);
15243                    conni--) {
15244                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15245                for (int i = 0;
15246                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15247                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15248                                || procState > ActivityManager.PROCESS_STATE_TOP);
15249                        i++) {
15250                    // XXX should compute this based on the max of
15251                    // all connected clients.
15252                    ConnectionRecord cr = clist.get(i);
15253                    if (cr.binding.client == app) {
15254                        // Binding to ourself is not interesting.
15255                        continue;
15256                    }
15257                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15258                        ProcessRecord client = cr.binding.client;
15259                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15260                                TOP_APP, doingAll, now);
15261                        int clientProcState = client.curProcState;
15262                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15263                            // If the other app is cached for any reason, for purposes here
15264                            // we are going to consider it empty.  The specific cached state
15265                            // doesn't propagate except under certain conditions.
15266                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15267                        }
15268                        String adjType = null;
15269                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15270                            // Not doing bind OOM management, so treat
15271                            // this guy more like a started service.
15272                            if (app.hasShownUi && app != mHomeProcess) {
15273                                // If this process has shown some UI, let it immediately
15274                                // go to the LRU list because it may be pretty heavy with
15275                                // UI stuff.  We'll tag it with a label just to help
15276                                // debug and understand what is going on.
15277                                if (adj > clientAdj) {
15278                                    adjType = "cch-bound-ui-services";
15279                                }
15280                                app.cached = false;
15281                                clientAdj = adj;
15282                                clientProcState = procState;
15283                            } else {
15284                                if (now >= (s.lastActivity
15285                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15286                                    // This service has not seen activity within
15287                                    // recent memory, so allow it to drop to the
15288                                    // LRU list if there is no other reason to keep
15289                                    // it around.  We'll also tag it with a label just
15290                                    // to help debug and undertand what is going on.
15291                                    if (adj > clientAdj) {
15292                                        adjType = "cch-bound-services";
15293                                    }
15294                                    clientAdj = adj;
15295                                }
15296                            }
15297                        }
15298                        if (adj > clientAdj) {
15299                            // If this process has recently shown UI, and
15300                            // the process that is binding to it is less
15301                            // important than being visible, then we don't
15302                            // care about the binding as much as we care
15303                            // about letting this process get into the LRU
15304                            // list to be killed and restarted if needed for
15305                            // memory.
15306                            if (app.hasShownUi && app != mHomeProcess
15307                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15308                                adjType = "cch-bound-ui-services";
15309                            } else {
15310                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15311                                        |Context.BIND_IMPORTANT)) != 0) {
15312                                    adj = clientAdj;
15313                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15314                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15315                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15316                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15317                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15318                                    adj = clientAdj;
15319                                } else {
15320                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15321                                        adj = ProcessList.VISIBLE_APP_ADJ;
15322                                    }
15323                                }
15324                                if (!client.cached) {
15325                                    app.cached = false;
15326                                }
15327                                if (client.keeping) {
15328                                    app.keeping = true;
15329                                }
15330                                adjType = "service";
15331                            }
15332                        }
15333                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15334                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15335                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15336                            }
15337                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15338                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15339                                    // Special handling of clients who are in the top state.
15340                                    // We *may* want to consider this process to be in the
15341                                    // top state as well, but only if there is not another
15342                                    // reason for it to be running.  Being on the top is a
15343                                    // special state, meaning you are specifically running
15344                                    // for the current top app.  If the process is already
15345                                    // running in the background for some other reason, it
15346                                    // is more important to continue considering it to be
15347                                    // in the background state.
15348                                    mayBeTop = true;
15349                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15350                                } else {
15351                                    // Special handling for above-top states (persistent
15352                                    // processes).  These should not bring the current process
15353                                    // into the top state, since they are not on top.  Instead
15354                                    // give them the best state after that.
15355                                    clientProcState =
15356                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15357                                }
15358                            }
15359                        } else {
15360                            if (clientProcState <
15361                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15362                                clientProcState =
15363                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15364                            }
15365                        }
15366                        if (procState > clientProcState) {
15367                            procState = clientProcState;
15368                        }
15369                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15370                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15371                            app.pendingUiClean = true;
15372                        }
15373                        if (adjType != null) {
15374                            app.adjType = adjType;
15375                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15376                                    .REASON_SERVICE_IN_USE;
15377                            app.adjSource = cr.binding.client;
15378                            app.adjSourceOom = clientAdj;
15379                            app.adjTarget = s.name;
15380                        }
15381                    }
15382                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15383                        app.treatLikeActivity = true;
15384                    }
15385                    final ActivityRecord a = cr.activity;
15386                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15387                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15388                                (a.visible || a.state == ActivityState.RESUMED
15389                                 || a.state == ActivityState.PAUSING)) {
15390                            adj = ProcessList.FOREGROUND_APP_ADJ;
15391                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15392                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15393                            }
15394                            app.cached = false;
15395                            app.adjType = "service";
15396                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15397                                    .REASON_SERVICE_IN_USE;
15398                            app.adjSource = a;
15399                            app.adjSourceOom = adj;
15400                            app.adjTarget = s.name;
15401                        }
15402                    }
15403                }
15404            }
15405        }
15406
15407        for (int provi = app.pubProviders.size()-1;
15408                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15409                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15410                        || procState > ActivityManager.PROCESS_STATE_TOP);
15411                provi--) {
15412            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15413            for (int i = cpr.connections.size()-1;
15414                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15415                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15416                            || procState > ActivityManager.PROCESS_STATE_TOP);
15417                    i--) {
15418                ContentProviderConnection conn = cpr.connections.get(i);
15419                ProcessRecord client = conn.client;
15420                if (client == app) {
15421                    // Being our own client is not interesting.
15422                    continue;
15423                }
15424                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15425                int clientProcState = client.curProcState;
15426                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15427                    // If the other app is cached for any reason, for purposes here
15428                    // we are going to consider it empty.
15429                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15430                }
15431                if (adj > clientAdj) {
15432                    if (app.hasShownUi && app != mHomeProcess
15433                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15434                        app.adjType = "cch-ui-provider";
15435                    } else {
15436                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15437                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15438                        app.adjType = "provider";
15439                    }
15440                    app.cached &= client.cached;
15441                    app.keeping |= client.keeping;
15442                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15443                            .REASON_PROVIDER_IN_USE;
15444                    app.adjSource = client;
15445                    app.adjSourceOom = clientAdj;
15446                    app.adjTarget = cpr.name;
15447                }
15448                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15449                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15450                        // Special handling of clients who are in the top state.
15451                        // We *may* want to consider this process to be in the
15452                        // top state as well, but only if there is not another
15453                        // reason for it to be running.  Being on the top is a
15454                        // special state, meaning you are specifically running
15455                        // for the current top app.  If the process is already
15456                        // running in the background for some other reason, it
15457                        // is more important to continue considering it to be
15458                        // in the background state.
15459                        mayBeTop = true;
15460                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15461                    } else {
15462                        // Special handling for above-top states (persistent
15463                        // processes).  These should not bring the current process
15464                        // into the top state, since they are not on top.  Instead
15465                        // give them the best state after that.
15466                        clientProcState =
15467                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15468                    }
15469                }
15470                if (procState > clientProcState) {
15471                    procState = clientProcState;
15472                }
15473                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15474                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15475                }
15476            }
15477            // If the provider has external (non-framework) process
15478            // dependencies, ensure that its adjustment is at least
15479            // FOREGROUND_APP_ADJ.
15480            if (cpr.hasExternalProcessHandles()) {
15481                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15482                    adj = ProcessList.FOREGROUND_APP_ADJ;
15483                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15484                    app.cached = false;
15485                    app.keeping = true;
15486                    app.adjType = "provider";
15487                    app.adjTarget = cpr.name;
15488                }
15489                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15490                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15491                }
15492            }
15493        }
15494
15495        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15496            // A client of one of our services or providers is in the top state.  We
15497            // *may* want to be in the top state, but not if we are already running in
15498            // the background for some other reason.  For the decision here, we are going
15499            // to pick out a few specific states that we want to remain in when a client
15500            // is top (states that tend to be longer-term) and otherwise allow it to go
15501            // to the top state.
15502            switch (procState) {
15503                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15504                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15505                case ActivityManager.PROCESS_STATE_SERVICE:
15506                    // These all are longer-term states, so pull them up to the top
15507                    // of the background states, but not all the way to the top state.
15508                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15509                    break;
15510                default:
15511                    // Otherwise, top is a better choice, so take it.
15512                    procState = ActivityManager.PROCESS_STATE_TOP;
15513                    break;
15514            }
15515        }
15516
15517        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15518            if (app.hasClientActivities) {
15519                // This is a cached process, but with client activities.  Mark it so.
15520                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15521                app.adjType = "cch-client-act";
15522            } else if (app.treatLikeActivity) {
15523                // This is a cached process, but somebody wants us to treat it like it has
15524                // an activity, okay!
15525                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15526                app.adjType = "cch-as-act";
15527            }
15528        }
15529
15530        if (adj == ProcessList.SERVICE_ADJ) {
15531            if (doingAll) {
15532                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15533                mNewNumServiceProcs++;
15534                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15535                if (!app.serviceb) {
15536                    // This service isn't far enough down on the LRU list to
15537                    // normally be a B service, but if we are low on RAM and it
15538                    // is large we want to force it down since we would prefer to
15539                    // keep launcher over it.
15540                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15541                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15542                        app.serviceHighRam = true;
15543                        app.serviceb = true;
15544                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15545                    } else {
15546                        mNewNumAServiceProcs++;
15547                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15548                    }
15549                } else {
15550                    app.serviceHighRam = false;
15551                }
15552            }
15553            if (app.serviceb) {
15554                adj = ProcessList.SERVICE_B_ADJ;
15555            }
15556        }
15557
15558        app.curRawAdj = adj;
15559
15560        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15561        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15562        if (adj > app.maxAdj) {
15563            adj = app.maxAdj;
15564            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15565                schedGroup = Process.THREAD_GROUP_DEFAULT;
15566            }
15567        }
15568        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15569            app.keeping = true;
15570        }
15571
15572        // Do final modification to adj.  Everything we do between here and applying
15573        // the final setAdj must be done in this function, because we will also use
15574        // it when computing the final cached adj later.  Note that we don't need to
15575        // worry about this for max adj above, since max adj will always be used to
15576        // keep it out of the cached vaues.
15577        app.curAdj = app.modifyRawOomAdj(adj);
15578        app.curSchedGroup = schedGroup;
15579        app.curProcState = procState;
15580        app.foregroundActivities = foregroundActivities;
15581
15582        return app.curRawAdj;
15583    }
15584
15585    /**
15586     * Schedule PSS collection of a process.
15587     */
15588    void requestPssLocked(ProcessRecord proc, int procState) {
15589        if (mPendingPssProcesses.contains(proc)) {
15590            return;
15591        }
15592        if (mPendingPssProcesses.size() == 0) {
15593            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15594        }
15595        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15596        proc.pssProcState = procState;
15597        mPendingPssProcesses.add(proc);
15598    }
15599
15600    /**
15601     * Schedule PSS collection of all processes.
15602     */
15603    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15604        if (!always) {
15605            if (now < (mLastFullPssTime +
15606                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15607                return;
15608            }
15609        }
15610        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15611        mLastFullPssTime = now;
15612        mFullPssPending = true;
15613        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15614        mPendingPssProcesses.clear();
15615        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15616            ProcessRecord app = mLruProcesses.get(i);
15617            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15618                app.pssProcState = app.setProcState;
15619                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15620                        isSleeping(), now);
15621                mPendingPssProcesses.add(app);
15622            }
15623        }
15624        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15625    }
15626
15627    /**
15628     * Ask a given process to GC right now.
15629     */
15630    final void performAppGcLocked(ProcessRecord app) {
15631        try {
15632            app.lastRequestedGc = SystemClock.uptimeMillis();
15633            if (app.thread != null) {
15634                if (app.reportLowMemory) {
15635                    app.reportLowMemory = false;
15636                    app.thread.scheduleLowMemory();
15637                } else {
15638                    app.thread.processInBackground();
15639                }
15640            }
15641        } catch (Exception e) {
15642            // whatever.
15643        }
15644    }
15645
15646    /**
15647     * Returns true if things are idle enough to perform GCs.
15648     */
15649    private final boolean canGcNowLocked() {
15650        boolean processingBroadcasts = false;
15651        for (BroadcastQueue q : mBroadcastQueues) {
15652            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15653                processingBroadcasts = true;
15654            }
15655        }
15656        return !processingBroadcasts
15657                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15658    }
15659
15660    /**
15661     * Perform GCs on all processes that are waiting for it, but only
15662     * if things are idle.
15663     */
15664    final void performAppGcsLocked() {
15665        final int N = mProcessesToGc.size();
15666        if (N <= 0) {
15667            return;
15668        }
15669        if (canGcNowLocked()) {
15670            while (mProcessesToGc.size() > 0) {
15671                ProcessRecord proc = mProcessesToGc.remove(0);
15672                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15673                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15674                            <= SystemClock.uptimeMillis()) {
15675                        // To avoid spamming the system, we will GC processes one
15676                        // at a time, waiting a few seconds between each.
15677                        performAppGcLocked(proc);
15678                        scheduleAppGcsLocked();
15679                        return;
15680                    } else {
15681                        // It hasn't been long enough since we last GCed this
15682                        // process...  put it in the list to wait for its time.
15683                        addProcessToGcListLocked(proc);
15684                        break;
15685                    }
15686                }
15687            }
15688
15689            scheduleAppGcsLocked();
15690        }
15691    }
15692
15693    /**
15694     * If all looks good, perform GCs on all processes waiting for them.
15695     */
15696    final void performAppGcsIfAppropriateLocked() {
15697        if (canGcNowLocked()) {
15698            performAppGcsLocked();
15699            return;
15700        }
15701        // Still not idle, wait some more.
15702        scheduleAppGcsLocked();
15703    }
15704
15705    /**
15706     * Schedule the execution of all pending app GCs.
15707     */
15708    final void scheduleAppGcsLocked() {
15709        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15710
15711        if (mProcessesToGc.size() > 0) {
15712            // Schedule a GC for the time to the next process.
15713            ProcessRecord proc = mProcessesToGc.get(0);
15714            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15715
15716            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15717            long now = SystemClock.uptimeMillis();
15718            if (when < (now+GC_TIMEOUT)) {
15719                when = now + GC_TIMEOUT;
15720            }
15721            mHandler.sendMessageAtTime(msg, when);
15722        }
15723    }
15724
15725    /**
15726     * Add a process to the array of processes waiting to be GCed.  Keeps the
15727     * list in sorted order by the last GC time.  The process can't already be
15728     * on the list.
15729     */
15730    final void addProcessToGcListLocked(ProcessRecord proc) {
15731        boolean added = false;
15732        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15733            if (mProcessesToGc.get(i).lastRequestedGc <
15734                    proc.lastRequestedGc) {
15735                added = true;
15736                mProcessesToGc.add(i+1, proc);
15737                break;
15738            }
15739        }
15740        if (!added) {
15741            mProcessesToGc.add(0, proc);
15742        }
15743    }
15744
15745    /**
15746     * Set up to ask a process to GC itself.  This will either do it
15747     * immediately, or put it on the list of processes to gc the next
15748     * time things are idle.
15749     */
15750    final void scheduleAppGcLocked(ProcessRecord app) {
15751        long now = SystemClock.uptimeMillis();
15752        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15753            return;
15754        }
15755        if (!mProcessesToGc.contains(app)) {
15756            addProcessToGcListLocked(app);
15757            scheduleAppGcsLocked();
15758        }
15759    }
15760
15761    final void checkExcessivePowerUsageLocked(boolean doKills) {
15762        updateCpuStatsNow();
15763
15764        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15765        boolean doWakeKills = doKills;
15766        boolean doCpuKills = doKills;
15767        if (mLastPowerCheckRealtime == 0) {
15768            doWakeKills = false;
15769        }
15770        if (mLastPowerCheckUptime == 0) {
15771            doCpuKills = false;
15772        }
15773        if (stats.isScreenOn()) {
15774            doWakeKills = false;
15775        }
15776        final long curRealtime = SystemClock.elapsedRealtime();
15777        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15778        final long curUptime = SystemClock.uptimeMillis();
15779        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15780        mLastPowerCheckRealtime = curRealtime;
15781        mLastPowerCheckUptime = curUptime;
15782        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15783            doWakeKills = false;
15784        }
15785        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15786            doCpuKills = false;
15787        }
15788        int i = mLruProcesses.size();
15789        while (i > 0) {
15790            i--;
15791            ProcessRecord app = mLruProcesses.get(i);
15792            if (!app.keeping) {
15793                long wtime;
15794                synchronized (stats) {
15795                    wtime = stats.getProcessWakeTime(app.info.uid,
15796                            app.pid, curRealtime);
15797                }
15798                long wtimeUsed = wtime - app.lastWakeTime;
15799                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15800                if (DEBUG_POWER) {
15801                    StringBuilder sb = new StringBuilder(128);
15802                    sb.append("Wake for ");
15803                    app.toShortString(sb);
15804                    sb.append(": over ");
15805                    TimeUtils.formatDuration(realtimeSince, sb);
15806                    sb.append(" used ");
15807                    TimeUtils.formatDuration(wtimeUsed, sb);
15808                    sb.append(" (");
15809                    sb.append((wtimeUsed*100)/realtimeSince);
15810                    sb.append("%)");
15811                    Slog.i(TAG, sb.toString());
15812                    sb.setLength(0);
15813                    sb.append("CPU for ");
15814                    app.toShortString(sb);
15815                    sb.append(": over ");
15816                    TimeUtils.formatDuration(uptimeSince, sb);
15817                    sb.append(" used ");
15818                    TimeUtils.formatDuration(cputimeUsed, sb);
15819                    sb.append(" (");
15820                    sb.append((cputimeUsed*100)/uptimeSince);
15821                    sb.append("%)");
15822                    Slog.i(TAG, sb.toString());
15823                }
15824                // If a process has held a wake lock for more
15825                // than 50% of the time during this period,
15826                // that sounds bad.  Kill!
15827                if (doWakeKills && realtimeSince > 0
15828                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15829                    synchronized (stats) {
15830                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15831                                realtimeSince, wtimeUsed);
15832                    }
15833                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15834                            + " during " + realtimeSince);
15835                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15836                } else if (doCpuKills && uptimeSince > 0
15837                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15838                    synchronized (stats) {
15839                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15840                                uptimeSince, cputimeUsed);
15841                    }
15842                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15843                            + " during " + uptimeSince);
15844                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15845                } else {
15846                    app.lastWakeTime = wtime;
15847                    app.lastCpuTime = app.curCpuTime;
15848                }
15849            }
15850        }
15851    }
15852
15853    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15854            ProcessRecord TOP_APP, boolean doingAll, long now) {
15855        boolean success = true;
15856
15857        if (app.curRawAdj != app.setRawAdj) {
15858            if (wasKeeping && !app.keeping) {
15859                // This app is no longer something we want to keep.  Note
15860                // its current wake lock time to later know to kill it if
15861                // it is not behaving well.
15862                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15863                synchronized (stats) {
15864                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15865                            app.pid, SystemClock.elapsedRealtime());
15866                }
15867                app.lastCpuTime = app.curCpuTime;
15868            }
15869
15870            app.setRawAdj = app.curRawAdj;
15871        }
15872
15873        int changes = 0;
15874
15875        if (app.curAdj != app.setAdj) {
15876            ProcessList.setOomAdj(app.pid, app.curAdj);
15877            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15878                TAG, "Set " + app.pid + " " + app.processName +
15879                " adj " + app.curAdj + ": " + app.adjType);
15880            app.setAdj = app.curAdj;
15881        }
15882
15883        if (app.setSchedGroup != app.curSchedGroup) {
15884            app.setSchedGroup = app.curSchedGroup;
15885            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15886                    "Setting process group of " + app.processName
15887                    + " to " + app.curSchedGroup);
15888            if (app.waitingToKill != null &&
15889                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15890                killUnneededProcessLocked(app, app.waitingToKill);
15891                success = false;
15892            } else {
15893                if (true) {
15894                    long oldId = Binder.clearCallingIdentity();
15895                    try {
15896                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15897                    } catch (Exception e) {
15898                        Slog.w(TAG, "Failed setting process group of " + app.pid
15899                                + " to " + app.curSchedGroup);
15900                        e.printStackTrace();
15901                    } finally {
15902                        Binder.restoreCallingIdentity(oldId);
15903                    }
15904                } else {
15905                    if (app.thread != null) {
15906                        try {
15907                            app.thread.setSchedulingGroup(app.curSchedGroup);
15908                        } catch (RemoteException e) {
15909                        }
15910                    }
15911                }
15912                Process.setSwappiness(app.pid,
15913                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15914            }
15915        }
15916        if (app.repForegroundActivities != app.foregroundActivities) {
15917            app.repForegroundActivities = app.foregroundActivities;
15918            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15919        }
15920        if (app.repProcState != app.curProcState) {
15921            app.repProcState = app.curProcState;
15922            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15923            if (app.thread != null) {
15924                try {
15925                    if (false) {
15926                        //RuntimeException h = new RuntimeException("here");
15927                        Slog.i(TAG, "Sending new process state " + app.repProcState
15928                                + " to " + app /*, h*/);
15929                    }
15930                    app.thread.setProcessState(app.repProcState);
15931                } catch (RemoteException e) {
15932                }
15933            }
15934        }
15935        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15936                app.setProcState)) {
15937            app.lastStateTime = now;
15938            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15939                    isSleeping(), now);
15940            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15941                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15942                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15943                    + (app.nextPssTime-now) + ": " + app);
15944        } else {
15945            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15946                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15947                requestPssLocked(app, app.setProcState);
15948                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15949                        isSleeping(), now);
15950            } else if (false && DEBUG_PSS) {
15951                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15952            }
15953        }
15954        if (app.setProcState != app.curProcState) {
15955            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15956                    "Proc state change of " + app.processName
15957                    + " to " + app.curProcState);
15958            app.setProcState = app.curProcState;
15959            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15960                app.notCachedSinceIdle = false;
15961            }
15962            if (!doingAll) {
15963                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15964            } else {
15965                app.procStateChanged = true;
15966            }
15967        }
15968
15969        if (changes != 0) {
15970            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15971            int i = mPendingProcessChanges.size()-1;
15972            ProcessChangeItem item = null;
15973            while (i >= 0) {
15974                item = mPendingProcessChanges.get(i);
15975                if (item.pid == app.pid) {
15976                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15977                    break;
15978                }
15979                i--;
15980            }
15981            if (i < 0) {
15982                // No existing item in pending changes; need a new one.
15983                final int NA = mAvailProcessChanges.size();
15984                if (NA > 0) {
15985                    item = mAvailProcessChanges.remove(NA-1);
15986                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15987                } else {
15988                    item = new ProcessChangeItem();
15989                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15990                }
15991                item.changes = 0;
15992                item.pid = app.pid;
15993                item.uid = app.info.uid;
15994                if (mPendingProcessChanges.size() == 0) {
15995                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15996                            "*** Enqueueing dispatch processes changed!");
15997                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15998                }
15999                mPendingProcessChanges.add(item);
16000            }
16001            item.changes |= changes;
16002            item.processState = app.repProcState;
16003            item.foregroundActivities = app.repForegroundActivities;
16004            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16005                    + Integer.toHexString(System.identityHashCode(item))
16006                    + " " + app.toShortString() + ": changes=" + item.changes
16007                    + " procState=" + item.processState
16008                    + " foreground=" + item.foregroundActivities
16009                    + " type=" + app.adjType + " source=" + app.adjSource
16010                    + " target=" + app.adjTarget);
16011        }
16012
16013        return success;
16014    }
16015
16016    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16017        if (proc.thread != null && proc.baseProcessTracker != null) {
16018            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16019        }
16020    }
16021
16022    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16023            ProcessRecord TOP_APP, boolean doingAll, long now) {
16024        if (app.thread == null) {
16025            return false;
16026        }
16027
16028        final boolean wasKeeping = app.keeping;
16029
16030        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16031
16032        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16033    }
16034
16035    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16036            boolean oomAdj) {
16037        if (isForeground != proc.foregroundServices) {
16038            proc.foregroundServices = isForeground;
16039            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16040                    proc.info.uid);
16041            if (isForeground) {
16042                if (curProcs == null) {
16043                    curProcs = new ArrayList<ProcessRecord>();
16044                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16045                }
16046                if (!curProcs.contains(proc)) {
16047                    curProcs.add(proc);
16048                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16049                            proc.info.packageName, proc.info.uid);
16050                }
16051            } else {
16052                if (curProcs != null) {
16053                    if (curProcs.remove(proc)) {
16054                        mBatteryStatsService.noteEvent(
16055                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16056                                proc.info.packageName, proc.info.uid);
16057                        if (curProcs.size() <= 0) {
16058                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16059                        }
16060                    }
16061                }
16062            }
16063            if (oomAdj) {
16064                updateOomAdjLocked();
16065            }
16066        }
16067    }
16068
16069    private final ActivityRecord resumedAppLocked() {
16070        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16071        String pkg;
16072        int uid;
16073        if (act != null && !act.sleeping) {
16074            pkg = act.packageName;
16075            uid = act.info.applicationInfo.uid;
16076        } else {
16077            pkg = null;
16078            uid = -1;
16079        }
16080        // Has the UID or resumed package name changed?
16081        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16082                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16083            if (mCurResumedPackage != null) {
16084                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16085                        mCurResumedPackage, mCurResumedUid);
16086            }
16087            mCurResumedPackage = pkg;
16088            mCurResumedUid = uid;
16089            if (mCurResumedPackage != null) {
16090                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16091                        mCurResumedPackage, mCurResumedUid);
16092            }
16093        }
16094        return act;
16095    }
16096
16097    final boolean updateOomAdjLocked(ProcessRecord app) {
16098        final ActivityRecord TOP_ACT = resumedAppLocked();
16099        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16100        final boolean wasCached = app.cached;
16101
16102        mAdjSeq++;
16103
16104        // This is the desired cached adjusment we want to tell it to use.
16105        // If our app is currently cached, we know it, and that is it.  Otherwise,
16106        // we don't know it yet, and it needs to now be cached we will then
16107        // need to do a complete oom adj.
16108        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16109                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16110        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16111                SystemClock.uptimeMillis());
16112        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16113            // Changed to/from cached state, so apps after it in the LRU
16114            // list may also be changed.
16115            updateOomAdjLocked();
16116        }
16117        return success;
16118    }
16119
16120    final void updateOomAdjLocked() {
16121        final ActivityRecord TOP_ACT = resumedAppLocked();
16122        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16123        final long now = SystemClock.uptimeMillis();
16124        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16125        final int N = mLruProcesses.size();
16126
16127        if (false) {
16128            RuntimeException e = new RuntimeException();
16129            e.fillInStackTrace();
16130            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16131        }
16132
16133        mAdjSeq++;
16134        mNewNumServiceProcs = 0;
16135        mNewNumAServiceProcs = 0;
16136
16137        final int emptyProcessLimit;
16138        final int cachedProcessLimit;
16139        if (mProcessLimit <= 0) {
16140            emptyProcessLimit = cachedProcessLimit = 0;
16141        } else if (mProcessLimit == 1) {
16142            emptyProcessLimit = 1;
16143            cachedProcessLimit = 0;
16144        } else {
16145            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16146            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16147        }
16148
16149        // Let's determine how many processes we have running vs.
16150        // how many slots we have for background processes; we may want
16151        // to put multiple processes in a slot of there are enough of
16152        // them.
16153        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16154                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16155        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16156        if (numEmptyProcs > cachedProcessLimit) {
16157            // If there are more empty processes than our limit on cached
16158            // processes, then use the cached process limit for the factor.
16159            // This ensures that the really old empty processes get pushed
16160            // down to the bottom, so if we are running low on memory we will
16161            // have a better chance at keeping around more cached processes
16162            // instead of a gazillion empty processes.
16163            numEmptyProcs = cachedProcessLimit;
16164        }
16165        int emptyFactor = numEmptyProcs/numSlots;
16166        if (emptyFactor < 1) emptyFactor = 1;
16167        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16168        if (cachedFactor < 1) cachedFactor = 1;
16169        int stepCached = 0;
16170        int stepEmpty = 0;
16171        int numCached = 0;
16172        int numEmpty = 0;
16173        int numTrimming = 0;
16174
16175        mNumNonCachedProcs = 0;
16176        mNumCachedHiddenProcs = 0;
16177
16178        // First update the OOM adjustment for each of the
16179        // application processes based on their current state.
16180        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16181        int nextCachedAdj = curCachedAdj+1;
16182        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16183        int nextEmptyAdj = curEmptyAdj+2;
16184        for (int i=N-1; i>=0; i--) {
16185            ProcessRecord app = mLruProcesses.get(i);
16186            if (!app.killedByAm && app.thread != null) {
16187                app.procStateChanged = false;
16188                final boolean wasKeeping = app.keeping;
16189                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16190
16191                // If we haven't yet assigned the final cached adj
16192                // to the process, do that now.
16193                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16194                    switch (app.curProcState) {
16195                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16196                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16197                            // This process is a cached process holding activities...
16198                            // assign it the next cached value for that type, and then
16199                            // step that cached level.
16200                            app.curRawAdj = curCachedAdj;
16201                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16202                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16203                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16204                                    + ")");
16205                            if (curCachedAdj != nextCachedAdj) {
16206                                stepCached++;
16207                                if (stepCached >= cachedFactor) {
16208                                    stepCached = 0;
16209                                    curCachedAdj = nextCachedAdj;
16210                                    nextCachedAdj += 2;
16211                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16212                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16213                                    }
16214                                }
16215                            }
16216                            break;
16217                        default:
16218                            // For everything else, assign next empty cached process
16219                            // level and bump that up.  Note that this means that
16220                            // long-running services that have dropped down to the
16221                            // cached level will be treated as empty (since their process
16222                            // state is still as a service), which is what we want.
16223                            app.curRawAdj = curEmptyAdj;
16224                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16225                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16226                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16227                                    + ")");
16228                            if (curEmptyAdj != nextEmptyAdj) {
16229                                stepEmpty++;
16230                                if (stepEmpty >= emptyFactor) {
16231                                    stepEmpty = 0;
16232                                    curEmptyAdj = nextEmptyAdj;
16233                                    nextEmptyAdj += 2;
16234                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16235                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16236                                    }
16237                                }
16238                            }
16239                            break;
16240                    }
16241                }
16242
16243                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16244
16245                // Count the number of process types.
16246                switch (app.curProcState) {
16247                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16248                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16249                        mNumCachedHiddenProcs++;
16250                        numCached++;
16251                        if (numCached > cachedProcessLimit) {
16252                            killUnneededProcessLocked(app, "cached #" + numCached);
16253                        }
16254                        break;
16255                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16256                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16257                                && app.lastActivityTime < oldTime) {
16258                            killUnneededProcessLocked(app, "empty for "
16259                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16260                                    / 1000) + "s");
16261                        } else {
16262                            numEmpty++;
16263                            if (numEmpty > emptyProcessLimit) {
16264                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16265                            }
16266                        }
16267                        break;
16268                    default:
16269                        mNumNonCachedProcs++;
16270                        break;
16271                }
16272
16273                if (app.isolated && app.services.size() <= 0) {
16274                    // If this is an isolated process, and there are no
16275                    // services running in it, then the process is no longer
16276                    // needed.  We agressively kill these because we can by
16277                    // definition not re-use the same process again, and it is
16278                    // good to avoid having whatever code was running in them
16279                    // left sitting around after no longer needed.
16280                    killUnneededProcessLocked(app, "isolated not needed");
16281                }
16282
16283                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16284                        && !app.killedByAm) {
16285                    numTrimming++;
16286                }
16287            }
16288        }
16289
16290        mNumServiceProcs = mNewNumServiceProcs;
16291
16292        // Now determine the memory trimming level of background processes.
16293        // Unfortunately we need to start at the back of the list to do this
16294        // properly.  We only do this if the number of background apps we
16295        // are managing to keep around is less than half the maximum we desire;
16296        // if we are keeping a good number around, we'll let them use whatever
16297        // memory they want.
16298        final int numCachedAndEmpty = numCached + numEmpty;
16299        int memFactor;
16300        if (numCached <= ProcessList.TRIM_CACHED_APPS
16301                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16302            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16303                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16304            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16305                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16306            } else {
16307                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16308            }
16309        } else {
16310            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16311        }
16312        // We always allow the memory level to go up (better).  We only allow it to go
16313        // down if we are in a state where that is allowed, *and* the total number of processes
16314        // has gone down since last time.
16315        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16316                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16317                + " last=" + mLastNumProcesses);
16318        if (memFactor > mLastMemoryLevel) {
16319            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16320                memFactor = mLastMemoryLevel;
16321                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16322            }
16323        }
16324        mLastMemoryLevel = memFactor;
16325        mLastNumProcesses = mLruProcesses.size();
16326        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16327        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16328        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16329            if (mLowRamStartTime == 0) {
16330                mLowRamStartTime = now;
16331            }
16332            int step = 0;
16333            int fgTrimLevel;
16334            switch (memFactor) {
16335                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16336                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16337                    break;
16338                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16339                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16340                    break;
16341                default:
16342                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16343                    break;
16344            }
16345            int factor = numTrimming/3;
16346            int minFactor = 2;
16347            if (mHomeProcess != null) minFactor++;
16348            if (mPreviousProcess != null) minFactor++;
16349            if (factor < minFactor) factor = minFactor;
16350            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16351            for (int i=N-1; i>=0; i--) {
16352                ProcessRecord app = mLruProcesses.get(i);
16353                if (allChanged || app.procStateChanged) {
16354                    setProcessTrackerState(app, trackerMemFactor, now);
16355                    app.procStateChanged = false;
16356                }
16357                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16358                        && !app.killedByAm) {
16359                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16360                        try {
16361                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16362                                    "Trimming memory of " + app.processName
16363                                    + " to " + curLevel);
16364                            app.thread.scheduleTrimMemory(curLevel);
16365                        } catch (RemoteException e) {
16366                        }
16367                        if (false) {
16368                            // For now we won't do this; our memory trimming seems
16369                            // to be good enough at this point that destroying
16370                            // activities causes more harm than good.
16371                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16372                                    && app != mHomeProcess && app != mPreviousProcess) {
16373                                // Need to do this on its own message because the stack may not
16374                                // be in a consistent state at this point.
16375                                // For these apps we will also finish their activities
16376                                // to help them free memory.
16377                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16378                            }
16379                        }
16380                    }
16381                    app.trimMemoryLevel = curLevel;
16382                    step++;
16383                    if (step >= factor) {
16384                        step = 0;
16385                        switch (curLevel) {
16386                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16387                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16388                                break;
16389                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16390                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16391                                break;
16392                        }
16393                    }
16394                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16395                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16396                            && app.thread != null) {
16397                        try {
16398                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16399                                    "Trimming memory of heavy-weight " + app.processName
16400                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16401                            app.thread.scheduleTrimMemory(
16402                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16403                        } catch (RemoteException e) {
16404                        }
16405                    }
16406                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16407                } else {
16408                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16409                            || app.systemNoUi) && app.pendingUiClean) {
16410                        // If this application is now in the background and it
16411                        // had done UI, then give it the special trim level to
16412                        // have it free UI resources.
16413                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16414                        if (app.trimMemoryLevel < level && app.thread != null) {
16415                            try {
16416                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16417                                        "Trimming memory of bg-ui " + app.processName
16418                                        + " to " + level);
16419                                app.thread.scheduleTrimMemory(level);
16420                            } catch (RemoteException e) {
16421                            }
16422                        }
16423                        app.pendingUiClean = false;
16424                    }
16425                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16426                        try {
16427                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16428                                    "Trimming memory of fg " + app.processName
16429                                    + " to " + fgTrimLevel);
16430                            app.thread.scheduleTrimMemory(fgTrimLevel);
16431                        } catch (RemoteException e) {
16432                        }
16433                    }
16434                    app.trimMemoryLevel = fgTrimLevel;
16435                }
16436            }
16437        } else {
16438            if (mLowRamStartTime != 0) {
16439                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16440                mLowRamStartTime = 0;
16441            }
16442            for (int i=N-1; i>=0; i--) {
16443                ProcessRecord app = mLruProcesses.get(i);
16444                if (allChanged || app.procStateChanged) {
16445                    setProcessTrackerState(app, trackerMemFactor, now);
16446                    app.procStateChanged = false;
16447                }
16448                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16449                        || app.systemNoUi) && app.pendingUiClean) {
16450                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16451                            && app.thread != null) {
16452                        try {
16453                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16454                                    "Trimming memory of ui hidden " + app.processName
16455                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16456                            app.thread.scheduleTrimMemory(
16457                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16458                        } catch (RemoteException e) {
16459                        }
16460                    }
16461                    app.pendingUiClean = false;
16462                }
16463                app.trimMemoryLevel = 0;
16464            }
16465        }
16466
16467        if (mAlwaysFinishActivities) {
16468            // Need to do this on its own message because the stack may not
16469            // be in a consistent state at this point.
16470            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16471        }
16472
16473        if (allChanged) {
16474            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16475        }
16476
16477        if (mProcessStats.shouldWriteNowLocked(now)) {
16478            mHandler.post(new Runnable() {
16479                @Override public void run() {
16480                    synchronized (ActivityManagerService.this) {
16481                        mProcessStats.writeStateAsyncLocked();
16482                    }
16483                }
16484            });
16485        }
16486
16487        if (DEBUG_OOM_ADJ) {
16488            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16489        }
16490    }
16491
16492    final void trimApplications() {
16493        synchronized (this) {
16494            int i;
16495
16496            // First remove any unused application processes whose package
16497            // has been removed.
16498            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16499                final ProcessRecord app = mRemovedProcesses.get(i);
16500                if (app.activities.size() == 0
16501                        && app.curReceiver == null && app.services.size() == 0) {
16502                    Slog.i(
16503                        TAG, "Exiting empty application process "
16504                        + app.processName + " ("
16505                        + (app.thread != null ? app.thread.asBinder() : null)
16506                        + ")\n");
16507                    if (app.pid > 0 && app.pid != MY_PID) {
16508                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16509                                app.processName, app.setAdj, "empty");
16510                        app.killedByAm = true;
16511                        Process.killProcessQuiet(app.pid);
16512                    } else {
16513                        try {
16514                            app.thread.scheduleExit();
16515                        } catch (Exception e) {
16516                            // Ignore exceptions.
16517                        }
16518                    }
16519                    cleanUpApplicationRecordLocked(app, false, true, -1);
16520                    mRemovedProcesses.remove(i);
16521
16522                    if (app.persistent) {
16523                        if (app.persistent) {
16524                            addAppLocked(app.info, false, null /* ABI override */);
16525                        }
16526                    }
16527                }
16528            }
16529
16530            // Now update the oom adj for all processes.
16531            updateOomAdjLocked();
16532        }
16533    }
16534
16535    /** This method sends the specified signal to each of the persistent apps */
16536    public void signalPersistentProcesses(int sig) throws RemoteException {
16537        if (sig != Process.SIGNAL_USR1) {
16538            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16539        }
16540
16541        synchronized (this) {
16542            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16543                    != PackageManager.PERMISSION_GRANTED) {
16544                throw new SecurityException("Requires permission "
16545                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16546            }
16547
16548            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16549                ProcessRecord r = mLruProcesses.get(i);
16550                if (r.thread != null && r.persistent) {
16551                    Process.sendSignal(r.pid, sig);
16552                }
16553            }
16554        }
16555    }
16556
16557    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16558        if (proc == null || proc == mProfileProc) {
16559            proc = mProfileProc;
16560            path = mProfileFile;
16561            profileType = mProfileType;
16562            clearProfilerLocked();
16563        }
16564        if (proc == null) {
16565            return;
16566        }
16567        try {
16568            proc.thread.profilerControl(false, path, null, profileType);
16569        } catch (RemoteException e) {
16570            throw new IllegalStateException("Process disappeared");
16571        }
16572    }
16573
16574    private void clearProfilerLocked() {
16575        if (mProfileFd != null) {
16576            try {
16577                mProfileFd.close();
16578            } catch (IOException e) {
16579            }
16580        }
16581        mProfileApp = null;
16582        mProfileProc = null;
16583        mProfileFile = null;
16584        mProfileType = 0;
16585        mAutoStopProfiler = false;
16586    }
16587
16588    public boolean profileControl(String process, int userId, boolean start,
16589            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16590
16591        try {
16592            synchronized (this) {
16593                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16594                // its own permission.
16595                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16596                        != PackageManager.PERMISSION_GRANTED) {
16597                    throw new SecurityException("Requires permission "
16598                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16599                }
16600
16601                if (start && fd == null) {
16602                    throw new IllegalArgumentException("null fd");
16603                }
16604
16605                ProcessRecord proc = null;
16606                if (process != null) {
16607                    proc = findProcessLocked(process, userId, "profileControl");
16608                }
16609
16610                if (start && (proc == null || proc.thread == null)) {
16611                    throw new IllegalArgumentException("Unknown process: " + process);
16612                }
16613
16614                if (start) {
16615                    stopProfilerLocked(null, null, 0);
16616                    setProfileApp(proc.info, proc.processName, path, fd, false);
16617                    mProfileProc = proc;
16618                    mProfileType = profileType;
16619                    try {
16620                        fd = fd.dup();
16621                    } catch (IOException e) {
16622                        fd = null;
16623                    }
16624                    proc.thread.profilerControl(start, path, fd, profileType);
16625                    fd = null;
16626                    mProfileFd = null;
16627                } else {
16628                    stopProfilerLocked(proc, path, profileType);
16629                    if (fd != null) {
16630                        try {
16631                            fd.close();
16632                        } catch (IOException e) {
16633                        }
16634                    }
16635                }
16636
16637                return true;
16638            }
16639        } catch (RemoteException e) {
16640            throw new IllegalStateException("Process disappeared");
16641        } finally {
16642            if (fd != null) {
16643                try {
16644                    fd.close();
16645                } catch (IOException e) {
16646                }
16647            }
16648        }
16649    }
16650
16651    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16652        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16653                userId, true, true, callName, null);
16654        ProcessRecord proc = null;
16655        try {
16656            int pid = Integer.parseInt(process);
16657            synchronized (mPidsSelfLocked) {
16658                proc = mPidsSelfLocked.get(pid);
16659            }
16660        } catch (NumberFormatException e) {
16661        }
16662
16663        if (proc == null) {
16664            ArrayMap<String, SparseArray<ProcessRecord>> all
16665                    = mProcessNames.getMap();
16666            SparseArray<ProcessRecord> procs = all.get(process);
16667            if (procs != null && procs.size() > 0) {
16668                proc = procs.valueAt(0);
16669                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16670                    for (int i=1; i<procs.size(); i++) {
16671                        ProcessRecord thisProc = procs.valueAt(i);
16672                        if (thisProc.userId == userId) {
16673                            proc = thisProc;
16674                            break;
16675                        }
16676                    }
16677                }
16678            }
16679        }
16680
16681        return proc;
16682    }
16683
16684    public boolean dumpHeap(String process, int userId, boolean managed,
16685            String path, ParcelFileDescriptor fd) throws RemoteException {
16686
16687        try {
16688            synchronized (this) {
16689                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16690                // its own permission (same as profileControl).
16691                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16692                        != PackageManager.PERMISSION_GRANTED) {
16693                    throw new SecurityException("Requires permission "
16694                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16695                }
16696
16697                if (fd == null) {
16698                    throw new IllegalArgumentException("null fd");
16699                }
16700
16701                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16702                if (proc == null || proc.thread == null) {
16703                    throw new IllegalArgumentException("Unknown process: " + process);
16704                }
16705
16706                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16707                if (!isDebuggable) {
16708                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16709                        throw new SecurityException("Process not debuggable: " + proc);
16710                    }
16711                }
16712
16713                proc.thread.dumpHeap(managed, path, fd);
16714                fd = null;
16715                return true;
16716            }
16717        } catch (RemoteException e) {
16718            throw new IllegalStateException("Process disappeared");
16719        } finally {
16720            if (fd != null) {
16721                try {
16722                    fd.close();
16723                } catch (IOException e) {
16724                }
16725            }
16726        }
16727    }
16728
16729    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16730    public void monitor() {
16731        synchronized (this) { }
16732    }
16733
16734    void onCoreSettingsChange(Bundle settings) {
16735        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16736            ProcessRecord processRecord = mLruProcesses.get(i);
16737            try {
16738                if (processRecord.thread != null) {
16739                    processRecord.thread.setCoreSettings(settings);
16740                }
16741            } catch (RemoteException re) {
16742                /* ignore */
16743            }
16744        }
16745    }
16746
16747    // Multi-user methods
16748
16749    /**
16750     * Start user, if its not already running, but don't bring it to foreground.
16751     */
16752    @Override
16753    public boolean startUserInBackground(final int userId) {
16754        return startUser(userId, /* foreground */ false);
16755    }
16756
16757    /**
16758     * Refreshes the list of users related to the current user when either a
16759     * user switch happens or when a new related user is started in the
16760     * background.
16761     */
16762    private void updateCurrentProfileIdsLocked() {
16763        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16764                mCurrentUserId, false /* enabledOnly */);
16765        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16766        for (int i = 0; i < currentProfileIds.length; i++) {
16767            currentProfileIds[i] = profiles.get(i).id;
16768        }
16769        mCurrentProfileIds = currentProfileIds;
16770    }
16771
16772    private Set getProfileIdsLocked(int userId) {
16773        Set userIds = new HashSet<Integer>();
16774        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16775                userId, false /* enabledOnly */);
16776        for (UserInfo user : profiles) {
16777            userIds.add(Integer.valueOf(user.id));
16778        }
16779        return userIds;
16780    }
16781
16782    @Override
16783    public boolean switchUser(final int userId) {
16784        return startUser(userId, /* foregound */ true);
16785    }
16786
16787    private boolean startUser(final int userId, boolean foreground) {
16788        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16789                != PackageManager.PERMISSION_GRANTED) {
16790            String msg = "Permission Denial: switchUser() from pid="
16791                    + Binder.getCallingPid()
16792                    + ", uid=" + Binder.getCallingUid()
16793                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16794            Slog.w(TAG, msg);
16795            throw new SecurityException(msg);
16796        }
16797
16798        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16799
16800        final long ident = Binder.clearCallingIdentity();
16801        try {
16802            synchronized (this) {
16803                final int oldUserId = mCurrentUserId;
16804                if (oldUserId == userId) {
16805                    return true;
16806                }
16807
16808                mStackSupervisor.setLockTaskModeLocked(null, false);
16809
16810                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16811                if (userInfo == null) {
16812                    Slog.w(TAG, "No user info for user #" + userId);
16813                    return false;
16814                }
16815
16816                if (foreground) {
16817                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16818                            R.anim.screen_user_enter);
16819                }
16820
16821                boolean needStart = false;
16822
16823                // If the user we are switching to is not currently started, then
16824                // we need to start it now.
16825                if (mStartedUsers.get(userId) == null) {
16826                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16827                    updateStartedUserArrayLocked();
16828                    needStart = true;
16829                }
16830
16831                final Integer userIdInt = Integer.valueOf(userId);
16832                mUserLru.remove(userIdInt);
16833                mUserLru.add(userIdInt);
16834
16835                if (foreground) {
16836                    mCurrentUserId = userId;
16837                    updateCurrentProfileIdsLocked();
16838                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16839                    // Once the internal notion of the active user has switched, we lock the device
16840                    // with the option to show the user switcher on the keyguard.
16841                    mWindowManager.lockNow(null);
16842                } else {
16843                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16844                    updateCurrentProfileIdsLocked();
16845                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16846                    mUserLru.remove(currentUserIdInt);
16847                    mUserLru.add(currentUserIdInt);
16848                }
16849
16850                final UserStartedState uss = mStartedUsers.get(userId);
16851
16852                // Make sure user is in the started state.  If it is currently
16853                // stopping, we need to knock that off.
16854                if (uss.mState == UserStartedState.STATE_STOPPING) {
16855                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16856                    // so we can just fairly silently bring the user back from
16857                    // the almost-dead.
16858                    uss.mState = UserStartedState.STATE_RUNNING;
16859                    updateStartedUserArrayLocked();
16860                    needStart = true;
16861                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16862                    // This means ACTION_SHUTDOWN has been sent, so we will
16863                    // need to treat this as a new boot of the user.
16864                    uss.mState = UserStartedState.STATE_BOOTING;
16865                    updateStartedUserArrayLocked();
16866                    needStart = true;
16867                }
16868
16869                if (uss.mState == UserStartedState.STATE_BOOTING) {
16870                    // Booting up a new user, need to tell system services about it.
16871                    // Note that this is on the same handler as scheduling of broadcasts,
16872                    // which is important because it needs to go first.
16873                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16874                }
16875
16876                if (foreground) {
16877                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16878                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16879                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16880                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16881                            oldUserId, userId, uss));
16882                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16883                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16884                }
16885
16886                if (needStart) {
16887                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16888                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16889                            | Intent.FLAG_RECEIVER_FOREGROUND);
16890                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16891                    broadcastIntentLocked(null, null, intent,
16892                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16893                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16894                }
16895
16896                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16897                    if (userId != UserHandle.USER_OWNER) {
16898                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16899                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16900                        broadcastIntentLocked(null, null, intent, null,
16901                                new IIntentReceiver.Stub() {
16902                                    public void performReceive(Intent intent, int resultCode,
16903                                            String data, Bundle extras, boolean ordered,
16904                                            boolean sticky, int sendingUser) {
16905                                        userInitialized(uss, userId);
16906                                    }
16907                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16908                                true, false, MY_PID, Process.SYSTEM_UID,
16909                                userId);
16910                        uss.initializing = true;
16911                    } else {
16912                        getUserManagerLocked().makeInitialized(userInfo.id);
16913                    }
16914                }
16915
16916                if (foreground) {
16917                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16918                    if (homeInFront) {
16919                        startHomeActivityLocked(userId);
16920                    } else {
16921                        mStackSupervisor.resumeTopActivitiesLocked();
16922                    }
16923                    EventLogTags.writeAmSwitchUser(userId);
16924                    getUserManagerLocked().userForeground(userId);
16925                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16926                } else {
16927                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16928                }
16929
16930                if (needStart) {
16931                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16932                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16933                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16934                    broadcastIntentLocked(null, null, intent,
16935                            null, new IIntentReceiver.Stub() {
16936                                @Override
16937                                public void performReceive(Intent intent, int resultCode, String data,
16938                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16939                                        throws RemoteException {
16940                                }
16941                            }, 0, null, null,
16942                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16943                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16944                }
16945            }
16946        } finally {
16947            Binder.restoreCallingIdentity(ident);
16948        }
16949
16950        return true;
16951    }
16952
16953    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16954        long ident = Binder.clearCallingIdentity();
16955        try {
16956            Intent intent;
16957            if (oldUserId >= 0) {
16958                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16959                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16960                        | Intent.FLAG_RECEIVER_FOREGROUND);
16961                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16962                broadcastIntentLocked(null, null, intent,
16963                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16964                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16965            }
16966            if (newUserId >= 0) {
16967                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16968                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16969                        | Intent.FLAG_RECEIVER_FOREGROUND);
16970                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16971                broadcastIntentLocked(null, null, intent,
16972                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16973                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16974                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16975                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16976                        | Intent.FLAG_RECEIVER_FOREGROUND);
16977                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16978                broadcastIntentLocked(null, null, intent,
16979                        null, null, 0, null, null,
16980                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16981                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16982            }
16983        } finally {
16984            Binder.restoreCallingIdentity(ident);
16985        }
16986    }
16987
16988    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16989            final int newUserId) {
16990        final int N = mUserSwitchObservers.beginBroadcast();
16991        if (N > 0) {
16992            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16993                int mCount = 0;
16994                @Override
16995                public void sendResult(Bundle data) throws RemoteException {
16996                    synchronized (ActivityManagerService.this) {
16997                        if (mCurUserSwitchCallback == this) {
16998                            mCount++;
16999                            if (mCount == N) {
17000                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17001                            }
17002                        }
17003                    }
17004                }
17005            };
17006            synchronized (this) {
17007                uss.switching = true;
17008                mCurUserSwitchCallback = callback;
17009            }
17010            for (int i=0; i<N; i++) {
17011                try {
17012                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17013                            newUserId, callback);
17014                } catch (RemoteException e) {
17015                }
17016            }
17017        } else {
17018            synchronized (this) {
17019                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17020            }
17021        }
17022        mUserSwitchObservers.finishBroadcast();
17023    }
17024
17025    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17026        synchronized (this) {
17027            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17028            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17029        }
17030    }
17031
17032    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17033        mCurUserSwitchCallback = null;
17034        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17035        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17036                oldUserId, newUserId, uss));
17037    }
17038
17039    void userInitialized(UserStartedState uss, int newUserId) {
17040        completeSwitchAndInitalize(uss, newUserId, true, false);
17041    }
17042
17043    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17044        completeSwitchAndInitalize(uss, newUserId, false, true);
17045    }
17046
17047    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17048            boolean clearInitializing, boolean clearSwitching) {
17049        boolean unfrozen = false;
17050        synchronized (this) {
17051            if (clearInitializing) {
17052                uss.initializing = false;
17053                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17054            }
17055            if (clearSwitching) {
17056                uss.switching = false;
17057            }
17058            if (!uss.switching && !uss.initializing) {
17059                mWindowManager.stopFreezingScreen();
17060                unfrozen = true;
17061            }
17062        }
17063        if (unfrozen) {
17064            final int N = mUserSwitchObservers.beginBroadcast();
17065            for (int i=0; i<N; i++) {
17066                try {
17067                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17068                } catch (RemoteException e) {
17069                }
17070            }
17071            mUserSwitchObservers.finishBroadcast();
17072        }
17073    }
17074
17075    void scheduleStartProfilesLocked() {
17076        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17077            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17078                    DateUtils.SECOND_IN_MILLIS);
17079        }
17080    }
17081
17082    void startProfilesLocked() {
17083        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17084        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17085                mCurrentUserId, false /* enabledOnly */);
17086        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17087        for (UserInfo user : profiles) {
17088            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17089                    && user.id != mCurrentUserId) {
17090                toStart.add(user);
17091            }
17092        }
17093        final int n = toStart.size();
17094        int i = 0;
17095        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17096            startUserInBackground(toStart.get(i).id);
17097        }
17098        if (i < n) {
17099            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17100        }
17101    }
17102
17103    void finishUserBoot(UserStartedState uss) {
17104        synchronized (this) {
17105            if (uss.mState == UserStartedState.STATE_BOOTING
17106                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17107                uss.mState = UserStartedState.STATE_RUNNING;
17108                final int userId = uss.mHandle.getIdentifier();
17109                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17110                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17111                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17112                broadcastIntentLocked(null, null, intent,
17113                        null, null, 0, null, null,
17114                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17115                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17116            }
17117        }
17118    }
17119
17120    void finishUserSwitch(UserStartedState uss) {
17121        synchronized (this) {
17122            finishUserBoot(uss);
17123
17124            startProfilesLocked();
17125
17126            int num = mUserLru.size();
17127            int i = 0;
17128            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17129                Integer oldUserId = mUserLru.get(i);
17130                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17131                if (oldUss == null) {
17132                    // Shouldn't happen, but be sane if it does.
17133                    mUserLru.remove(i);
17134                    num--;
17135                    continue;
17136                }
17137                if (oldUss.mState == UserStartedState.STATE_STOPPING
17138                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17139                    // This user is already stopping, doesn't count.
17140                    num--;
17141                    i++;
17142                    continue;
17143                }
17144                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17145                    // Owner and current can't be stopped, but count as running.
17146                    i++;
17147                    continue;
17148                }
17149                // This is a user to be stopped.
17150                stopUserLocked(oldUserId, null);
17151                num--;
17152                i++;
17153            }
17154        }
17155    }
17156
17157    @Override
17158    public int stopUser(final int userId, final IStopUserCallback callback) {
17159        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17160                != PackageManager.PERMISSION_GRANTED) {
17161            String msg = "Permission Denial: switchUser() from pid="
17162                    + Binder.getCallingPid()
17163                    + ", uid=" + Binder.getCallingUid()
17164                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17165            Slog.w(TAG, msg);
17166            throw new SecurityException(msg);
17167        }
17168        if (userId <= 0) {
17169            throw new IllegalArgumentException("Can't stop primary user " + userId);
17170        }
17171        synchronized (this) {
17172            return stopUserLocked(userId, callback);
17173        }
17174    }
17175
17176    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17177        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17178        if (mCurrentUserId == userId) {
17179            return ActivityManager.USER_OP_IS_CURRENT;
17180        }
17181
17182        final UserStartedState uss = mStartedUsers.get(userId);
17183        if (uss == null) {
17184            // User is not started, nothing to do...  but we do need to
17185            // callback if requested.
17186            if (callback != null) {
17187                mHandler.post(new Runnable() {
17188                    @Override
17189                    public void run() {
17190                        try {
17191                            callback.userStopped(userId);
17192                        } catch (RemoteException e) {
17193                        }
17194                    }
17195                });
17196            }
17197            return ActivityManager.USER_OP_SUCCESS;
17198        }
17199
17200        if (callback != null) {
17201            uss.mStopCallbacks.add(callback);
17202        }
17203
17204        if (uss.mState != UserStartedState.STATE_STOPPING
17205                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17206            uss.mState = UserStartedState.STATE_STOPPING;
17207            updateStartedUserArrayLocked();
17208
17209            long ident = Binder.clearCallingIdentity();
17210            try {
17211                // We are going to broadcast ACTION_USER_STOPPING and then
17212                // once that is done send a final ACTION_SHUTDOWN and then
17213                // stop the user.
17214                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17215                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17216                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17217                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17218                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17219                // This is the result receiver for the final shutdown broadcast.
17220                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17221                    @Override
17222                    public void performReceive(Intent intent, int resultCode, String data,
17223                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17224                        finishUserStop(uss);
17225                    }
17226                };
17227                // This is the result receiver for the initial stopping broadcast.
17228                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17229                    @Override
17230                    public void performReceive(Intent intent, int resultCode, String data,
17231                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17232                        // On to the next.
17233                        synchronized (ActivityManagerService.this) {
17234                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17235                                // Whoops, we are being started back up.  Abort, abort!
17236                                return;
17237                            }
17238                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17239                        }
17240                        mSystemServiceManager.stopUser(userId);
17241                        broadcastIntentLocked(null, null, shutdownIntent,
17242                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17243                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17244                    }
17245                };
17246                // Kick things off.
17247                broadcastIntentLocked(null, null, stoppingIntent,
17248                        null, stoppingReceiver, 0, null, null,
17249                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17250                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17251            } finally {
17252                Binder.restoreCallingIdentity(ident);
17253            }
17254        }
17255
17256        return ActivityManager.USER_OP_SUCCESS;
17257    }
17258
17259    void finishUserStop(UserStartedState uss) {
17260        final int userId = uss.mHandle.getIdentifier();
17261        boolean stopped;
17262        ArrayList<IStopUserCallback> callbacks;
17263        synchronized (this) {
17264            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17265            if (mStartedUsers.get(userId) != uss) {
17266                stopped = false;
17267            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17268                stopped = false;
17269            } else {
17270                stopped = true;
17271                // User can no longer run.
17272                mStartedUsers.remove(userId);
17273                mUserLru.remove(Integer.valueOf(userId));
17274                updateStartedUserArrayLocked();
17275
17276                // Clean up all state and processes associated with the user.
17277                // Kill all the processes for the user.
17278                forceStopUserLocked(userId, "finish user");
17279            }
17280        }
17281
17282        for (int i=0; i<callbacks.size(); i++) {
17283            try {
17284                if (stopped) callbacks.get(i).userStopped(userId);
17285                else callbacks.get(i).userStopAborted(userId);
17286            } catch (RemoteException e) {
17287            }
17288        }
17289
17290        if (stopped) {
17291            mSystemServiceManager.cleanupUser(userId);
17292            synchronized (this) {
17293                mStackSupervisor.removeUserLocked(userId);
17294            }
17295        }
17296    }
17297
17298    @Override
17299    public UserInfo getCurrentUser() {
17300        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17301                != PackageManager.PERMISSION_GRANTED) && (
17302                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17303                != PackageManager.PERMISSION_GRANTED)) {
17304            String msg = "Permission Denial: getCurrentUser() from pid="
17305                    + Binder.getCallingPid()
17306                    + ", uid=" + Binder.getCallingUid()
17307                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17308            Slog.w(TAG, msg);
17309            throw new SecurityException(msg);
17310        }
17311        synchronized (this) {
17312            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17313        }
17314    }
17315
17316    int getCurrentUserIdLocked() {
17317        return mCurrentUserId;
17318    }
17319
17320    @Override
17321    public boolean isUserRunning(int userId, boolean orStopped) {
17322        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17323                != PackageManager.PERMISSION_GRANTED) {
17324            String msg = "Permission Denial: isUserRunning() from pid="
17325                    + Binder.getCallingPid()
17326                    + ", uid=" + Binder.getCallingUid()
17327                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17328            Slog.w(TAG, msg);
17329            throw new SecurityException(msg);
17330        }
17331        synchronized (this) {
17332            return isUserRunningLocked(userId, orStopped);
17333        }
17334    }
17335
17336    boolean isUserRunningLocked(int userId, boolean orStopped) {
17337        UserStartedState state = mStartedUsers.get(userId);
17338        if (state == null) {
17339            return false;
17340        }
17341        if (orStopped) {
17342            return true;
17343        }
17344        return state.mState != UserStartedState.STATE_STOPPING
17345                && state.mState != UserStartedState.STATE_SHUTDOWN;
17346    }
17347
17348    @Override
17349    public int[] getRunningUserIds() {
17350        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17351                != PackageManager.PERMISSION_GRANTED) {
17352            String msg = "Permission Denial: isUserRunning() from pid="
17353                    + Binder.getCallingPid()
17354                    + ", uid=" + Binder.getCallingUid()
17355                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17356            Slog.w(TAG, msg);
17357            throw new SecurityException(msg);
17358        }
17359        synchronized (this) {
17360            return mStartedUserArray;
17361        }
17362    }
17363
17364    private void updateStartedUserArrayLocked() {
17365        int num = 0;
17366        for (int i=0; i<mStartedUsers.size();  i++) {
17367            UserStartedState uss = mStartedUsers.valueAt(i);
17368            // This list does not include stopping users.
17369            if (uss.mState != UserStartedState.STATE_STOPPING
17370                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17371                num++;
17372            }
17373        }
17374        mStartedUserArray = new int[num];
17375        num = 0;
17376        for (int i=0; i<mStartedUsers.size();  i++) {
17377            UserStartedState uss = mStartedUsers.valueAt(i);
17378            if (uss.mState != UserStartedState.STATE_STOPPING
17379                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17380                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17381                num++;
17382            }
17383        }
17384    }
17385
17386    @Override
17387    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17388        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17389                != PackageManager.PERMISSION_GRANTED) {
17390            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17391                    + Binder.getCallingPid()
17392                    + ", uid=" + Binder.getCallingUid()
17393                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17394            Slog.w(TAG, msg);
17395            throw new SecurityException(msg);
17396        }
17397
17398        mUserSwitchObservers.register(observer);
17399    }
17400
17401    @Override
17402    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17403        mUserSwitchObservers.unregister(observer);
17404    }
17405
17406    private boolean userExists(int userId) {
17407        if (userId == 0) {
17408            return true;
17409        }
17410        UserManagerService ums = getUserManagerLocked();
17411        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17412    }
17413
17414    int[] getUsersLocked() {
17415        UserManagerService ums = getUserManagerLocked();
17416        return ums != null ? ums.getUserIds() : new int[] { 0 };
17417    }
17418
17419    UserManagerService getUserManagerLocked() {
17420        if (mUserManager == null) {
17421            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17422            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17423        }
17424        return mUserManager;
17425    }
17426
17427    private int applyUserId(int uid, int userId) {
17428        return UserHandle.getUid(userId, uid);
17429    }
17430
17431    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17432        if (info == null) return null;
17433        ApplicationInfo newInfo = new ApplicationInfo(info);
17434        newInfo.uid = applyUserId(info.uid, userId);
17435        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17436                + info.packageName;
17437        return newInfo;
17438    }
17439
17440    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17441        if (aInfo == null
17442                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17443            return aInfo;
17444        }
17445
17446        ActivityInfo info = new ActivityInfo(aInfo);
17447        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17448        return info;
17449    }
17450
17451    private final class LocalService extends ActivityManagerInternal {
17452        @Override
17453        public void goingToSleep() {
17454            ActivityManagerService.this.goingToSleep();
17455        }
17456
17457        @Override
17458        public void wakingUp() {
17459            ActivityManagerService.this.wakingUp();
17460        }
17461    }
17462
17463    /**
17464     * An implementation of IAppTask, that allows an app to manage its own tasks via
17465     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17466     * only the process that calls getAppTasks() can call the AppTask methods.
17467     */
17468    class AppTaskImpl extends IAppTask.Stub {
17469        private int mTaskId;
17470        private int mCallingUid;
17471
17472        public AppTaskImpl(int taskId, int callingUid) {
17473            mTaskId = taskId;
17474            mCallingUid = callingUid;
17475        }
17476
17477        @Override
17478        public void finishAndRemoveTask() {
17479            // Ensure that we are called from the same process that created this AppTask
17480            if (mCallingUid != Binder.getCallingUid()) {
17481                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17482                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17483                return;
17484            }
17485
17486            synchronized (ActivityManagerService.this) {
17487                long origId = Binder.clearCallingIdentity();
17488                try {
17489                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17490                    if (tr != null) {
17491                        // Only kill the process if we are not a new document
17492                        int flags = tr.getBaseIntent().getFlags();
17493                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17494                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17495                        removeTaskByIdLocked(mTaskId,
17496                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17497                    }
17498                } finally {
17499                    Binder.restoreCallingIdentity(origId);
17500                }
17501            }
17502        }
17503
17504        @Override
17505        public ActivityManager.RecentTaskInfo getTaskInfo() {
17506            // Ensure that we are called from the same process that created this AppTask
17507            if (mCallingUid != Binder.getCallingUid()) {
17508                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17509                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17510                return null;
17511            }
17512
17513            synchronized (ActivityManagerService.this) {
17514                long origId = Binder.clearCallingIdentity();
17515                try {
17516                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17517                    if (tr != null) {
17518                        return createRecentTaskInfoFromTaskRecord(tr);
17519                    }
17520                } finally {
17521                    Binder.restoreCallingIdentity(origId);
17522                }
17523                return null;
17524            }
17525        }
17526    }
17527}
17528