ActivityManagerService.java revision f1fbd77cf057e43926f9a0347692611386d09f40
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        rti.lastActiveTime = tr.lastActiveTime;
7242        return rti;
7243    }
7244
7245    @Override
7246    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7247            int flags, int userId) {
7248        final int callingUid = Binder.getCallingUid();
7249        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7250                false, true, "getRecentTasks", null);
7251
7252        synchronized (this) {
7253            final boolean allowed = checkCallingPermission(
7254                    android.Manifest.permission.GET_TASKS)
7255                    == PackageManager.PERMISSION_GRANTED;
7256            if (!allowed) {
7257                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7258                        + " does not hold GET_TASKS; limiting output");
7259            }
7260            final boolean detailed = checkCallingPermission(
7261                    android.Manifest.permission.GET_DETAILED_TASKS)
7262                    == PackageManager.PERMISSION_GRANTED;
7263
7264            IPackageManager pm = AppGlobals.getPackageManager();
7265
7266            final int N = mRecentTasks.size();
7267            ArrayList<ActivityManager.RecentTaskInfo> res
7268                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7269                            maxNum < N ? maxNum : N);
7270
7271            final Set<Integer> includedUsers;
7272            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7273                includedUsers = getProfileIdsLocked(userId);
7274            } else {
7275                includedUsers = new HashSet<Integer>();
7276            }
7277            includedUsers.add(Integer.valueOf(userId));
7278            for (int i=0; i<N && maxNum > 0; i++) {
7279                TaskRecord tr = mRecentTasks.get(i);
7280                // Only add calling user or related users recent tasks
7281                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7282
7283                // Return the entry if desired by the caller.  We always return
7284                // the first entry, because callers always expect this to be the
7285                // foreground app.  We may filter others if the caller has
7286                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7287                // we should exclude the entry.
7288
7289                if (i == 0
7290                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7291                        || (tr.intent == null)
7292                        || ((tr.intent.getFlags()
7293                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7294                    if (!allowed) {
7295                        // If the caller doesn't have the GET_TASKS permission, then only
7296                        // allow them to see a small subset of tasks -- their own and home.
7297                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7298                            continue;
7299                        }
7300                    }
7301                    if (tr.intent != null &&
7302                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7303                            != 0 && tr.getTopActivity() == null) {
7304                        // Don't include auto remove tasks that are finished or finishing.
7305                        continue;
7306                    }
7307
7308                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7309                    if (!detailed) {
7310                        rti.baseIntent.replaceExtras((Bundle)null);
7311                    }
7312
7313                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7314                        // Check whether this activity is currently available.
7315                        try {
7316                            if (rti.origActivity != null) {
7317                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7318                                        == null) {
7319                                    continue;
7320                                }
7321                            } else if (rti.baseIntent != null) {
7322                                if (pm.queryIntentActivities(rti.baseIntent,
7323                                        null, 0, userId) == null) {
7324                                    continue;
7325                                }
7326                            }
7327                        } catch (RemoteException e) {
7328                            // Will never happen.
7329                        }
7330                    }
7331
7332                    res.add(rti);
7333                    maxNum--;
7334                }
7335            }
7336            return res;
7337        }
7338    }
7339
7340    private TaskRecord recentTaskForIdLocked(int id) {
7341        final int N = mRecentTasks.size();
7342            for (int i=0; i<N; i++) {
7343                TaskRecord tr = mRecentTasks.get(i);
7344                if (tr.taskId == id) {
7345                    return tr;
7346                }
7347            }
7348            return null;
7349    }
7350
7351    @Override
7352    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7353        synchronized (this) {
7354            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7355                    "getTaskThumbnails()");
7356            TaskRecord tr = recentTaskForIdLocked(id);
7357            if (tr != null) {
7358                return tr.getTaskThumbnailsLocked();
7359            }
7360        }
7361        return null;
7362    }
7363
7364    @Override
7365    public Bitmap getTaskTopThumbnail(int id) {
7366        synchronized (this) {
7367            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7368                    "getTaskTopThumbnail()");
7369            TaskRecord tr = recentTaskForIdLocked(id);
7370            if (tr != null) {
7371                return tr.getTaskTopThumbnailLocked();
7372            }
7373        }
7374        return null;
7375    }
7376
7377    @Override
7378    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7379        synchronized (this) {
7380            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7381            if (r != null) {
7382                r.taskDescription = td;
7383                r.task.updateTaskDescription();
7384            }
7385        }
7386    }
7387
7388    @Override
7389    public boolean removeSubTask(int taskId, int subTaskIndex) {
7390        synchronized (this) {
7391            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7392                    "removeSubTask()");
7393            long ident = Binder.clearCallingIdentity();
7394            try {
7395                TaskRecord tr = recentTaskForIdLocked(taskId);
7396                if (tr != null) {
7397                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7398                }
7399                return false;
7400            } finally {
7401                Binder.restoreCallingIdentity(ident);
7402            }
7403        }
7404    }
7405
7406    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7407        if (!pr.killedByAm) {
7408            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7409            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7410                    pr.processName, pr.setAdj, reason);
7411            pr.killedByAm = true;
7412            Process.killProcessQuiet(pr.pid);
7413        }
7414    }
7415
7416    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7417        tr.disposeThumbnail();
7418        mRecentTasks.remove(tr);
7419        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7420        Intent baseIntent = new Intent(
7421                tr.intent != null ? tr.intent : tr.affinityIntent);
7422        ComponentName component = baseIntent.getComponent();
7423        if (component == null) {
7424            Slog.w(TAG, "Now component for base intent of task: " + tr);
7425            return;
7426        }
7427
7428        // Find any running services associated with this app.
7429        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7430
7431        if (killProcesses) {
7432            // Find any running processes associated with this app.
7433            final String pkg = component.getPackageName();
7434            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7435            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7436            for (int i=0; i<pmap.size(); i++) {
7437                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7438                for (int j=0; j<uids.size(); j++) {
7439                    ProcessRecord proc = uids.valueAt(j);
7440                    if (proc.userId != tr.userId) {
7441                        continue;
7442                    }
7443                    if (!proc.pkgList.containsKey(pkg)) {
7444                        continue;
7445                    }
7446                    procs.add(proc);
7447                }
7448            }
7449
7450            // Kill the running processes.
7451            for (int i=0; i<procs.size(); i++) {
7452                ProcessRecord pr = procs.get(i);
7453                if (pr == mHomeProcess) {
7454                    // Don't kill the home process along with tasks from the same package.
7455                    continue;
7456                }
7457                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7458                    killUnneededProcessLocked(pr, "remove task");
7459                } else {
7460                    pr.waitingToKill = "remove task";
7461                }
7462            }
7463        }
7464    }
7465
7466    /**
7467     * Removes the task with the specified task id.
7468     *
7469     * @param taskId Identifier of the task to be removed.
7470     * @param flags Additional operational flags.  May be 0 or
7471     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7472     * @return Returns true if the given task was found and removed.
7473     */
7474    private boolean removeTaskByIdLocked(int taskId, int flags) {
7475        TaskRecord tr = recentTaskForIdLocked(taskId);
7476        if (tr != null) {
7477            tr.removeTaskActivitiesLocked(-1, false);
7478            cleanUpRemovedTaskLocked(tr, flags);
7479            if (tr.isPersistable) {
7480                notifyTaskPersisterLocked(tr, true);
7481            }
7482            return true;
7483        }
7484        return false;
7485    }
7486
7487    @Override
7488    public boolean removeTask(int taskId, int flags) {
7489        synchronized (this) {
7490            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7491                    "removeTask()");
7492            long ident = Binder.clearCallingIdentity();
7493            try {
7494                return removeTaskByIdLocked(taskId, flags);
7495            } finally {
7496                Binder.restoreCallingIdentity(ident);
7497            }
7498        }
7499    }
7500
7501    /**
7502     * TODO: Add mController hook
7503     */
7504    @Override
7505    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7506        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7507                "moveTaskToFront()");
7508
7509        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7510        synchronized(this) {
7511            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7512                    Binder.getCallingUid(), "Task to front")) {
7513                ActivityOptions.abort(options);
7514                return;
7515            }
7516            final long origId = Binder.clearCallingIdentity();
7517            try {
7518                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7519                if (task == null) {
7520                    return;
7521                }
7522                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7523                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7524                    return;
7525                }
7526                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7527                if (prev != null && prev.isRecentsActivity()) {
7528                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7529                }
7530                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7531            } finally {
7532                Binder.restoreCallingIdentity(origId);
7533            }
7534            ActivityOptions.abort(options);
7535        }
7536    }
7537
7538    @Override
7539    public void moveTaskToBack(int taskId) {
7540        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7541                "moveTaskToBack()");
7542
7543        synchronized(this) {
7544            TaskRecord tr = recentTaskForIdLocked(taskId);
7545            if (tr != null) {
7546                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7547                ActivityStack stack = tr.stack;
7548                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7549                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7550                            Binder.getCallingUid(), "Task to back")) {
7551                        return;
7552                    }
7553                }
7554                final long origId = Binder.clearCallingIdentity();
7555                try {
7556                    stack.moveTaskToBackLocked(taskId, null);
7557                } finally {
7558                    Binder.restoreCallingIdentity(origId);
7559                }
7560            }
7561        }
7562    }
7563
7564    /**
7565     * Moves an activity, and all of the other activities within the same task, to the bottom
7566     * of the history stack.  The activity's order within the task is unchanged.
7567     *
7568     * @param token A reference to the activity we wish to move
7569     * @param nonRoot If false then this only works if the activity is the root
7570     *                of a task; if true it will work for any activity in a task.
7571     * @return Returns true if the move completed, false if not.
7572     */
7573    @Override
7574    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7575        enforceNotIsolatedCaller("moveActivityTaskToBack");
7576        synchronized(this) {
7577            final long origId = Binder.clearCallingIdentity();
7578            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7579            if (taskId >= 0) {
7580                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7581            }
7582            Binder.restoreCallingIdentity(origId);
7583        }
7584        return false;
7585    }
7586
7587    @Override
7588    public void moveTaskBackwards(int task) {
7589        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7590                "moveTaskBackwards()");
7591
7592        synchronized(this) {
7593            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7594                    Binder.getCallingUid(), "Task backwards")) {
7595                return;
7596            }
7597            final long origId = Binder.clearCallingIdentity();
7598            moveTaskBackwardsLocked(task);
7599            Binder.restoreCallingIdentity(origId);
7600        }
7601    }
7602
7603    private final void moveTaskBackwardsLocked(int task) {
7604        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7605    }
7606
7607    @Override
7608    public IBinder getHomeActivityToken() throws RemoteException {
7609        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7610                "getHomeActivityToken()");
7611        synchronized (this) {
7612            return mStackSupervisor.getHomeActivityToken();
7613        }
7614    }
7615
7616    @Override
7617    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7618            IActivityContainerCallback callback) throws RemoteException {
7619        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7620                "createActivityContainer()");
7621        synchronized (this) {
7622            if (parentActivityToken == null) {
7623                throw new IllegalArgumentException("parent token must not be null");
7624            }
7625            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7626            if (r == null) {
7627                return null;
7628            }
7629            if (callback == null) {
7630                throw new IllegalArgumentException("callback must not be null");
7631            }
7632            return mStackSupervisor.createActivityContainer(r, callback);
7633        }
7634    }
7635
7636    @Override
7637    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7638        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7639                "deleteActivityContainer()");
7640        synchronized (this) {
7641            mStackSupervisor.deleteActivityContainer(container);
7642        }
7643    }
7644
7645    @Override
7646    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7647            throws RemoteException {
7648        synchronized (this) {
7649            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7650            if (stack != null) {
7651                return stack.mActivityContainer;
7652            }
7653            return null;
7654        }
7655    }
7656
7657    @Override
7658    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7659        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7660                "moveTaskToStack()");
7661        if (stackId == HOME_STACK_ID) {
7662            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7663                    new RuntimeException("here").fillInStackTrace());
7664        }
7665        synchronized (this) {
7666            long ident = Binder.clearCallingIdentity();
7667            try {
7668                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7669                        + stackId + " toTop=" + toTop);
7670                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7671            } finally {
7672                Binder.restoreCallingIdentity(ident);
7673            }
7674        }
7675    }
7676
7677    @Override
7678    public void resizeStack(int stackBoxId, Rect bounds) {
7679        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7680                "resizeStackBox()");
7681        long ident = Binder.clearCallingIdentity();
7682        try {
7683            mWindowManager.resizeStack(stackBoxId, bounds);
7684        } finally {
7685            Binder.restoreCallingIdentity(ident);
7686        }
7687    }
7688
7689    @Override
7690    public List<StackInfo> getAllStackInfos() {
7691        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7692                "getAllStackInfos()");
7693        long ident = Binder.clearCallingIdentity();
7694        try {
7695            synchronized (this) {
7696                return mStackSupervisor.getAllStackInfosLocked();
7697            }
7698        } finally {
7699            Binder.restoreCallingIdentity(ident);
7700        }
7701    }
7702
7703    @Override
7704    public StackInfo getStackInfo(int stackId) {
7705        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7706                "getStackInfo()");
7707        long ident = Binder.clearCallingIdentity();
7708        try {
7709            synchronized (this) {
7710                return mStackSupervisor.getStackInfoLocked(stackId);
7711            }
7712        } finally {
7713            Binder.restoreCallingIdentity(ident);
7714        }
7715    }
7716
7717    @Override
7718    public boolean isInHomeStack(int taskId) {
7719        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7720                "getStackInfo()");
7721        long ident = Binder.clearCallingIdentity();
7722        try {
7723            synchronized (this) {
7724                TaskRecord tr = recentTaskForIdLocked(taskId);
7725                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7726            }
7727        } finally {
7728            Binder.restoreCallingIdentity(ident);
7729        }
7730    }
7731
7732    @Override
7733    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7734        synchronized(this) {
7735            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7736        }
7737    }
7738
7739    private boolean isLockTaskAuthorized(String pkg) {
7740        final DevicePolicyManager dpm = (DevicePolicyManager)
7741                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7742        try {
7743            int uid = mContext.getPackageManager().getPackageUid(pkg,
7744                    Binder.getCallingUserHandle().getIdentifier());
7745            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7746        } catch (NameNotFoundException e) {
7747            return false;
7748        }
7749    }
7750
7751    void startLockTaskMode(TaskRecord task) {
7752        final String pkg;
7753        synchronized (this) {
7754            pkg = task.intent.getComponent().getPackageName();
7755        }
7756        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7757        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7758            final TaskRecord taskRecord = task;
7759            mHandler.post(new Runnable() {
7760                @Override
7761                public void run() {
7762                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7763                }
7764            });
7765            return;
7766        }
7767        long ident = Binder.clearCallingIdentity();
7768        try {
7769            synchronized (this) {
7770                // Since we lost lock on task, make sure it is still there.
7771                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7772                if (task != null) {
7773                    if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
7774                        throw new IllegalArgumentException("Invalid task, not in foreground");
7775                    }
7776                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7777                }
7778            }
7779        } finally {
7780            Binder.restoreCallingIdentity(ident);
7781        }
7782    }
7783
7784    @Override
7785    public void startLockTaskMode(int taskId) {
7786        final TaskRecord task;
7787        long ident = Binder.clearCallingIdentity();
7788        try {
7789            synchronized (this) {
7790                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7791            }
7792        } finally {
7793            Binder.restoreCallingIdentity(ident);
7794        }
7795        if (task != null) {
7796            startLockTaskMode(task);
7797        }
7798    }
7799
7800    @Override
7801    public void startLockTaskMode(IBinder token) {
7802        final TaskRecord task;
7803        long ident = Binder.clearCallingIdentity();
7804        try {
7805            synchronized (this) {
7806                final ActivityRecord r = ActivityRecord.forToken(token);
7807                if (r == null) {
7808                    return;
7809                }
7810                task = r.task;
7811            }
7812        } finally {
7813            Binder.restoreCallingIdentity(ident);
7814        }
7815        if (task != null) {
7816            startLockTaskMode(task);
7817        }
7818    }
7819
7820    @Override
7821    public void startLockTaskModeOnCurrent() throws RemoteException {
7822        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7823        ActivityRecord r = null;
7824        synchronized (this) {
7825            r = mStackSupervisor.topRunningActivityLocked();
7826        }
7827        startLockTaskMode(r.task);
7828    }
7829
7830    @Override
7831    public void stopLockTaskMode() {
7832        // Verify that the user matches the package of the intent for the TaskRecord
7833        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7834        // and stopLockTaskMode.
7835        final int callingUid = Binder.getCallingUid();
7836        if (callingUid != Process.SYSTEM_UID) {
7837            try {
7838                String pkg =
7839                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7840                int uid = mContext.getPackageManager().getPackageUid(pkg,
7841                        Binder.getCallingUserHandle().getIdentifier());
7842                if (uid != callingUid) {
7843                    throw new SecurityException("Invalid uid, expected " + uid);
7844                }
7845            } catch (NameNotFoundException e) {
7846                Log.d(TAG, "stopLockTaskMode " + e);
7847                return;
7848            }
7849        }
7850        long ident = Binder.clearCallingIdentity();
7851        try {
7852            Log.d(TAG, "stopLockTaskMode");
7853            // Stop lock task
7854            synchronized (this) {
7855                mStackSupervisor.setLockTaskModeLocked(null, false);
7856            }
7857        } finally {
7858            Binder.restoreCallingIdentity(ident);
7859        }
7860    }
7861
7862    @Override
7863    public void stopLockTaskModeOnCurrent() throws RemoteException {
7864        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7865        long ident = Binder.clearCallingIdentity();
7866        try {
7867            stopLockTaskMode();
7868        } finally {
7869            Binder.restoreCallingIdentity(ident);
7870        }
7871    }
7872
7873    @Override
7874    public boolean isInLockTaskMode() {
7875        synchronized (this) {
7876            return mStackSupervisor.isInLockTaskMode();
7877        }
7878    }
7879
7880    // =========================================================
7881    // CONTENT PROVIDERS
7882    // =========================================================
7883
7884    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7885        List<ProviderInfo> providers = null;
7886        try {
7887            providers = AppGlobals.getPackageManager().
7888                queryContentProviders(app.processName, app.uid,
7889                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7890        } catch (RemoteException ex) {
7891        }
7892        if (DEBUG_MU)
7893            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7894        int userId = app.userId;
7895        if (providers != null) {
7896            int N = providers.size();
7897            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7898            for (int i=0; i<N; i++) {
7899                ProviderInfo cpi =
7900                    (ProviderInfo)providers.get(i);
7901                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7902                        cpi.name, cpi.flags);
7903                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7904                    // This is a singleton provider, but a user besides the
7905                    // default user is asking to initialize a process it runs
7906                    // in...  well, no, it doesn't actually run in this process,
7907                    // it runs in the process of the default user.  Get rid of it.
7908                    providers.remove(i);
7909                    N--;
7910                    i--;
7911                    continue;
7912                }
7913
7914                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7915                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7916                if (cpr == null) {
7917                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7918                    mProviderMap.putProviderByClass(comp, cpr);
7919                }
7920                if (DEBUG_MU)
7921                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7922                app.pubProviders.put(cpi.name, cpr);
7923                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7924                    // Don't add this if it is a platform component that is marked
7925                    // to run in multiple processes, because this is actually
7926                    // part of the framework so doesn't make sense to track as a
7927                    // separate apk in the process.
7928                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7929                            mProcessStats);
7930                }
7931                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7932            }
7933        }
7934        return providers;
7935    }
7936
7937    /**
7938     * Check if {@link ProcessRecord} has a possible chance at accessing the
7939     * given {@link ProviderInfo}. Final permission checking is always done
7940     * in {@link ContentProvider}.
7941     */
7942    private final String checkContentProviderPermissionLocked(
7943            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7944        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7945        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7946        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7947        // Looking for cross-user grants before to enforce the typical cross-users permissions
7948        if (userId != UserHandle.getUserId(callingUid)) {
7949            if (perms != null) {
7950                for (GrantUri grantUri : perms.keySet()) {
7951                    if (grantUri.sourceUserId == userId) {
7952                        String authority = grantUri.uri.getAuthority();
7953                        if (authority.equals(cpi.authority)) {
7954                            return null;
7955                        }
7956                    }
7957                }
7958            }
7959        }
7960        if (checkUser) {
7961            userId = handleIncomingUser(callingPid, callingUid, userId,
7962                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7963        }
7964        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7965                cpi.applicationInfo.uid, cpi.exported)
7966                == PackageManager.PERMISSION_GRANTED) {
7967            return null;
7968        }
7969        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7970                cpi.applicationInfo.uid, cpi.exported)
7971                == PackageManager.PERMISSION_GRANTED) {
7972            return null;
7973        }
7974
7975        PathPermission[] pps = cpi.pathPermissions;
7976        if (pps != null) {
7977            int i = pps.length;
7978            while (i > 0) {
7979                i--;
7980                PathPermission pp = pps[i];
7981                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7982                        cpi.applicationInfo.uid, cpi.exported)
7983                        == PackageManager.PERMISSION_GRANTED) {
7984                    return null;
7985                }
7986                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7987                        cpi.applicationInfo.uid, cpi.exported)
7988                        == PackageManager.PERMISSION_GRANTED) {
7989                    return null;
7990                }
7991            }
7992        }
7993
7994        if (perms != null) {
7995            for (GrantUri grantUri : perms.keySet()) {
7996                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7997                    return null;
7998                }
7999            }
8000        }
8001
8002        String msg;
8003        if (!cpi.exported) {
8004            msg = "Permission Denial: opening provider " + cpi.name
8005                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8006                    + ", uid=" + callingUid + ") that is not exported from uid "
8007                    + cpi.applicationInfo.uid;
8008        } else {
8009            msg = "Permission Denial: opening provider " + cpi.name
8010                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8011                    + ", uid=" + callingUid + ") requires "
8012                    + cpi.readPermission + " or " + cpi.writePermission;
8013        }
8014        Slog.w(TAG, msg);
8015        return msg;
8016    }
8017
8018    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8019            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8020        if (r != null) {
8021            for (int i=0; i<r.conProviders.size(); i++) {
8022                ContentProviderConnection conn = r.conProviders.get(i);
8023                if (conn.provider == cpr) {
8024                    if (DEBUG_PROVIDER) Slog.v(TAG,
8025                            "Adding provider requested by "
8026                            + r.processName + " from process "
8027                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8028                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8029                    if (stable) {
8030                        conn.stableCount++;
8031                        conn.numStableIncs++;
8032                    } else {
8033                        conn.unstableCount++;
8034                        conn.numUnstableIncs++;
8035                    }
8036                    return conn;
8037                }
8038            }
8039            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8040            if (stable) {
8041                conn.stableCount = 1;
8042                conn.numStableIncs = 1;
8043            } else {
8044                conn.unstableCount = 1;
8045                conn.numUnstableIncs = 1;
8046            }
8047            cpr.connections.add(conn);
8048            r.conProviders.add(conn);
8049            return conn;
8050        }
8051        cpr.addExternalProcessHandleLocked(externalProcessToken);
8052        return null;
8053    }
8054
8055    boolean decProviderCountLocked(ContentProviderConnection conn,
8056            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8057        if (conn != null) {
8058            cpr = conn.provider;
8059            if (DEBUG_PROVIDER) Slog.v(TAG,
8060                    "Removing provider requested by "
8061                    + conn.client.processName + " from process "
8062                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8063                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8064            if (stable) {
8065                conn.stableCount--;
8066            } else {
8067                conn.unstableCount--;
8068            }
8069            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8070                cpr.connections.remove(conn);
8071                conn.client.conProviders.remove(conn);
8072                return true;
8073            }
8074            return false;
8075        }
8076        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8077        return false;
8078    }
8079
8080    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8081            String name, IBinder token, boolean stable, int userId) {
8082        ContentProviderRecord cpr;
8083        ContentProviderConnection conn = null;
8084        ProviderInfo cpi = null;
8085
8086        synchronized(this) {
8087            ProcessRecord r = null;
8088            if (caller != null) {
8089                r = getRecordForAppLocked(caller);
8090                if (r == null) {
8091                    throw new SecurityException(
8092                            "Unable to find app for caller " + caller
8093                          + " (pid=" + Binder.getCallingPid()
8094                          + ") when getting content provider " + name);
8095                }
8096            }
8097
8098            boolean checkCrossUser = true;
8099
8100            // First check if this content provider has been published...
8101            cpr = mProviderMap.getProviderByName(name, userId);
8102            // If that didn't work, check if it exists for user 0 and then
8103            // verify that it's a singleton provider before using it.
8104            if (cpr == null && userId != UserHandle.USER_OWNER) {
8105                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8106                if (cpr != null) {
8107                    cpi = cpr.info;
8108                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8109                            cpi.name, cpi.flags)
8110                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8111                        userId = UserHandle.USER_OWNER;
8112                        checkCrossUser = false;
8113                    } else {
8114                        cpr = null;
8115                        cpi = null;
8116                    }
8117                }
8118            }
8119
8120            boolean providerRunning = cpr != null;
8121            if (providerRunning) {
8122                cpi = cpr.info;
8123                String msg;
8124                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8125                        != null) {
8126                    throw new SecurityException(msg);
8127                }
8128
8129                if (r != null && cpr.canRunHere(r)) {
8130                    // This provider has been published or is in the process
8131                    // of being published...  but it is also allowed to run
8132                    // in the caller's process, so don't make a connection
8133                    // and just let the caller instantiate its own instance.
8134                    ContentProviderHolder holder = cpr.newHolder(null);
8135                    // don't give caller the provider object, it needs
8136                    // to make its own.
8137                    holder.provider = null;
8138                    return holder;
8139                }
8140
8141                final long origId = Binder.clearCallingIdentity();
8142
8143                // In this case the provider instance already exists, so we can
8144                // return it right away.
8145                conn = incProviderCountLocked(r, cpr, token, stable);
8146                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8147                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8148                        // If this is a perceptible app accessing the provider,
8149                        // make sure to count it as being accessed and thus
8150                        // back up on the LRU list.  This is good because
8151                        // content providers are often expensive to start.
8152                        updateLruProcessLocked(cpr.proc, false, null);
8153                    }
8154                }
8155
8156                if (cpr.proc != null) {
8157                    if (false) {
8158                        if (cpr.name.flattenToShortString().equals(
8159                                "com.android.providers.calendar/.CalendarProvider2")) {
8160                            Slog.v(TAG, "****************** KILLING "
8161                                + cpr.name.flattenToShortString());
8162                            Process.killProcess(cpr.proc.pid);
8163                        }
8164                    }
8165                    boolean success = updateOomAdjLocked(cpr.proc);
8166                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8167                    // NOTE: there is still a race here where a signal could be
8168                    // pending on the process even though we managed to update its
8169                    // adj level.  Not sure what to do about this, but at least
8170                    // the race is now smaller.
8171                    if (!success) {
8172                        // Uh oh...  it looks like the provider's process
8173                        // has been killed on us.  We need to wait for a new
8174                        // process to be started, and make sure its death
8175                        // doesn't kill our process.
8176                        Slog.i(TAG,
8177                                "Existing provider " + cpr.name.flattenToShortString()
8178                                + " is crashing; detaching " + r);
8179                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8180                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8181                        if (!lastRef) {
8182                            // This wasn't the last ref our process had on
8183                            // the provider...  we have now been killed, bail.
8184                            return null;
8185                        }
8186                        providerRunning = false;
8187                        conn = null;
8188                    }
8189                }
8190
8191                Binder.restoreCallingIdentity(origId);
8192            }
8193
8194            boolean singleton;
8195            if (!providerRunning) {
8196                try {
8197                    cpi = AppGlobals.getPackageManager().
8198                        resolveContentProvider(name,
8199                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8200                } catch (RemoteException ex) {
8201                }
8202                if (cpi == null) {
8203                    return null;
8204                }
8205                // If the provider is a singleton AND
8206                // (it's a call within the same user || the provider is a
8207                // privileged app)
8208                // Then allow connecting to the singleton provider
8209                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8210                        cpi.name, cpi.flags)
8211                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8212                if (singleton) {
8213                    userId = UserHandle.USER_OWNER;
8214                }
8215                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8216
8217                String msg;
8218                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8219                        != null) {
8220                    throw new SecurityException(msg);
8221                }
8222
8223                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8224                        && !cpi.processName.equals("system")) {
8225                    // If this content provider does not run in the system
8226                    // process, and the system is not yet ready to run other
8227                    // processes, then fail fast instead of hanging.
8228                    throw new IllegalArgumentException(
8229                            "Attempt to launch content provider before system ready");
8230                }
8231
8232                // Make sure that the user who owns this provider is started.  If not,
8233                // we don't want to allow it to run.
8234                if (mStartedUsers.get(userId) == null) {
8235                    Slog.w(TAG, "Unable to launch app "
8236                            + cpi.applicationInfo.packageName + "/"
8237                            + cpi.applicationInfo.uid + " for provider "
8238                            + name + ": user " + userId + " is stopped");
8239                    return null;
8240                }
8241
8242                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8243                cpr = mProviderMap.getProviderByClass(comp, userId);
8244                final boolean firstClass = cpr == null;
8245                if (firstClass) {
8246                    try {
8247                        ApplicationInfo ai =
8248                            AppGlobals.getPackageManager().
8249                                getApplicationInfo(
8250                                        cpi.applicationInfo.packageName,
8251                                        STOCK_PM_FLAGS, userId);
8252                        if (ai == null) {
8253                            Slog.w(TAG, "No package info for content provider "
8254                                    + cpi.name);
8255                            return null;
8256                        }
8257                        ai = getAppInfoForUser(ai, userId);
8258                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8259                    } catch (RemoteException ex) {
8260                        // pm is in same process, this will never happen.
8261                    }
8262                }
8263
8264                if (r != null && cpr.canRunHere(r)) {
8265                    // If this is a multiprocess provider, then just return its
8266                    // info and allow the caller to instantiate it.  Only do
8267                    // this if the provider is the same user as the caller's
8268                    // process, or can run as root (so can be in any process).
8269                    return cpr.newHolder(null);
8270                }
8271
8272                if (DEBUG_PROVIDER) {
8273                    RuntimeException e = new RuntimeException("here");
8274                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8275                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8276                }
8277
8278                // This is single process, and our app is now connecting to it.
8279                // See if we are already in the process of launching this
8280                // provider.
8281                final int N = mLaunchingProviders.size();
8282                int i;
8283                for (i=0; i<N; i++) {
8284                    if (mLaunchingProviders.get(i) == cpr) {
8285                        break;
8286                    }
8287                }
8288
8289                // If the provider is not already being launched, then get it
8290                // started.
8291                if (i >= N) {
8292                    final long origId = Binder.clearCallingIdentity();
8293
8294                    try {
8295                        // Content provider is now in use, its package can't be stopped.
8296                        try {
8297                            AppGlobals.getPackageManager().setPackageStoppedState(
8298                                    cpr.appInfo.packageName, false, userId);
8299                        } catch (RemoteException e) {
8300                        } catch (IllegalArgumentException e) {
8301                            Slog.w(TAG, "Failed trying to unstop package "
8302                                    + cpr.appInfo.packageName + ": " + e);
8303                        }
8304
8305                        // Use existing process if already started
8306                        ProcessRecord proc = getProcessRecordLocked(
8307                                cpi.processName, cpr.appInfo.uid, false);
8308                        if (proc != null && proc.thread != null) {
8309                            if (DEBUG_PROVIDER) {
8310                                Slog.d(TAG, "Installing in existing process " + proc);
8311                            }
8312                            proc.pubProviders.put(cpi.name, cpr);
8313                            try {
8314                                proc.thread.scheduleInstallProvider(cpi);
8315                            } catch (RemoteException e) {
8316                            }
8317                        } else {
8318                            proc = startProcessLocked(cpi.processName,
8319                                    cpr.appInfo, false, 0, "content provider",
8320                                    new ComponentName(cpi.applicationInfo.packageName,
8321                                            cpi.name), false, false, false);
8322                            if (proc == null) {
8323                                Slog.w(TAG, "Unable to launch app "
8324                                        + cpi.applicationInfo.packageName + "/"
8325                                        + cpi.applicationInfo.uid + " for provider "
8326                                        + name + ": process is bad");
8327                                return null;
8328                            }
8329                        }
8330                        cpr.launchingApp = proc;
8331                        mLaunchingProviders.add(cpr);
8332                    } finally {
8333                        Binder.restoreCallingIdentity(origId);
8334                    }
8335                }
8336
8337                // Make sure the provider is published (the same provider class
8338                // may be published under multiple names).
8339                if (firstClass) {
8340                    mProviderMap.putProviderByClass(comp, cpr);
8341                }
8342
8343                mProviderMap.putProviderByName(name, cpr);
8344                conn = incProviderCountLocked(r, cpr, token, stable);
8345                if (conn != null) {
8346                    conn.waiting = true;
8347                }
8348            }
8349        }
8350
8351        // Wait for the provider to be published...
8352        synchronized (cpr) {
8353            while (cpr.provider == null) {
8354                if (cpr.launchingApp == null) {
8355                    Slog.w(TAG, "Unable to launch app "
8356                            + cpi.applicationInfo.packageName + "/"
8357                            + cpi.applicationInfo.uid + " for provider "
8358                            + name + ": launching app became null");
8359                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8360                            UserHandle.getUserId(cpi.applicationInfo.uid),
8361                            cpi.applicationInfo.packageName,
8362                            cpi.applicationInfo.uid, name);
8363                    return null;
8364                }
8365                try {
8366                    if (DEBUG_MU) {
8367                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8368                                + cpr.launchingApp);
8369                    }
8370                    if (conn != null) {
8371                        conn.waiting = true;
8372                    }
8373                    cpr.wait();
8374                } catch (InterruptedException ex) {
8375                } finally {
8376                    if (conn != null) {
8377                        conn.waiting = false;
8378                    }
8379                }
8380            }
8381        }
8382        return cpr != null ? cpr.newHolder(conn) : null;
8383    }
8384
8385    @Override
8386    public final ContentProviderHolder getContentProvider(
8387            IApplicationThread caller, String name, int userId, boolean stable) {
8388        enforceNotIsolatedCaller("getContentProvider");
8389        if (caller == null) {
8390            String msg = "null IApplicationThread when getting content provider "
8391                    + name;
8392            Slog.w(TAG, msg);
8393            throw new SecurityException(msg);
8394        }
8395        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8396        // with cross-user grant.
8397        return getContentProviderImpl(caller, name, null, stable, userId);
8398    }
8399
8400    public ContentProviderHolder getContentProviderExternal(
8401            String name, int userId, IBinder token) {
8402        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8403            "Do not have permission in call getContentProviderExternal()");
8404        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8405                false, true, "getContentProvider", null);
8406        return getContentProviderExternalUnchecked(name, token, userId);
8407    }
8408
8409    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8410            IBinder token, int userId) {
8411        return getContentProviderImpl(null, name, token, true, userId);
8412    }
8413
8414    /**
8415     * Drop a content provider from a ProcessRecord's bookkeeping
8416     */
8417    public void removeContentProvider(IBinder connection, boolean stable) {
8418        enforceNotIsolatedCaller("removeContentProvider");
8419        long ident = Binder.clearCallingIdentity();
8420        try {
8421            synchronized (this) {
8422                ContentProviderConnection conn;
8423                try {
8424                    conn = (ContentProviderConnection)connection;
8425                } catch (ClassCastException e) {
8426                    String msg ="removeContentProvider: " + connection
8427                            + " not a ContentProviderConnection";
8428                    Slog.w(TAG, msg);
8429                    throw new IllegalArgumentException(msg);
8430                }
8431                if (conn == null) {
8432                    throw new NullPointerException("connection is null");
8433                }
8434                if (decProviderCountLocked(conn, null, null, stable)) {
8435                    updateOomAdjLocked();
8436                }
8437            }
8438        } finally {
8439            Binder.restoreCallingIdentity(ident);
8440        }
8441    }
8442
8443    public void removeContentProviderExternal(String name, IBinder token) {
8444        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8445            "Do not have permission in call removeContentProviderExternal()");
8446        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8447    }
8448
8449    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8450        synchronized (this) {
8451            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8452            if(cpr == null) {
8453                //remove from mProvidersByClass
8454                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8455                return;
8456            }
8457
8458            //update content provider record entry info
8459            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8460            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8461            if (localCpr.hasExternalProcessHandles()) {
8462                if (localCpr.removeExternalProcessHandleLocked(token)) {
8463                    updateOomAdjLocked();
8464                } else {
8465                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8466                            + " with no external reference for token: "
8467                            + token + ".");
8468                }
8469            } else {
8470                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8471                        + " with no external references.");
8472            }
8473        }
8474    }
8475
8476    public final void publishContentProviders(IApplicationThread caller,
8477            List<ContentProviderHolder> providers) {
8478        if (providers == null) {
8479            return;
8480        }
8481
8482        enforceNotIsolatedCaller("publishContentProviders");
8483        synchronized (this) {
8484            final ProcessRecord r = getRecordForAppLocked(caller);
8485            if (DEBUG_MU)
8486                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8487            if (r == null) {
8488                throw new SecurityException(
8489                        "Unable to find app for caller " + caller
8490                      + " (pid=" + Binder.getCallingPid()
8491                      + ") when publishing content providers");
8492            }
8493
8494            final long origId = Binder.clearCallingIdentity();
8495
8496            final int N = providers.size();
8497            for (int i=0; i<N; i++) {
8498                ContentProviderHolder src = providers.get(i);
8499                if (src == null || src.info == null || src.provider == null) {
8500                    continue;
8501                }
8502                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8503                if (DEBUG_MU)
8504                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8505                if (dst != null) {
8506                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8507                    mProviderMap.putProviderByClass(comp, dst);
8508                    String names[] = dst.info.authority.split(";");
8509                    for (int j = 0; j < names.length; j++) {
8510                        mProviderMap.putProviderByName(names[j], dst);
8511                    }
8512
8513                    int NL = mLaunchingProviders.size();
8514                    int j;
8515                    for (j=0; j<NL; j++) {
8516                        if (mLaunchingProviders.get(j) == dst) {
8517                            mLaunchingProviders.remove(j);
8518                            j--;
8519                            NL--;
8520                        }
8521                    }
8522                    synchronized (dst) {
8523                        dst.provider = src.provider;
8524                        dst.proc = r;
8525                        dst.notifyAll();
8526                    }
8527                    updateOomAdjLocked(r);
8528                }
8529            }
8530
8531            Binder.restoreCallingIdentity(origId);
8532        }
8533    }
8534
8535    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8536        ContentProviderConnection conn;
8537        try {
8538            conn = (ContentProviderConnection)connection;
8539        } catch (ClassCastException e) {
8540            String msg ="refContentProvider: " + connection
8541                    + " not a ContentProviderConnection";
8542            Slog.w(TAG, msg);
8543            throw new IllegalArgumentException(msg);
8544        }
8545        if (conn == null) {
8546            throw new NullPointerException("connection is null");
8547        }
8548
8549        synchronized (this) {
8550            if (stable > 0) {
8551                conn.numStableIncs += stable;
8552            }
8553            stable = conn.stableCount + stable;
8554            if (stable < 0) {
8555                throw new IllegalStateException("stableCount < 0: " + stable);
8556            }
8557
8558            if (unstable > 0) {
8559                conn.numUnstableIncs += unstable;
8560            }
8561            unstable = conn.unstableCount + unstable;
8562            if (unstable < 0) {
8563                throw new IllegalStateException("unstableCount < 0: " + unstable);
8564            }
8565
8566            if ((stable+unstable) <= 0) {
8567                throw new IllegalStateException("ref counts can't go to zero here: stable="
8568                        + stable + " unstable=" + unstable);
8569            }
8570            conn.stableCount = stable;
8571            conn.unstableCount = unstable;
8572            return !conn.dead;
8573        }
8574    }
8575
8576    public void unstableProviderDied(IBinder connection) {
8577        ContentProviderConnection conn;
8578        try {
8579            conn = (ContentProviderConnection)connection;
8580        } catch (ClassCastException e) {
8581            String msg ="refContentProvider: " + connection
8582                    + " not a ContentProviderConnection";
8583            Slog.w(TAG, msg);
8584            throw new IllegalArgumentException(msg);
8585        }
8586        if (conn == null) {
8587            throw new NullPointerException("connection is null");
8588        }
8589
8590        // Safely retrieve the content provider associated with the connection.
8591        IContentProvider provider;
8592        synchronized (this) {
8593            provider = conn.provider.provider;
8594        }
8595
8596        if (provider == null) {
8597            // Um, yeah, we're way ahead of you.
8598            return;
8599        }
8600
8601        // Make sure the caller is being honest with us.
8602        if (provider.asBinder().pingBinder()) {
8603            // Er, no, still looks good to us.
8604            synchronized (this) {
8605                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8606                        + " says " + conn + " died, but we don't agree");
8607                return;
8608            }
8609        }
8610
8611        // Well look at that!  It's dead!
8612        synchronized (this) {
8613            if (conn.provider.provider != provider) {
8614                // But something changed...  good enough.
8615                return;
8616            }
8617
8618            ProcessRecord proc = conn.provider.proc;
8619            if (proc == null || proc.thread == null) {
8620                // Seems like the process is already cleaned up.
8621                return;
8622            }
8623
8624            // As far as we're concerned, this is just like receiving a
8625            // death notification...  just a bit prematurely.
8626            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8627                    + ") early provider death");
8628            final long ident = Binder.clearCallingIdentity();
8629            try {
8630                appDiedLocked(proc, proc.pid, proc.thread);
8631            } finally {
8632                Binder.restoreCallingIdentity(ident);
8633            }
8634        }
8635    }
8636
8637    @Override
8638    public void appNotRespondingViaProvider(IBinder connection) {
8639        enforceCallingPermission(
8640                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8641
8642        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8643        if (conn == null) {
8644            Slog.w(TAG, "ContentProviderConnection is null");
8645            return;
8646        }
8647
8648        final ProcessRecord host = conn.provider.proc;
8649        if (host == null) {
8650            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8651            return;
8652        }
8653
8654        final long token = Binder.clearCallingIdentity();
8655        try {
8656            appNotResponding(host, null, null, false, "ContentProvider not responding");
8657        } finally {
8658            Binder.restoreCallingIdentity(token);
8659        }
8660    }
8661
8662    public final void installSystemProviders() {
8663        List<ProviderInfo> providers;
8664        synchronized (this) {
8665            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8666            providers = generateApplicationProvidersLocked(app);
8667            if (providers != null) {
8668                for (int i=providers.size()-1; i>=0; i--) {
8669                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8670                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8671                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8672                                + ": not system .apk");
8673                        providers.remove(i);
8674                    }
8675                }
8676            }
8677        }
8678        if (providers != null) {
8679            mSystemThread.installSystemProviders(providers);
8680        }
8681
8682        mCoreSettingsObserver = new CoreSettingsObserver(this);
8683
8684        mUsageStatsService.monitorPackages();
8685    }
8686
8687    /**
8688     * Allows app to retrieve the MIME type of a URI without having permission
8689     * to access its content provider.
8690     *
8691     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8692     *
8693     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8694     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8695     */
8696    public String getProviderMimeType(Uri uri, int userId) {
8697        enforceNotIsolatedCaller("getProviderMimeType");
8698        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8699                userId, false, true, "getProviderMimeType", null);
8700        final String name = uri.getAuthority();
8701        final long ident = Binder.clearCallingIdentity();
8702        ContentProviderHolder holder = null;
8703
8704        try {
8705            holder = getContentProviderExternalUnchecked(name, null, userId);
8706            if (holder != null) {
8707                return holder.provider.getType(uri);
8708            }
8709        } catch (RemoteException e) {
8710            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8711            return null;
8712        } finally {
8713            if (holder != null) {
8714                removeContentProviderExternalUnchecked(name, null, userId);
8715            }
8716            Binder.restoreCallingIdentity(ident);
8717        }
8718
8719        return null;
8720    }
8721
8722    // =========================================================
8723    // GLOBAL MANAGEMENT
8724    // =========================================================
8725
8726    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8727            boolean isolated) {
8728        String proc = customProcess != null ? customProcess : info.processName;
8729        BatteryStatsImpl.Uid.Proc ps = null;
8730        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8731        int uid = info.uid;
8732        if (isolated) {
8733            int userId = UserHandle.getUserId(uid);
8734            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8735            while (true) {
8736                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8737                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8738                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8739                }
8740                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8741                mNextIsolatedProcessUid++;
8742                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8743                    // No process for this uid, use it.
8744                    break;
8745                }
8746                stepsLeft--;
8747                if (stepsLeft <= 0) {
8748                    return null;
8749                }
8750            }
8751        }
8752        return new ProcessRecord(stats, info, proc, uid);
8753    }
8754
8755    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8756            String abiOverride) {
8757        ProcessRecord app;
8758        if (!isolated) {
8759            app = getProcessRecordLocked(info.processName, info.uid, true);
8760        } else {
8761            app = null;
8762        }
8763
8764        if (app == null) {
8765            app = newProcessRecordLocked(info, null, isolated);
8766            mProcessNames.put(info.processName, app.uid, app);
8767            if (isolated) {
8768                mIsolatedProcesses.put(app.uid, app);
8769            }
8770            updateLruProcessLocked(app, false, null);
8771            updateOomAdjLocked();
8772        }
8773
8774        // This package really, really can not be stopped.
8775        try {
8776            AppGlobals.getPackageManager().setPackageStoppedState(
8777                    info.packageName, false, UserHandle.getUserId(app.uid));
8778        } catch (RemoteException e) {
8779        } catch (IllegalArgumentException e) {
8780            Slog.w(TAG, "Failed trying to unstop package "
8781                    + info.packageName + ": " + e);
8782        }
8783
8784        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8785                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8786            app.persistent = true;
8787            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8788        }
8789        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8790            mPersistentStartingProcesses.add(app);
8791            startProcessLocked(app, "added application", app.processName,
8792                    abiOverride);
8793        }
8794
8795        return app;
8796    }
8797
8798    public void unhandledBack() {
8799        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8800                "unhandledBack()");
8801
8802        synchronized(this) {
8803            final long origId = Binder.clearCallingIdentity();
8804            try {
8805                getFocusedStack().unhandledBackLocked();
8806            } finally {
8807                Binder.restoreCallingIdentity(origId);
8808            }
8809        }
8810    }
8811
8812    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8813        enforceNotIsolatedCaller("openContentUri");
8814        final int userId = UserHandle.getCallingUserId();
8815        String name = uri.getAuthority();
8816        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8817        ParcelFileDescriptor pfd = null;
8818        if (cph != null) {
8819            // We record the binder invoker's uid in thread-local storage before
8820            // going to the content provider to open the file.  Later, in the code
8821            // that handles all permissions checks, we look for this uid and use
8822            // that rather than the Activity Manager's own uid.  The effect is that
8823            // we do the check against the caller's permissions even though it looks
8824            // to the content provider like the Activity Manager itself is making
8825            // the request.
8826            sCallerIdentity.set(new Identity(
8827                    Binder.getCallingPid(), Binder.getCallingUid()));
8828            try {
8829                pfd = cph.provider.openFile(null, uri, "r", null);
8830            } catch (FileNotFoundException e) {
8831                // do nothing; pfd will be returned null
8832            } finally {
8833                // Ensure that whatever happens, we clean up the identity state
8834                sCallerIdentity.remove();
8835            }
8836
8837            // We've got the fd now, so we're done with the provider.
8838            removeContentProviderExternalUnchecked(name, null, userId);
8839        } else {
8840            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8841        }
8842        return pfd;
8843    }
8844
8845    // Actually is sleeping or shutting down or whatever else in the future
8846    // is an inactive state.
8847    public boolean isSleepingOrShuttingDown() {
8848        return mSleeping || mShuttingDown;
8849    }
8850
8851    public boolean isSleeping() {
8852        return mSleeping;
8853    }
8854
8855    void goingToSleep() {
8856        synchronized(this) {
8857            mWentToSleep = true;
8858            updateEventDispatchingLocked();
8859            goToSleepIfNeededLocked();
8860        }
8861    }
8862
8863    void finishRunningVoiceLocked() {
8864        if (mRunningVoice) {
8865            mRunningVoice = false;
8866            goToSleepIfNeededLocked();
8867        }
8868    }
8869
8870    void goToSleepIfNeededLocked() {
8871        if (mWentToSleep && !mRunningVoice) {
8872            if (!mSleeping) {
8873                mSleeping = true;
8874                mStackSupervisor.goingToSleepLocked();
8875
8876                // Initialize the wake times of all processes.
8877                checkExcessivePowerUsageLocked(false);
8878                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8879                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8880                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8881            }
8882        }
8883    }
8884
8885    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8886        mTaskPersister.notify(task, flush);
8887    }
8888
8889    @Override
8890    public boolean shutdown(int timeout) {
8891        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8892                != PackageManager.PERMISSION_GRANTED) {
8893            throw new SecurityException("Requires permission "
8894                    + android.Manifest.permission.SHUTDOWN);
8895        }
8896
8897        boolean timedout = false;
8898
8899        synchronized(this) {
8900            mShuttingDown = true;
8901            updateEventDispatchingLocked();
8902            timedout = mStackSupervisor.shutdownLocked(timeout);
8903        }
8904
8905        mAppOpsService.shutdown();
8906        mUsageStatsService.shutdown();
8907        mBatteryStatsService.shutdown();
8908        synchronized (this) {
8909            mProcessStats.shutdownLocked();
8910        }
8911        notifyTaskPersisterLocked(null, true);
8912
8913        return timedout;
8914    }
8915
8916    public final void activitySlept(IBinder token) {
8917        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8918
8919        final long origId = Binder.clearCallingIdentity();
8920
8921        synchronized (this) {
8922            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8923            if (r != null) {
8924                mStackSupervisor.activitySleptLocked(r);
8925            }
8926        }
8927
8928        Binder.restoreCallingIdentity(origId);
8929    }
8930
8931    void logLockScreen(String msg) {
8932        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8933                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8934                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8935                mStackSupervisor.mDismissKeyguardOnNextActivity);
8936    }
8937
8938    private void comeOutOfSleepIfNeededLocked() {
8939        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8940            if (mSleeping) {
8941                mSleeping = false;
8942                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8943            }
8944        }
8945    }
8946
8947    void wakingUp() {
8948        synchronized(this) {
8949            mWentToSleep = false;
8950            updateEventDispatchingLocked();
8951            comeOutOfSleepIfNeededLocked();
8952        }
8953    }
8954
8955    void startRunningVoiceLocked() {
8956        if (!mRunningVoice) {
8957            mRunningVoice = true;
8958            comeOutOfSleepIfNeededLocked();
8959        }
8960    }
8961
8962    private void updateEventDispatchingLocked() {
8963        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8964    }
8965
8966    public void setLockScreenShown(boolean shown) {
8967        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8968                != PackageManager.PERMISSION_GRANTED) {
8969            throw new SecurityException("Requires permission "
8970                    + android.Manifest.permission.DEVICE_POWER);
8971        }
8972
8973        synchronized(this) {
8974            long ident = Binder.clearCallingIdentity();
8975            try {
8976                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8977                mLockScreenShown = shown;
8978                comeOutOfSleepIfNeededLocked();
8979            } finally {
8980                Binder.restoreCallingIdentity(ident);
8981            }
8982        }
8983    }
8984
8985    public void stopAppSwitches() {
8986        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8987                != PackageManager.PERMISSION_GRANTED) {
8988            throw new SecurityException("Requires permission "
8989                    + android.Manifest.permission.STOP_APP_SWITCHES);
8990        }
8991
8992        synchronized(this) {
8993            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8994                    + APP_SWITCH_DELAY_TIME;
8995            mDidAppSwitch = false;
8996            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8997            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8998            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8999        }
9000    }
9001
9002    public void resumeAppSwitches() {
9003        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9004                != PackageManager.PERMISSION_GRANTED) {
9005            throw new SecurityException("Requires permission "
9006                    + android.Manifest.permission.STOP_APP_SWITCHES);
9007        }
9008
9009        synchronized(this) {
9010            // Note that we don't execute any pending app switches... we will
9011            // let those wait until either the timeout, or the next start
9012            // activity request.
9013            mAppSwitchesAllowedTime = 0;
9014        }
9015    }
9016
9017    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9018            String name) {
9019        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9020            return true;
9021        }
9022
9023        final int perm = checkComponentPermission(
9024                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9025                callingUid, -1, true);
9026        if (perm == PackageManager.PERMISSION_GRANTED) {
9027            return true;
9028        }
9029
9030        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9031        return false;
9032    }
9033
9034    public void setDebugApp(String packageName, boolean waitForDebugger,
9035            boolean persistent) {
9036        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9037                "setDebugApp()");
9038
9039        long ident = Binder.clearCallingIdentity();
9040        try {
9041            // Note that this is not really thread safe if there are multiple
9042            // callers into it at the same time, but that's not a situation we
9043            // care about.
9044            if (persistent) {
9045                final ContentResolver resolver = mContext.getContentResolver();
9046                Settings.Global.putString(
9047                    resolver, Settings.Global.DEBUG_APP,
9048                    packageName);
9049                Settings.Global.putInt(
9050                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9051                    waitForDebugger ? 1 : 0);
9052            }
9053
9054            synchronized (this) {
9055                if (!persistent) {
9056                    mOrigDebugApp = mDebugApp;
9057                    mOrigWaitForDebugger = mWaitForDebugger;
9058                }
9059                mDebugApp = packageName;
9060                mWaitForDebugger = waitForDebugger;
9061                mDebugTransient = !persistent;
9062                if (packageName != null) {
9063                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9064                            false, UserHandle.USER_ALL, "set debug app");
9065                }
9066            }
9067        } finally {
9068            Binder.restoreCallingIdentity(ident);
9069        }
9070    }
9071
9072    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9073        synchronized (this) {
9074            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9075            if (!isDebuggable) {
9076                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9077                    throw new SecurityException("Process not debuggable: " + app.packageName);
9078                }
9079            }
9080
9081            mOpenGlTraceApp = processName;
9082        }
9083    }
9084
9085    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9086            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9087        synchronized (this) {
9088            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9089            if (!isDebuggable) {
9090                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9091                    throw new SecurityException("Process not debuggable: " + app.packageName);
9092                }
9093            }
9094            mProfileApp = processName;
9095            mProfileFile = profileFile;
9096            if (mProfileFd != null) {
9097                try {
9098                    mProfileFd.close();
9099                } catch (IOException e) {
9100                }
9101                mProfileFd = null;
9102            }
9103            mProfileFd = profileFd;
9104            mProfileType = 0;
9105            mAutoStopProfiler = autoStopProfiler;
9106        }
9107    }
9108
9109    @Override
9110    public void setAlwaysFinish(boolean enabled) {
9111        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9112                "setAlwaysFinish()");
9113
9114        Settings.Global.putInt(
9115                mContext.getContentResolver(),
9116                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9117
9118        synchronized (this) {
9119            mAlwaysFinishActivities = enabled;
9120        }
9121    }
9122
9123    @Override
9124    public void setActivityController(IActivityController controller) {
9125        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9126                "setActivityController()");
9127        synchronized (this) {
9128            mController = controller;
9129            Watchdog.getInstance().setActivityController(controller);
9130        }
9131    }
9132
9133    @Override
9134    public void setUserIsMonkey(boolean userIsMonkey) {
9135        synchronized (this) {
9136            synchronized (mPidsSelfLocked) {
9137                final int callingPid = Binder.getCallingPid();
9138                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9139                if (precessRecord == null) {
9140                    throw new SecurityException("Unknown process: " + callingPid);
9141                }
9142                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9143                    throw new SecurityException("Only an instrumentation process "
9144                            + "with a UiAutomation can call setUserIsMonkey");
9145                }
9146            }
9147            mUserIsMonkey = userIsMonkey;
9148        }
9149    }
9150
9151    @Override
9152    public boolean isUserAMonkey() {
9153        synchronized (this) {
9154            // If there is a controller also implies the user is a monkey.
9155            return (mUserIsMonkey || mController != null);
9156        }
9157    }
9158
9159    public void requestBugReport() {
9160        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9161        SystemProperties.set("ctl.start", "bugreport");
9162    }
9163
9164    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9165        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9166    }
9167
9168    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9169        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9170            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9171        }
9172        return KEY_DISPATCHING_TIMEOUT;
9173    }
9174
9175    @Override
9176    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9177        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9178                != PackageManager.PERMISSION_GRANTED) {
9179            throw new SecurityException("Requires permission "
9180                    + android.Manifest.permission.FILTER_EVENTS);
9181        }
9182        ProcessRecord proc;
9183        long timeout;
9184        synchronized (this) {
9185            synchronized (mPidsSelfLocked) {
9186                proc = mPidsSelfLocked.get(pid);
9187            }
9188            timeout = getInputDispatchingTimeoutLocked(proc);
9189        }
9190
9191        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9192            return -1;
9193        }
9194
9195        return timeout;
9196    }
9197
9198    /**
9199     * Handle input dispatching timeouts.
9200     * Returns whether input dispatching should be aborted or not.
9201     */
9202    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9203            final ActivityRecord activity, final ActivityRecord parent,
9204            final boolean aboveSystem, String reason) {
9205        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9206                != PackageManager.PERMISSION_GRANTED) {
9207            throw new SecurityException("Requires permission "
9208                    + android.Manifest.permission.FILTER_EVENTS);
9209        }
9210
9211        final String annotation;
9212        if (reason == null) {
9213            annotation = "Input dispatching timed out";
9214        } else {
9215            annotation = "Input dispatching timed out (" + reason + ")";
9216        }
9217
9218        if (proc != null) {
9219            synchronized (this) {
9220                if (proc.debugging) {
9221                    return false;
9222                }
9223
9224                if (mDidDexOpt) {
9225                    // Give more time since we were dexopting.
9226                    mDidDexOpt = false;
9227                    return false;
9228                }
9229
9230                if (proc.instrumentationClass != null) {
9231                    Bundle info = new Bundle();
9232                    info.putString("shortMsg", "keyDispatchingTimedOut");
9233                    info.putString("longMsg", annotation);
9234                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9235                    return true;
9236                }
9237            }
9238            mHandler.post(new Runnable() {
9239                @Override
9240                public void run() {
9241                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9242                }
9243            });
9244        }
9245
9246        return true;
9247    }
9248
9249    public Bundle getAssistContextExtras(int requestType) {
9250        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9251                "getAssistContextExtras()");
9252        PendingAssistExtras pae;
9253        Bundle extras = new Bundle();
9254        synchronized (this) {
9255            ActivityRecord activity = getFocusedStack().mResumedActivity;
9256            if (activity == null) {
9257                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9258                return null;
9259            }
9260            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9261            if (activity.app == null || activity.app.thread == null) {
9262                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9263                return extras;
9264            }
9265            if (activity.app.pid == Binder.getCallingPid()) {
9266                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9267                return extras;
9268            }
9269            pae = new PendingAssistExtras(activity);
9270            try {
9271                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9272                        requestType);
9273                mPendingAssistExtras.add(pae);
9274                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9275            } catch (RemoteException e) {
9276                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9277                return extras;
9278            }
9279        }
9280        synchronized (pae) {
9281            while (!pae.haveResult) {
9282                try {
9283                    pae.wait();
9284                } catch (InterruptedException e) {
9285                }
9286            }
9287            if (pae.result != null) {
9288                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9289            }
9290        }
9291        synchronized (this) {
9292            mPendingAssistExtras.remove(pae);
9293            mHandler.removeCallbacks(pae);
9294        }
9295        return extras;
9296    }
9297
9298    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9299        PendingAssistExtras pae = (PendingAssistExtras)token;
9300        synchronized (pae) {
9301            pae.result = extras;
9302            pae.haveResult = true;
9303            pae.notifyAll();
9304        }
9305    }
9306
9307    public void registerProcessObserver(IProcessObserver observer) {
9308        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9309                "registerProcessObserver()");
9310        synchronized (this) {
9311            mProcessObservers.register(observer);
9312        }
9313    }
9314
9315    @Override
9316    public void unregisterProcessObserver(IProcessObserver observer) {
9317        synchronized (this) {
9318            mProcessObservers.unregister(observer);
9319        }
9320    }
9321
9322    @Override
9323    public boolean convertFromTranslucent(IBinder token) {
9324        final long origId = Binder.clearCallingIdentity();
9325        try {
9326            synchronized (this) {
9327                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9328                if (r == null) {
9329                    return false;
9330                }
9331                if (r.changeWindowTranslucency(true)) {
9332                    mWindowManager.setAppFullscreen(token, true);
9333                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9334                    return true;
9335                }
9336                return false;
9337            }
9338        } finally {
9339            Binder.restoreCallingIdentity(origId);
9340        }
9341    }
9342
9343    @Override
9344    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9345        final long origId = Binder.clearCallingIdentity();
9346        try {
9347            synchronized (this) {
9348                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9349                if (r == null) {
9350                    return false;
9351                }
9352                if (r.changeWindowTranslucency(false)) {
9353                    r.task.stack.convertToTranslucent(r, options);
9354                    mWindowManager.setAppFullscreen(token, false);
9355                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9356                    return true;
9357                }
9358                return false;
9359            }
9360        } finally {
9361            Binder.restoreCallingIdentity(origId);
9362        }
9363    }
9364
9365    @Override
9366    public ActivityOptions getActivityOptions(IBinder token) {
9367        final long origId = Binder.clearCallingIdentity();
9368        try {
9369            synchronized (this) {
9370                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9371                if (r != null) {
9372                    final ActivityOptions activityOptions = r.pendingOptions;
9373                    r.pendingOptions = null;
9374                    return activityOptions;
9375                }
9376                return null;
9377            }
9378        } finally {
9379            Binder.restoreCallingIdentity(origId);
9380        }
9381    }
9382
9383    @Override
9384    public void setImmersive(IBinder token, boolean immersive) {
9385        synchronized(this) {
9386            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9387            if (r == null) {
9388                throw new IllegalArgumentException();
9389            }
9390            r.immersive = immersive;
9391
9392            // update associated state if we're frontmost
9393            if (r == mFocusedActivity) {
9394                if (DEBUG_IMMERSIVE) {
9395                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9396                }
9397                applyUpdateLockStateLocked(r);
9398            }
9399        }
9400    }
9401
9402    @Override
9403    public boolean isImmersive(IBinder token) {
9404        synchronized (this) {
9405            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9406            if (r == null) {
9407                throw new IllegalArgumentException();
9408            }
9409            return r.immersive;
9410        }
9411    }
9412
9413    public boolean isTopActivityImmersive() {
9414        enforceNotIsolatedCaller("startActivity");
9415        synchronized (this) {
9416            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9417            return (r != null) ? r.immersive : false;
9418        }
9419    }
9420
9421    public final void enterSafeMode() {
9422        synchronized(this) {
9423            // It only makes sense to do this before the system is ready
9424            // and started launching other packages.
9425            if (!mSystemReady) {
9426                try {
9427                    AppGlobals.getPackageManager().enterSafeMode();
9428                } catch (RemoteException e) {
9429                }
9430            }
9431
9432            mSafeMode = true;
9433        }
9434    }
9435
9436    public final void showSafeModeOverlay() {
9437        View v = LayoutInflater.from(mContext).inflate(
9438                com.android.internal.R.layout.safe_mode, null);
9439        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9440        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9441        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9442        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9443        lp.gravity = Gravity.BOTTOM | Gravity.START;
9444        lp.format = v.getBackground().getOpacity();
9445        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9446                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9447        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9448        ((WindowManager)mContext.getSystemService(
9449                Context.WINDOW_SERVICE)).addView(v, lp);
9450    }
9451
9452    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9453        if (!(sender instanceof PendingIntentRecord)) {
9454            return;
9455        }
9456        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9457        synchronized (stats) {
9458            if (mBatteryStatsService.isOnBattery()) {
9459                mBatteryStatsService.enforceCallingPermission();
9460                PendingIntentRecord rec = (PendingIntentRecord)sender;
9461                int MY_UID = Binder.getCallingUid();
9462                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9463                BatteryStatsImpl.Uid.Pkg pkg =
9464                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9465                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9466                pkg.incWakeupsLocked();
9467            }
9468        }
9469    }
9470
9471    public boolean killPids(int[] pids, String pReason, boolean secure) {
9472        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9473            throw new SecurityException("killPids only available to the system");
9474        }
9475        String reason = (pReason == null) ? "Unknown" : pReason;
9476        // XXX Note: don't acquire main activity lock here, because the window
9477        // manager calls in with its locks held.
9478
9479        boolean killed = false;
9480        synchronized (mPidsSelfLocked) {
9481            int[] types = new int[pids.length];
9482            int worstType = 0;
9483            for (int i=0; i<pids.length; i++) {
9484                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9485                if (proc != null) {
9486                    int type = proc.setAdj;
9487                    types[i] = type;
9488                    if (type > worstType) {
9489                        worstType = type;
9490                    }
9491                }
9492            }
9493
9494            // If the worst oom_adj is somewhere in the cached proc LRU range,
9495            // then constrain it so we will kill all cached procs.
9496            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9497                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9498                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9499            }
9500
9501            // If this is not a secure call, don't let it kill processes that
9502            // are important.
9503            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9504                worstType = ProcessList.SERVICE_ADJ;
9505            }
9506
9507            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9508            for (int i=0; i<pids.length; i++) {
9509                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9510                if (proc == null) {
9511                    continue;
9512                }
9513                int adj = proc.setAdj;
9514                if (adj >= worstType && !proc.killedByAm) {
9515                    killUnneededProcessLocked(proc, reason);
9516                    killed = true;
9517                }
9518            }
9519        }
9520        return killed;
9521    }
9522
9523    @Override
9524    public void killUid(int uid, String reason) {
9525        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9526            throw new SecurityException("killUid only available to the system");
9527        }
9528        synchronized (this) {
9529            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9530                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9531                    reason != null ? reason : "kill uid");
9532        }
9533    }
9534
9535    @Override
9536    public boolean killProcessesBelowForeground(String reason) {
9537        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9538            throw new SecurityException("killProcessesBelowForeground() only available to system");
9539        }
9540
9541        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9542    }
9543
9544    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9545        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9546            throw new SecurityException("killProcessesBelowAdj() only available to system");
9547        }
9548
9549        boolean killed = false;
9550        synchronized (mPidsSelfLocked) {
9551            final int size = mPidsSelfLocked.size();
9552            for (int i = 0; i < size; i++) {
9553                final int pid = mPidsSelfLocked.keyAt(i);
9554                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9555                if (proc == null) continue;
9556
9557                final int adj = proc.setAdj;
9558                if (adj > belowAdj && !proc.killedByAm) {
9559                    killUnneededProcessLocked(proc, reason);
9560                    killed = true;
9561                }
9562            }
9563        }
9564        return killed;
9565    }
9566
9567    @Override
9568    public void hang(final IBinder who, boolean allowRestart) {
9569        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9570                != PackageManager.PERMISSION_GRANTED) {
9571            throw new SecurityException("Requires permission "
9572                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9573        }
9574
9575        final IBinder.DeathRecipient death = new DeathRecipient() {
9576            @Override
9577            public void binderDied() {
9578                synchronized (this) {
9579                    notifyAll();
9580                }
9581            }
9582        };
9583
9584        try {
9585            who.linkToDeath(death, 0);
9586        } catch (RemoteException e) {
9587            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9588            return;
9589        }
9590
9591        synchronized (this) {
9592            Watchdog.getInstance().setAllowRestart(allowRestart);
9593            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9594            synchronized (death) {
9595                while (who.isBinderAlive()) {
9596                    try {
9597                        death.wait();
9598                    } catch (InterruptedException e) {
9599                    }
9600                }
9601            }
9602            Watchdog.getInstance().setAllowRestart(true);
9603        }
9604    }
9605
9606    @Override
9607    public void restart() {
9608        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9609                != PackageManager.PERMISSION_GRANTED) {
9610            throw new SecurityException("Requires permission "
9611                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9612        }
9613
9614        Log.i(TAG, "Sending shutdown broadcast...");
9615
9616        BroadcastReceiver br = new BroadcastReceiver() {
9617            @Override public void onReceive(Context context, Intent intent) {
9618                // Now the broadcast is done, finish up the low-level shutdown.
9619                Log.i(TAG, "Shutting down activity manager...");
9620                shutdown(10000);
9621                Log.i(TAG, "Shutdown complete, restarting!");
9622                Process.killProcess(Process.myPid());
9623                System.exit(10);
9624            }
9625        };
9626
9627        // First send the high-level shut down broadcast.
9628        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9629        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9630        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9631        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9632        mContext.sendOrderedBroadcastAsUser(intent,
9633                UserHandle.ALL, null, br, mHandler, 0, null, null);
9634        */
9635        br.onReceive(mContext, intent);
9636    }
9637
9638    private long getLowRamTimeSinceIdle(long now) {
9639        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9640    }
9641
9642    @Override
9643    public void performIdleMaintenance() {
9644        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9645                != PackageManager.PERMISSION_GRANTED) {
9646            throw new SecurityException("Requires permission "
9647                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9648        }
9649
9650        synchronized (this) {
9651            final long now = SystemClock.uptimeMillis();
9652            final long timeSinceLastIdle = now - mLastIdleTime;
9653            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9654            mLastIdleTime = now;
9655            mLowRamTimeSinceLastIdle = 0;
9656            if (mLowRamStartTime != 0) {
9657                mLowRamStartTime = now;
9658            }
9659
9660            StringBuilder sb = new StringBuilder(128);
9661            sb.append("Idle maintenance over ");
9662            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9663            sb.append(" low RAM for ");
9664            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9665            Slog.i(TAG, sb.toString());
9666
9667            // If at least 1/3 of our time since the last idle period has been spent
9668            // with RAM low, then we want to kill processes.
9669            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9670
9671            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9672                ProcessRecord proc = mLruProcesses.get(i);
9673                if (proc.notCachedSinceIdle) {
9674                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9675                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9676                        if (doKilling && proc.initialIdlePss != 0
9677                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9678                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9679                                    + " from " + proc.initialIdlePss + ")");
9680                        }
9681                    }
9682                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9683                    proc.notCachedSinceIdle = true;
9684                    proc.initialIdlePss = 0;
9685                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9686                            isSleeping(), now);
9687                }
9688            }
9689
9690            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9691            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9692        }
9693    }
9694
9695    private void retrieveSettings() {
9696        final ContentResolver resolver = mContext.getContentResolver();
9697        String debugApp = Settings.Global.getString(
9698            resolver, Settings.Global.DEBUG_APP);
9699        boolean waitForDebugger = Settings.Global.getInt(
9700            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9701        boolean alwaysFinishActivities = Settings.Global.getInt(
9702            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9703        boolean forceRtl = Settings.Global.getInt(
9704                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9705        // Transfer any global setting for forcing RTL layout, into a System Property
9706        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9707
9708        Configuration configuration = new Configuration();
9709        Settings.System.getConfiguration(resolver, configuration);
9710        if (forceRtl) {
9711            // This will take care of setting the correct layout direction flags
9712            configuration.setLayoutDirection(configuration.locale);
9713        }
9714
9715        synchronized (this) {
9716            mDebugApp = mOrigDebugApp = debugApp;
9717            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9718            mAlwaysFinishActivities = alwaysFinishActivities;
9719            // This happens before any activities are started, so we can
9720            // change mConfiguration in-place.
9721            updateConfigurationLocked(configuration, null, false, true);
9722            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9723        }
9724    }
9725
9726    public boolean testIsSystemReady() {
9727        // no need to synchronize(this) just to read & return the value
9728        return mSystemReady;
9729    }
9730
9731    private static File getCalledPreBootReceiversFile() {
9732        File dataDir = Environment.getDataDirectory();
9733        File systemDir = new File(dataDir, "system");
9734        File fname = new File(systemDir, "called_pre_boots.dat");
9735        return fname;
9736    }
9737
9738    static final int LAST_DONE_VERSION = 10000;
9739
9740    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9741        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9742        File file = getCalledPreBootReceiversFile();
9743        FileInputStream fis = null;
9744        try {
9745            fis = new FileInputStream(file);
9746            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9747            int fvers = dis.readInt();
9748            if (fvers == LAST_DONE_VERSION) {
9749                String vers = dis.readUTF();
9750                String codename = dis.readUTF();
9751                String build = dis.readUTF();
9752                if (android.os.Build.VERSION.RELEASE.equals(vers)
9753                        && android.os.Build.VERSION.CODENAME.equals(codename)
9754                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9755                    int num = dis.readInt();
9756                    while (num > 0) {
9757                        num--;
9758                        String pkg = dis.readUTF();
9759                        String cls = dis.readUTF();
9760                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9761                    }
9762                }
9763            }
9764        } catch (FileNotFoundException e) {
9765        } catch (IOException e) {
9766            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9767        } finally {
9768            if (fis != null) {
9769                try {
9770                    fis.close();
9771                } catch (IOException e) {
9772                }
9773            }
9774        }
9775        return lastDoneReceivers;
9776    }
9777
9778    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9779        File file = getCalledPreBootReceiversFile();
9780        FileOutputStream fos = null;
9781        DataOutputStream dos = null;
9782        try {
9783            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9784            fos = new FileOutputStream(file);
9785            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9786            dos.writeInt(LAST_DONE_VERSION);
9787            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9788            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9789            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9790            dos.writeInt(list.size());
9791            for (int i=0; i<list.size(); i++) {
9792                dos.writeUTF(list.get(i).getPackageName());
9793                dos.writeUTF(list.get(i).getClassName());
9794            }
9795        } catch (IOException e) {
9796            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9797            file.delete();
9798        } finally {
9799            FileUtils.sync(fos);
9800            if (dos != null) {
9801                try {
9802                    dos.close();
9803                } catch (IOException e) {
9804                    // TODO Auto-generated catch block
9805                    e.printStackTrace();
9806                }
9807            }
9808        }
9809    }
9810
9811    public void systemReady(final Runnable goingCallback) {
9812        synchronized(this) {
9813            if (mSystemReady) {
9814                if (goingCallback != null) goingCallback.run();
9815                return;
9816            }
9817
9818            if (mRecentTasks == null) {
9819                mRecentTasks = mTaskPersister.restoreTasksLocked();
9820                if (!mRecentTasks.isEmpty()) {
9821                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9822                }
9823                mTaskPersister.startPersisting();
9824            }
9825
9826            // Check to see if there are any update receivers to run.
9827            if (!mDidUpdate) {
9828                if (mWaitingUpdate) {
9829                    return;
9830                }
9831                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9832                List<ResolveInfo> ris = null;
9833                try {
9834                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9835                            intent, null, 0, 0);
9836                } catch (RemoteException e) {
9837                }
9838                if (ris != null) {
9839                    for (int i=ris.size()-1; i>=0; i--) {
9840                        if ((ris.get(i).activityInfo.applicationInfo.flags
9841                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9842                            ris.remove(i);
9843                        }
9844                    }
9845                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9846
9847                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9848
9849                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9850                    for (int i=0; i<ris.size(); i++) {
9851                        ActivityInfo ai = ris.get(i).activityInfo;
9852                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9853                        if (lastDoneReceivers.contains(comp)) {
9854                            // We already did the pre boot receiver for this app with the current
9855                            // platform version, so don't do it again...
9856                            ris.remove(i);
9857                            i--;
9858                            // ...however, do keep it as one that has been done, so we don't
9859                            // forget about it when rewriting the file of last done receivers.
9860                            doneReceivers.add(comp);
9861                        }
9862                    }
9863
9864                    final int[] users = getUsersLocked();
9865                    for (int i=0; i<ris.size(); i++) {
9866                        ActivityInfo ai = ris.get(i).activityInfo;
9867                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9868                        doneReceivers.add(comp);
9869                        intent.setComponent(comp);
9870                        for (int j=0; j<users.length; j++) {
9871                            IIntentReceiver finisher = null;
9872                            if (i == ris.size()-1 && j == users.length-1) {
9873                                finisher = new IIntentReceiver.Stub() {
9874                                    public void performReceive(Intent intent, int resultCode,
9875                                            String data, Bundle extras, boolean ordered,
9876                                            boolean sticky, int sendingUser) {
9877                                        // The raw IIntentReceiver interface is called
9878                                        // with the AM lock held, so redispatch to
9879                                        // execute our code without the lock.
9880                                        mHandler.post(new Runnable() {
9881                                            public void run() {
9882                                                synchronized (ActivityManagerService.this) {
9883                                                    mDidUpdate = true;
9884                                                }
9885                                                writeLastDonePreBootReceivers(doneReceivers);
9886                                                showBootMessage(mContext.getText(
9887                                                        R.string.android_upgrading_complete),
9888                                                        false);
9889                                                systemReady(goingCallback);
9890                                            }
9891                                        });
9892                                    }
9893                                };
9894                            }
9895                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9896                                    + " for user " + users[j]);
9897                            broadcastIntentLocked(null, null, intent, null, finisher,
9898                                    0, null, null, null, AppOpsManager.OP_NONE,
9899                                    true, false, MY_PID, Process.SYSTEM_UID,
9900                                    users[j]);
9901                            if (finisher != null) {
9902                                mWaitingUpdate = true;
9903                            }
9904                        }
9905                    }
9906                }
9907                if (mWaitingUpdate) {
9908                    return;
9909                }
9910                mDidUpdate = true;
9911            }
9912
9913            mAppOpsService.systemReady();
9914            mUsageStatsService.systemReady();
9915            mSystemReady = true;
9916        }
9917
9918        ArrayList<ProcessRecord> procsToKill = null;
9919        synchronized(mPidsSelfLocked) {
9920            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9921                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9922                if (!isAllowedWhileBooting(proc.info)){
9923                    if (procsToKill == null) {
9924                        procsToKill = new ArrayList<ProcessRecord>();
9925                    }
9926                    procsToKill.add(proc);
9927                }
9928            }
9929        }
9930
9931        synchronized(this) {
9932            if (procsToKill != null) {
9933                for (int i=procsToKill.size()-1; i>=0; i--) {
9934                    ProcessRecord proc = procsToKill.get(i);
9935                    Slog.i(TAG, "Removing system update proc: " + proc);
9936                    removeProcessLocked(proc, true, false, "system update done");
9937                }
9938            }
9939
9940            // Now that we have cleaned up any update processes, we
9941            // are ready to start launching real processes and know that
9942            // we won't trample on them any more.
9943            mProcessesReady = true;
9944        }
9945
9946        Slog.i(TAG, "System now ready");
9947        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9948            SystemClock.uptimeMillis());
9949
9950        synchronized(this) {
9951            // Make sure we have no pre-ready processes sitting around.
9952
9953            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9954                ResolveInfo ri = mContext.getPackageManager()
9955                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9956                                STOCK_PM_FLAGS);
9957                CharSequence errorMsg = null;
9958                if (ri != null) {
9959                    ActivityInfo ai = ri.activityInfo;
9960                    ApplicationInfo app = ai.applicationInfo;
9961                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9962                        mTopAction = Intent.ACTION_FACTORY_TEST;
9963                        mTopData = null;
9964                        mTopComponent = new ComponentName(app.packageName,
9965                                ai.name);
9966                    } else {
9967                        errorMsg = mContext.getResources().getText(
9968                                com.android.internal.R.string.factorytest_not_system);
9969                    }
9970                } else {
9971                    errorMsg = mContext.getResources().getText(
9972                            com.android.internal.R.string.factorytest_no_action);
9973                }
9974                if (errorMsg != null) {
9975                    mTopAction = null;
9976                    mTopData = null;
9977                    mTopComponent = null;
9978                    Message msg = Message.obtain();
9979                    msg.what = SHOW_FACTORY_ERROR_MSG;
9980                    msg.getData().putCharSequence("msg", errorMsg);
9981                    mHandler.sendMessage(msg);
9982                }
9983            }
9984        }
9985
9986        retrieveSettings();
9987
9988        synchronized (this) {
9989            readGrantedUriPermissionsLocked();
9990        }
9991
9992        if (goingCallback != null) goingCallback.run();
9993
9994        mSystemServiceManager.startUser(mCurrentUserId);
9995
9996        synchronized (this) {
9997            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9998                try {
9999                    List apps = AppGlobals.getPackageManager().
10000                        getPersistentApplications(STOCK_PM_FLAGS);
10001                    if (apps != null) {
10002                        int N = apps.size();
10003                        int i;
10004                        for (i=0; i<N; i++) {
10005                            ApplicationInfo info
10006                                = (ApplicationInfo)apps.get(i);
10007                            if (info != null &&
10008                                    !info.packageName.equals("android")) {
10009                                addAppLocked(info, false, null /* ABI override */);
10010                            }
10011                        }
10012                    }
10013                } catch (RemoteException ex) {
10014                    // pm is in same process, this will never happen.
10015                }
10016            }
10017
10018            // Start up initial activity.
10019            mBooting = true;
10020
10021            try {
10022                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10023                    Message msg = Message.obtain();
10024                    msg.what = SHOW_UID_ERROR_MSG;
10025                    mHandler.sendMessage(msg);
10026                }
10027            } catch (RemoteException e) {
10028            }
10029
10030            long ident = Binder.clearCallingIdentity();
10031            try {
10032                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10033                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10034                        | Intent.FLAG_RECEIVER_FOREGROUND);
10035                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10036                broadcastIntentLocked(null, null, intent,
10037                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10038                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10039                intent = new Intent(Intent.ACTION_USER_STARTING);
10040                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10041                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10042                broadcastIntentLocked(null, null, intent,
10043                        null, new IIntentReceiver.Stub() {
10044                            @Override
10045                            public void performReceive(Intent intent, int resultCode, String data,
10046                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10047                                    throws RemoteException {
10048                            }
10049                        }, 0, null, null,
10050                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10051                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10052            } catch (Throwable t) {
10053                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10054            } finally {
10055                Binder.restoreCallingIdentity(ident);
10056            }
10057            mStackSupervisor.resumeTopActivitiesLocked();
10058            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10059        }
10060    }
10061
10062    private boolean makeAppCrashingLocked(ProcessRecord app,
10063            String shortMsg, String longMsg, String stackTrace) {
10064        app.crashing = true;
10065        app.crashingReport = generateProcessError(app,
10066                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10067        startAppProblemLocked(app);
10068        app.stopFreezingAllLocked();
10069        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10070    }
10071
10072    private void makeAppNotRespondingLocked(ProcessRecord app,
10073            String activity, String shortMsg, String longMsg) {
10074        app.notResponding = true;
10075        app.notRespondingReport = generateProcessError(app,
10076                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10077                activity, shortMsg, longMsg, null);
10078        startAppProblemLocked(app);
10079        app.stopFreezingAllLocked();
10080    }
10081
10082    /**
10083     * Generate a process error record, suitable for attachment to a ProcessRecord.
10084     *
10085     * @param app The ProcessRecord in which the error occurred.
10086     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10087     *                      ActivityManager.AppErrorStateInfo
10088     * @param activity The activity associated with the crash, if known.
10089     * @param shortMsg Short message describing the crash.
10090     * @param longMsg Long message describing the crash.
10091     * @param stackTrace Full crash stack trace, may be null.
10092     *
10093     * @return Returns a fully-formed AppErrorStateInfo record.
10094     */
10095    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10096            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10097        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10098
10099        report.condition = condition;
10100        report.processName = app.processName;
10101        report.pid = app.pid;
10102        report.uid = app.info.uid;
10103        report.tag = activity;
10104        report.shortMsg = shortMsg;
10105        report.longMsg = longMsg;
10106        report.stackTrace = stackTrace;
10107
10108        return report;
10109    }
10110
10111    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10112        synchronized (this) {
10113            app.crashing = false;
10114            app.crashingReport = null;
10115            app.notResponding = false;
10116            app.notRespondingReport = null;
10117            if (app.anrDialog == fromDialog) {
10118                app.anrDialog = null;
10119            }
10120            if (app.waitDialog == fromDialog) {
10121                app.waitDialog = null;
10122            }
10123            if (app.pid > 0 && app.pid != MY_PID) {
10124                handleAppCrashLocked(app, null, null, null);
10125                killUnneededProcessLocked(app, "user request after error");
10126            }
10127        }
10128    }
10129
10130    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10131            String stackTrace) {
10132        long now = SystemClock.uptimeMillis();
10133
10134        Long crashTime;
10135        if (!app.isolated) {
10136            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10137        } else {
10138            crashTime = null;
10139        }
10140        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10141            // This process loses!
10142            Slog.w(TAG, "Process " + app.info.processName
10143                    + " has crashed too many times: killing!");
10144            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10145                    app.userId, app.info.processName, app.uid);
10146            mStackSupervisor.handleAppCrashLocked(app);
10147            if (!app.persistent) {
10148                // We don't want to start this process again until the user
10149                // explicitly does so...  but for persistent process, we really
10150                // need to keep it running.  If a persistent process is actually
10151                // repeatedly crashing, then badness for everyone.
10152                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10153                        app.info.processName);
10154                if (!app.isolated) {
10155                    // XXX We don't have a way to mark isolated processes
10156                    // as bad, since they don't have a peristent identity.
10157                    mBadProcesses.put(app.info.processName, app.uid,
10158                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10159                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10160                }
10161                app.bad = true;
10162                app.removed = true;
10163                // Don't let services in this process be restarted and potentially
10164                // annoy the user repeatedly.  Unless it is persistent, since those
10165                // processes run critical code.
10166                removeProcessLocked(app, false, false, "crash");
10167                mStackSupervisor.resumeTopActivitiesLocked();
10168                return false;
10169            }
10170            mStackSupervisor.resumeTopActivitiesLocked();
10171        } else {
10172            mStackSupervisor.finishTopRunningActivityLocked(app);
10173        }
10174
10175        // Bump up the crash count of any services currently running in the proc.
10176        for (int i=app.services.size()-1; i>=0; i--) {
10177            // Any services running in the application need to be placed
10178            // back in the pending list.
10179            ServiceRecord sr = app.services.valueAt(i);
10180            sr.crashCount++;
10181        }
10182
10183        // If the crashing process is what we consider to be the "home process" and it has been
10184        // replaced by a third-party app, clear the package preferred activities from packages
10185        // with a home activity running in the process to prevent a repeatedly crashing app
10186        // from blocking the user to manually clear the list.
10187        final ArrayList<ActivityRecord> activities = app.activities;
10188        if (app == mHomeProcess && activities.size() > 0
10189                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10190            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10191                final ActivityRecord r = activities.get(activityNdx);
10192                if (r.isHomeActivity()) {
10193                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10194                    try {
10195                        ActivityThread.getPackageManager()
10196                                .clearPackagePreferredActivities(r.packageName);
10197                    } catch (RemoteException c) {
10198                        // pm is in same process, this will never happen.
10199                    }
10200                }
10201            }
10202        }
10203
10204        if (!app.isolated) {
10205            // XXX Can't keep track of crash times for isolated processes,
10206            // because they don't have a perisistent identity.
10207            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10208        }
10209
10210        return true;
10211    }
10212
10213    void startAppProblemLocked(ProcessRecord app) {
10214        if (app.userId == mCurrentUserId) {
10215            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10216                    mContext, app.info.packageName, app.info.flags);
10217        } else {
10218            // If this app is not running under the current user, then we
10219            // can't give it a report button because that would require
10220            // launching the report UI under a different user.
10221            app.errorReportReceiver = null;
10222        }
10223        skipCurrentReceiverLocked(app);
10224    }
10225
10226    void skipCurrentReceiverLocked(ProcessRecord app) {
10227        for (BroadcastQueue queue : mBroadcastQueues) {
10228            queue.skipCurrentReceiverLocked(app);
10229        }
10230    }
10231
10232    /**
10233     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10234     * The application process will exit immediately after this call returns.
10235     * @param app object of the crashing app, null for the system server
10236     * @param crashInfo describing the exception
10237     */
10238    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10239        ProcessRecord r = findAppProcess(app, "Crash");
10240        final String processName = app == null ? "system_server"
10241                : (r == null ? "unknown" : r.processName);
10242
10243        handleApplicationCrashInner("crash", r, processName, crashInfo);
10244    }
10245
10246    /* Native crash reporting uses this inner version because it needs to be somewhat
10247     * decoupled from the AM-managed cleanup lifecycle
10248     */
10249    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10250            ApplicationErrorReport.CrashInfo crashInfo) {
10251        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10252                UserHandle.getUserId(Binder.getCallingUid()), processName,
10253                r == null ? -1 : r.info.flags,
10254                crashInfo.exceptionClassName,
10255                crashInfo.exceptionMessage,
10256                crashInfo.throwFileName,
10257                crashInfo.throwLineNumber);
10258
10259        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10260
10261        crashApplication(r, crashInfo);
10262    }
10263
10264    public void handleApplicationStrictModeViolation(
10265            IBinder app,
10266            int violationMask,
10267            StrictMode.ViolationInfo info) {
10268        ProcessRecord r = findAppProcess(app, "StrictMode");
10269        if (r == null) {
10270            return;
10271        }
10272
10273        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10274            Integer stackFingerprint = info.hashCode();
10275            boolean logIt = true;
10276            synchronized (mAlreadyLoggedViolatedStacks) {
10277                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10278                    logIt = false;
10279                    // TODO: sub-sample into EventLog for these, with
10280                    // the info.durationMillis?  Then we'd get
10281                    // the relative pain numbers, without logging all
10282                    // the stack traces repeatedly.  We'd want to do
10283                    // likewise in the client code, which also does
10284                    // dup suppression, before the Binder call.
10285                } else {
10286                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10287                        mAlreadyLoggedViolatedStacks.clear();
10288                    }
10289                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10290                }
10291            }
10292            if (logIt) {
10293                logStrictModeViolationToDropBox(r, info);
10294            }
10295        }
10296
10297        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10298            AppErrorResult result = new AppErrorResult();
10299            synchronized (this) {
10300                final long origId = Binder.clearCallingIdentity();
10301
10302                Message msg = Message.obtain();
10303                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10304                HashMap<String, Object> data = new HashMap<String, Object>();
10305                data.put("result", result);
10306                data.put("app", r);
10307                data.put("violationMask", violationMask);
10308                data.put("info", info);
10309                msg.obj = data;
10310                mHandler.sendMessage(msg);
10311
10312                Binder.restoreCallingIdentity(origId);
10313            }
10314            int res = result.get();
10315            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10316        }
10317    }
10318
10319    // Depending on the policy in effect, there could be a bunch of
10320    // these in quick succession so we try to batch these together to
10321    // minimize disk writes, number of dropbox entries, and maximize
10322    // compression, by having more fewer, larger records.
10323    private void logStrictModeViolationToDropBox(
10324            ProcessRecord process,
10325            StrictMode.ViolationInfo info) {
10326        if (info == null) {
10327            return;
10328        }
10329        final boolean isSystemApp = process == null ||
10330                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10331                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10332        final String processName = process == null ? "unknown" : process.processName;
10333        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10334        final DropBoxManager dbox = (DropBoxManager)
10335                mContext.getSystemService(Context.DROPBOX_SERVICE);
10336
10337        // Exit early if the dropbox isn't configured to accept this report type.
10338        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10339
10340        boolean bufferWasEmpty;
10341        boolean needsFlush;
10342        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10343        synchronized (sb) {
10344            bufferWasEmpty = sb.length() == 0;
10345            appendDropBoxProcessHeaders(process, processName, sb);
10346            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10347            sb.append("System-App: ").append(isSystemApp).append("\n");
10348            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10349            if (info.violationNumThisLoop != 0) {
10350                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10351            }
10352            if (info.numAnimationsRunning != 0) {
10353                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10354            }
10355            if (info.broadcastIntentAction != null) {
10356                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10357            }
10358            if (info.durationMillis != -1) {
10359                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10360            }
10361            if (info.numInstances != -1) {
10362                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10363            }
10364            if (info.tags != null) {
10365                for (String tag : info.tags) {
10366                    sb.append("Span-Tag: ").append(tag).append("\n");
10367                }
10368            }
10369            sb.append("\n");
10370            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10371                sb.append(info.crashInfo.stackTrace);
10372            }
10373            sb.append("\n");
10374
10375            // Only buffer up to ~64k.  Various logging bits truncate
10376            // things at 128k.
10377            needsFlush = (sb.length() > 64 * 1024);
10378        }
10379
10380        // Flush immediately if the buffer's grown too large, or this
10381        // is a non-system app.  Non-system apps are isolated with a
10382        // different tag & policy and not batched.
10383        //
10384        // Batching is useful during internal testing with
10385        // StrictMode settings turned up high.  Without batching,
10386        // thousands of separate files could be created on boot.
10387        if (!isSystemApp || needsFlush) {
10388            new Thread("Error dump: " + dropboxTag) {
10389                @Override
10390                public void run() {
10391                    String report;
10392                    synchronized (sb) {
10393                        report = sb.toString();
10394                        sb.delete(0, sb.length());
10395                        sb.trimToSize();
10396                    }
10397                    if (report.length() != 0) {
10398                        dbox.addText(dropboxTag, report);
10399                    }
10400                }
10401            }.start();
10402            return;
10403        }
10404
10405        // System app batching:
10406        if (!bufferWasEmpty) {
10407            // An existing dropbox-writing thread is outstanding, so
10408            // we don't need to start it up.  The existing thread will
10409            // catch the buffer appends we just did.
10410            return;
10411        }
10412
10413        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10414        // (After this point, we shouldn't access AMS internal data structures.)
10415        new Thread("Error dump: " + dropboxTag) {
10416            @Override
10417            public void run() {
10418                // 5 second sleep to let stacks arrive and be batched together
10419                try {
10420                    Thread.sleep(5000);  // 5 seconds
10421                } catch (InterruptedException e) {}
10422
10423                String errorReport;
10424                synchronized (mStrictModeBuffer) {
10425                    errorReport = mStrictModeBuffer.toString();
10426                    if (errorReport.length() == 0) {
10427                        return;
10428                    }
10429                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10430                    mStrictModeBuffer.trimToSize();
10431                }
10432                dbox.addText(dropboxTag, errorReport);
10433            }
10434        }.start();
10435    }
10436
10437    /**
10438     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10439     * @param app object of the crashing app, null for the system server
10440     * @param tag reported by the caller
10441     * @param crashInfo describing the context of the error
10442     * @return true if the process should exit immediately (WTF is fatal)
10443     */
10444    public boolean handleApplicationWtf(IBinder app, String tag,
10445            ApplicationErrorReport.CrashInfo crashInfo) {
10446        ProcessRecord r = findAppProcess(app, "WTF");
10447        final String processName = app == null ? "system_server"
10448                : (r == null ? "unknown" : r.processName);
10449
10450        EventLog.writeEvent(EventLogTags.AM_WTF,
10451                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10452                processName,
10453                r == null ? -1 : r.info.flags,
10454                tag, crashInfo.exceptionMessage);
10455
10456        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10457
10458        if (r != null && r.pid != Process.myPid() &&
10459                Settings.Global.getInt(mContext.getContentResolver(),
10460                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10461            crashApplication(r, crashInfo);
10462            return true;
10463        } else {
10464            return false;
10465        }
10466    }
10467
10468    /**
10469     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10470     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10471     */
10472    private ProcessRecord findAppProcess(IBinder app, String reason) {
10473        if (app == null) {
10474            return null;
10475        }
10476
10477        synchronized (this) {
10478            final int NP = mProcessNames.getMap().size();
10479            for (int ip=0; ip<NP; ip++) {
10480                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10481                final int NA = apps.size();
10482                for (int ia=0; ia<NA; ia++) {
10483                    ProcessRecord p = apps.valueAt(ia);
10484                    if (p.thread != null && p.thread.asBinder() == app) {
10485                        return p;
10486                    }
10487                }
10488            }
10489
10490            Slog.w(TAG, "Can't find mystery application for " + reason
10491                    + " from pid=" + Binder.getCallingPid()
10492                    + " uid=" + Binder.getCallingUid() + ": " + app);
10493            return null;
10494        }
10495    }
10496
10497    /**
10498     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10499     * to append various headers to the dropbox log text.
10500     */
10501    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10502            StringBuilder sb) {
10503        // Watchdog thread ends up invoking this function (with
10504        // a null ProcessRecord) to add the stack file to dropbox.
10505        // Do not acquire a lock on this (am) in such cases, as it
10506        // could cause a potential deadlock, if and when watchdog
10507        // is invoked due to unavailability of lock on am and it
10508        // would prevent watchdog from killing system_server.
10509        if (process == null) {
10510            sb.append("Process: ").append(processName).append("\n");
10511            return;
10512        }
10513        // Note: ProcessRecord 'process' is guarded by the service
10514        // instance.  (notably process.pkgList, which could otherwise change
10515        // concurrently during execution of this method)
10516        synchronized (this) {
10517            sb.append("Process: ").append(processName).append("\n");
10518            int flags = process.info.flags;
10519            IPackageManager pm = AppGlobals.getPackageManager();
10520            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10521            for (int ip=0; ip<process.pkgList.size(); ip++) {
10522                String pkg = process.pkgList.keyAt(ip);
10523                sb.append("Package: ").append(pkg);
10524                try {
10525                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10526                    if (pi != null) {
10527                        sb.append(" v").append(pi.versionCode);
10528                        if (pi.versionName != null) {
10529                            sb.append(" (").append(pi.versionName).append(")");
10530                        }
10531                    }
10532                } catch (RemoteException e) {
10533                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10534                }
10535                sb.append("\n");
10536            }
10537        }
10538    }
10539
10540    private static String processClass(ProcessRecord process) {
10541        if (process == null || process.pid == MY_PID) {
10542            return "system_server";
10543        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10544            return "system_app";
10545        } else {
10546            return "data_app";
10547        }
10548    }
10549
10550    /**
10551     * Write a description of an error (crash, WTF, ANR) to the drop box.
10552     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10553     * @param process which caused the error, null means the system server
10554     * @param activity which triggered the error, null if unknown
10555     * @param parent activity related to the error, null if unknown
10556     * @param subject line related to the error, null if absent
10557     * @param report in long form describing the error, null if absent
10558     * @param logFile to include in the report, null if none
10559     * @param crashInfo giving an application stack trace, null if absent
10560     */
10561    public void addErrorToDropBox(String eventType,
10562            ProcessRecord process, String processName, ActivityRecord activity,
10563            ActivityRecord parent, String subject,
10564            final String report, final File logFile,
10565            final ApplicationErrorReport.CrashInfo crashInfo) {
10566        // NOTE -- this must never acquire the ActivityManagerService lock,
10567        // otherwise the watchdog may be prevented from resetting the system.
10568
10569        final String dropboxTag = processClass(process) + "_" + eventType;
10570        final DropBoxManager dbox = (DropBoxManager)
10571                mContext.getSystemService(Context.DROPBOX_SERVICE);
10572
10573        // Exit early if the dropbox isn't configured to accept this report type.
10574        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10575
10576        final StringBuilder sb = new StringBuilder(1024);
10577        appendDropBoxProcessHeaders(process, processName, sb);
10578        if (activity != null) {
10579            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10580        }
10581        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10582            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10583        }
10584        if (parent != null && parent != activity) {
10585            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10586        }
10587        if (subject != null) {
10588            sb.append("Subject: ").append(subject).append("\n");
10589        }
10590        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10591        if (Debug.isDebuggerConnected()) {
10592            sb.append("Debugger: Connected\n");
10593        }
10594        sb.append("\n");
10595
10596        // Do the rest in a worker thread to avoid blocking the caller on I/O
10597        // (After this point, we shouldn't access AMS internal data structures.)
10598        Thread worker = new Thread("Error dump: " + dropboxTag) {
10599            @Override
10600            public void run() {
10601                if (report != null) {
10602                    sb.append(report);
10603                }
10604                if (logFile != null) {
10605                    try {
10606                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10607                                    "\n\n[[TRUNCATED]]"));
10608                    } catch (IOException e) {
10609                        Slog.e(TAG, "Error reading " + logFile, e);
10610                    }
10611                }
10612                if (crashInfo != null && crashInfo.stackTrace != null) {
10613                    sb.append(crashInfo.stackTrace);
10614                }
10615
10616                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10617                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10618                if (lines > 0) {
10619                    sb.append("\n");
10620
10621                    // Merge several logcat streams, and take the last N lines
10622                    InputStreamReader input = null;
10623                    try {
10624                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10625                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10626                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10627
10628                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10629                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10630                        input = new InputStreamReader(logcat.getInputStream());
10631
10632                        int num;
10633                        char[] buf = new char[8192];
10634                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10635                    } catch (IOException e) {
10636                        Slog.e(TAG, "Error running logcat", e);
10637                    } finally {
10638                        if (input != null) try { input.close(); } catch (IOException e) {}
10639                    }
10640                }
10641
10642                dbox.addText(dropboxTag, sb.toString());
10643            }
10644        };
10645
10646        if (process == null) {
10647            // If process is null, we are being called from some internal code
10648            // and may be about to die -- run this synchronously.
10649            worker.run();
10650        } else {
10651            worker.start();
10652        }
10653    }
10654
10655    /**
10656     * Bring up the "unexpected error" dialog box for a crashing app.
10657     * Deal with edge cases (intercepts from instrumented applications,
10658     * ActivityController, error intent receivers, that sort of thing).
10659     * @param r the application crashing
10660     * @param crashInfo describing the failure
10661     */
10662    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10663        long timeMillis = System.currentTimeMillis();
10664        String shortMsg = crashInfo.exceptionClassName;
10665        String longMsg = crashInfo.exceptionMessage;
10666        String stackTrace = crashInfo.stackTrace;
10667        if (shortMsg != null && longMsg != null) {
10668            longMsg = shortMsg + ": " + longMsg;
10669        } else if (shortMsg != null) {
10670            longMsg = shortMsg;
10671        }
10672
10673        AppErrorResult result = new AppErrorResult();
10674        synchronized (this) {
10675            if (mController != null) {
10676                try {
10677                    String name = r != null ? r.processName : null;
10678                    int pid = r != null ? r.pid : Binder.getCallingPid();
10679                    if (!mController.appCrashed(name, pid,
10680                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10681                        Slog.w(TAG, "Force-killing crashed app " + name
10682                                + " at watcher's request");
10683                        Process.killProcess(pid);
10684                        return;
10685                    }
10686                } catch (RemoteException e) {
10687                    mController = null;
10688                    Watchdog.getInstance().setActivityController(null);
10689                }
10690            }
10691
10692            final long origId = Binder.clearCallingIdentity();
10693
10694            // If this process is running instrumentation, finish it.
10695            if (r != null && r.instrumentationClass != null) {
10696                Slog.w(TAG, "Error in app " + r.processName
10697                      + " running instrumentation " + r.instrumentationClass + ":");
10698                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10699                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10700                Bundle info = new Bundle();
10701                info.putString("shortMsg", shortMsg);
10702                info.putString("longMsg", longMsg);
10703                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10704                Binder.restoreCallingIdentity(origId);
10705                return;
10706            }
10707
10708            // If we can't identify the process or it's already exceeded its crash quota,
10709            // quit right away without showing a crash dialog.
10710            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10711                Binder.restoreCallingIdentity(origId);
10712                return;
10713            }
10714
10715            Message msg = Message.obtain();
10716            msg.what = SHOW_ERROR_MSG;
10717            HashMap data = new HashMap();
10718            data.put("result", result);
10719            data.put("app", r);
10720            msg.obj = data;
10721            mHandler.sendMessage(msg);
10722
10723            Binder.restoreCallingIdentity(origId);
10724        }
10725
10726        int res = result.get();
10727
10728        Intent appErrorIntent = null;
10729        synchronized (this) {
10730            if (r != null && !r.isolated) {
10731                // XXX Can't keep track of crash time for isolated processes,
10732                // since they don't have a persistent identity.
10733                mProcessCrashTimes.put(r.info.processName, r.uid,
10734                        SystemClock.uptimeMillis());
10735            }
10736            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10737                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10738            }
10739        }
10740
10741        if (appErrorIntent != null) {
10742            try {
10743                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10744            } catch (ActivityNotFoundException e) {
10745                Slog.w(TAG, "bug report receiver dissappeared", e);
10746            }
10747        }
10748    }
10749
10750    Intent createAppErrorIntentLocked(ProcessRecord r,
10751            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10752        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10753        if (report == null) {
10754            return null;
10755        }
10756        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10757        result.setComponent(r.errorReportReceiver);
10758        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10759        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10760        return result;
10761    }
10762
10763    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10764            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10765        if (r.errorReportReceiver == null) {
10766            return null;
10767        }
10768
10769        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10770            return null;
10771        }
10772
10773        ApplicationErrorReport report = new ApplicationErrorReport();
10774        report.packageName = r.info.packageName;
10775        report.installerPackageName = r.errorReportReceiver.getPackageName();
10776        report.processName = r.processName;
10777        report.time = timeMillis;
10778        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10779
10780        if (r.crashing || r.forceCrashReport) {
10781            report.type = ApplicationErrorReport.TYPE_CRASH;
10782            report.crashInfo = crashInfo;
10783        } else if (r.notResponding) {
10784            report.type = ApplicationErrorReport.TYPE_ANR;
10785            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10786
10787            report.anrInfo.activity = r.notRespondingReport.tag;
10788            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10789            report.anrInfo.info = r.notRespondingReport.longMsg;
10790        }
10791
10792        return report;
10793    }
10794
10795    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10796        enforceNotIsolatedCaller("getProcessesInErrorState");
10797        // assume our apps are happy - lazy create the list
10798        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10799
10800        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10801                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10802        int userId = UserHandle.getUserId(Binder.getCallingUid());
10803
10804        synchronized (this) {
10805
10806            // iterate across all processes
10807            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10808                ProcessRecord app = mLruProcesses.get(i);
10809                if (!allUsers && app.userId != userId) {
10810                    continue;
10811                }
10812                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10813                    // This one's in trouble, so we'll generate a report for it
10814                    // crashes are higher priority (in case there's a crash *and* an anr)
10815                    ActivityManager.ProcessErrorStateInfo report = null;
10816                    if (app.crashing) {
10817                        report = app.crashingReport;
10818                    } else if (app.notResponding) {
10819                        report = app.notRespondingReport;
10820                    }
10821
10822                    if (report != null) {
10823                        if (errList == null) {
10824                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10825                        }
10826                        errList.add(report);
10827                    } else {
10828                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10829                                " crashing = " + app.crashing +
10830                                " notResponding = " + app.notResponding);
10831                    }
10832                }
10833            }
10834        }
10835
10836        return errList;
10837    }
10838
10839    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10840        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10841            if (currApp != null) {
10842                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10843            }
10844            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10845        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10846            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10847        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10848            if (currApp != null) {
10849                currApp.lru = 0;
10850            }
10851            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10852        } else if (adj >= ProcessList.SERVICE_ADJ) {
10853            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10854        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10855            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10856        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10857            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10858        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10859            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10860        } else {
10861            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10862        }
10863    }
10864
10865    private void fillInProcMemInfo(ProcessRecord app,
10866            ActivityManager.RunningAppProcessInfo outInfo) {
10867        outInfo.pid = app.pid;
10868        outInfo.uid = app.info.uid;
10869        if (mHeavyWeightProcess == app) {
10870            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10871        }
10872        if (app.persistent) {
10873            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10874        }
10875        if (app.activities.size() > 0) {
10876            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10877        }
10878        outInfo.lastTrimLevel = app.trimMemoryLevel;
10879        int adj = app.curAdj;
10880        outInfo.importance = oomAdjToImportance(adj, outInfo);
10881        outInfo.importanceReasonCode = app.adjTypeCode;
10882        outInfo.processState = app.curProcState;
10883    }
10884
10885    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10886        enforceNotIsolatedCaller("getRunningAppProcesses");
10887        // Lazy instantiation of list
10888        List<ActivityManager.RunningAppProcessInfo> runList = null;
10889        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10890                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10891        int userId = UserHandle.getUserId(Binder.getCallingUid());
10892        synchronized (this) {
10893            // Iterate across all processes
10894            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10895                ProcessRecord app = mLruProcesses.get(i);
10896                if (!allUsers && app.userId != userId) {
10897                    continue;
10898                }
10899                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10900                    // Generate process state info for running application
10901                    ActivityManager.RunningAppProcessInfo currApp =
10902                        new ActivityManager.RunningAppProcessInfo(app.processName,
10903                                app.pid, app.getPackageList());
10904                    fillInProcMemInfo(app, currApp);
10905                    if (app.adjSource instanceof ProcessRecord) {
10906                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10907                        currApp.importanceReasonImportance = oomAdjToImportance(
10908                                app.adjSourceOom, null);
10909                    } else if (app.adjSource instanceof ActivityRecord) {
10910                        ActivityRecord r = (ActivityRecord)app.adjSource;
10911                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10912                    }
10913                    if (app.adjTarget instanceof ComponentName) {
10914                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10915                    }
10916                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10917                    //        + " lru=" + currApp.lru);
10918                    if (runList == null) {
10919                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10920                    }
10921                    runList.add(currApp);
10922                }
10923            }
10924        }
10925        return runList;
10926    }
10927
10928    public List<ApplicationInfo> getRunningExternalApplications() {
10929        enforceNotIsolatedCaller("getRunningExternalApplications");
10930        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10931        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10932        if (runningApps != null && runningApps.size() > 0) {
10933            Set<String> extList = new HashSet<String>();
10934            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10935                if (app.pkgList != null) {
10936                    for (String pkg : app.pkgList) {
10937                        extList.add(pkg);
10938                    }
10939                }
10940            }
10941            IPackageManager pm = AppGlobals.getPackageManager();
10942            for (String pkg : extList) {
10943                try {
10944                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10945                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10946                        retList.add(info);
10947                    }
10948                } catch (RemoteException e) {
10949                }
10950            }
10951        }
10952        return retList;
10953    }
10954
10955    @Override
10956    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10957        enforceNotIsolatedCaller("getMyMemoryState");
10958        synchronized (this) {
10959            ProcessRecord proc;
10960            synchronized (mPidsSelfLocked) {
10961                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10962            }
10963            fillInProcMemInfo(proc, outInfo);
10964        }
10965    }
10966
10967    @Override
10968    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10969        if (checkCallingPermission(android.Manifest.permission.DUMP)
10970                != PackageManager.PERMISSION_GRANTED) {
10971            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10972                    + Binder.getCallingPid()
10973                    + ", uid=" + Binder.getCallingUid()
10974                    + " without permission "
10975                    + android.Manifest.permission.DUMP);
10976            return;
10977        }
10978
10979        boolean dumpAll = false;
10980        boolean dumpClient = false;
10981        String dumpPackage = null;
10982
10983        int opti = 0;
10984        while (opti < args.length) {
10985            String opt = args[opti];
10986            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10987                break;
10988            }
10989            opti++;
10990            if ("-a".equals(opt)) {
10991                dumpAll = true;
10992            } else if ("-c".equals(opt)) {
10993                dumpClient = true;
10994            } else if ("-h".equals(opt)) {
10995                pw.println("Activity manager dump options:");
10996                pw.println("  [-a] [-c] [-h] [cmd] ...");
10997                pw.println("  cmd may be one of:");
10998                pw.println("    a[ctivities]: activity stack state");
10999                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11000                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11001                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11002                pw.println("    o[om]: out of memory management");
11003                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11004                pw.println("    provider [COMP_SPEC]: provider client-side state");
11005                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11006                pw.println("    service [COMP_SPEC]: service client-side state");
11007                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11008                pw.println("    all: dump all activities");
11009                pw.println("    top: dump the top activity");
11010                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11011                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11012                pw.println("    a partial substring in a component name, a");
11013                pw.println("    hex object identifier.");
11014                pw.println("  -a: include all available server state.");
11015                pw.println("  -c: include client state.");
11016                return;
11017            } else {
11018                pw.println("Unknown argument: " + opt + "; use -h for help");
11019            }
11020        }
11021
11022        long origId = Binder.clearCallingIdentity();
11023        boolean more = false;
11024        // Is the caller requesting to dump a particular piece of data?
11025        if (opti < args.length) {
11026            String cmd = args[opti];
11027            opti++;
11028            if ("activities".equals(cmd) || "a".equals(cmd)) {
11029                synchronized (this) {
11030                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11031                }
11032            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11033                String[] newArgs;
11034                String name;
11035                if (opti >= args.length) {
11036                    name = null;
11037                    newArgs = EMPTY_STRING_ARRAY;
11038                } else {
11039                    name = args[opti];
11040                    opti++;
11041                    newArgs = new String[args.length - opti];
11042                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11043                            args.length - opti);
11044                }
11045                synchronized (this) {
11046                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11047                }
11048            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11049                String[] newArgs;
11050                String name;
11051                if (opti >= args.length) {
11052                    name = null;
11053                    newArgs = EMPTY_STRING_ARRAY;
11054                } else {
11055                    name = args[opti];
11056                    opti++;
11057                    newArgs = new String[args.length - opti];
11058                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11059                            args.length - opti);
11060                }
11061                synchronized (this) {
11062                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11063                }
11064            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11065                String[] newArgs;
11066                String name;
11067                if (opti >= args.length) {
11068                    name = null;
11069                    newArgs = EMPTY_STRING_ARRAY;
11070                } else {
11071                    name = args[opti];
11072                    opti++;
11073                    newArgs = new String[args.length - opti];
11074                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11075                            args.length - opti);
11076                }
11077                synchronized (this) {
11078                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11079                }
11080            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11081                synchronized (this) {
11082                    dumpOomLocked(fd, pw, args, opti, true);
11083                }
11084            } else if ("provider".equals(cmd)) {
11085                String[] newArgs;
11086                String name;
11087                if (opti >= args.length) {
11088                    name = null;
11089                    newArgs = EMPTY_STRING_ARRAY;
11090                } else {
11091                    name = args[opti];
11092                    opti++;
11093                    newArgs = new String[args.length - opti];
11094                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11095                }
11096                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11097                    pw.println("No providers match: " + name);
11098                    pw.println("Use -h for help.");
11099                }
11100            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11101                synchronized (this) {
11102                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11103                }
11104            } else if ("service".equals(cmd)) {
11105                String[] newArgs;
11106                String name;
11107                if (opti >= args.length) {
11108                    name = null;
11109                    newArgs = EMPTY_STRING_ARRAY;
11110                } else {
11111                    name = args[opti];
11112                    opti++;
11113                    newArgs = new String[args.length - opti];
11114                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11115                            args.length - opti);
11116                }
11117                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11118                    pw.println("No services match: " + name);
11119                    pw.println("Use -h for help.");
11120                }
11121            } else if ("package".equals(cmd)) {
11122                String[] newArgs;
11123                if (opti >= args.length) {
11124                    pw.println("package: no package name specified");
11125                    pw.println("Use -h for help.");
11126                } else {
11127                    dumpPackage = args[opti];
11128                    opti++;
11129                    newArgs = new String[args.length - opti];
11130                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11131                            args.length - opti);
11132                    args = newArgs;
11133                    opti = 0;
11134                    more = true;
11135                }
11136            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11137                synchronized (this) {
11138                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11139                }
11140            } else {
11141                // Dumping a single activity?
11142                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11143                    pw.println("Bad activity command, or no activities match: " + cmd);
11144                    pw.println("Use -h for help.");
11145                }
11146            }
11147            if (!more) {
11148                Binder.restoreCallingIdentity(origId);
11149                return;
11150            }
11151        }
11152
11153        // No piece of data specified, dump everything.
11154        synchronized (this) {
11155            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11156            pw.println();
11157            if (dumpAll) {
11158                pw.println("-------------------------------------------------------------------------------");
11159            }
11160            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11161            pw.println();
11162            if (dumpAll) {
11163                pw.println("-------------------------------------------------------------------------------");
11164            }
11165            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11166            pw.println();
11167            if (dumpAll) {
11168                pw.println("-------------------------------------------------------------------------------");
11169            }
11170            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11171            pw.println();
11172            if (dumpAll) {
11173                pw.println("-------------------------------------------------------------------------------");
11174            }
11175            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11176            pw.println();
11177            if (dumpAll) {
11178                pw.println("-------------------------------------------------------------------------------");
11179            }
11180            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11181        }
11182        Binder.restoreCallingIdentity(origId);
11183    }
11184
11185    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11186            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11187        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11188
11189        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11190                dumpPackage);
11191        boolean needSep = printedAnything;
11192
11193        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11194                dumpPackage, needSep, "  mFocusedActivity: ");
11195        if (printed) {
11196            printedAnything = true;
11197            needSep = false;
11198        }
11199
11200        if (dumpPackage == null) {
11201            if (needSep) {
11202                pw.println();
11203            }
11204            needSep = true;
11205            printedAnything = true;
11206            mStackSupervisor.dump(pw, "  ");
11207        }
11208
11209        if (mRecentTasks.size() > 0) {
11210            boolean printedHeader = false;
11211
11212            final int N = mRecentTasks.size();
11213            for (int i=0; i<N; i++) {
11214                TaskRecord tr = mRecentTasks.get(i);
11215                if (dumpPackage != null) {
11216                    if (tr.realActivity == null ||
11217                            !dumpPackage.equals(tr.realActivity)) {
11218                        continue;
11219                    }
11220                }
11221                if (!printedHeader) {
11222                    if (needSep) {
11223                        pw.println();
11224                    }
11225                    pw.println("  Recent tasks:");
11226                    printedHeader = true;
11227                    printedAnything = true;
11228                }
11229                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11230                        pw.println(tr);
11231                if (dumpAll) {
11232                    mRecentTasks.get(i).dump(pw, "    ");
11233                }
11234            }
11235        }
11236
11237        if (!printedAnything) {
11238            pw.println("  (nothing)");
11239        }
11240    }
11241
11242    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11243            int opti, boolean dumpAll, String dumpPackage) {
11244        boolean needSep = false;
11245        boolean printedAnything = false;
11246        int numPers = 0;
11247
11248        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11249
11250        if (dumpAll) {
11251            final int NP = mProcessNames.getMap().size();
11252            for (int ip=0; ip<NP; ip++) {
11253                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11254                final int NA = procs.size();
11255                for (int ia=0; ia<NA; ia++) {
11256                    ProcessRecord r = procs.valueAt(ia);
11257                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11258                        continue;
11259                    }
11260                    if (!needSep) {
11261                        pw.println("  All known processes:");
11262                        needSep = true;
11263                        printedAnything = true;
11264                    }
11265                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11266                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11267                        pw.print(" "); pw.println(r);
11268                    r.dump(pw, "    ");
11269                    if (r.persistent) {
11270                        numPers++;
11271                    }
11272                }
11273            }
11274        }
11275
11276        if (mIsolatedProcesses.size() > 0) {
11277            boolean printed = false;
11278            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11279                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11280                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11281                    continue;
11282                }
11283                if (!printed) {
11284                    if (needSep) {
11285                        pw.println();
11286                    }
11287                    pw.println("  Isolated process list (sorted by uid):");
11288                    printedAnything = true;
11289                    printed = true;
11290                    needSep = true;
11291                }
11292                pw.println(String.format("%sIsolated #%2d: %s",
11293                        "    ", i, r.toString()));
11294            }
11295        }
11296
11297        if (mLruProcesses.size() > 0) {
11298            if (needSep) {
11299                pw.println();
11300            }
11301            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11302                    pw.print(" total, non-act at ");
11303                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11304                    pw.print(", non-svc at ");
11305                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11306                    pw.println("):");
11307            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11308            needSep = true;
11309            printedAnything = true;
11310        }
11311
11312        if (dumpAll || dumpPackage != null) {
11313            synchronized (mPidsSelfLocked) {
11314                boolean printed = false;
11315                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11316                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11317                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11318                        continue;
11319                    }
11320                    if (!printed) {
11321                        if (needSep) pw.println();
11322                        needSep = true;
11323                        pw.println("  PID mappings:");
11324                        printed = true;
11325                        printedAnything = true;
11326                    }
11327                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11328                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11329                }
11330            }
11331        }
11332
11333        if (mForegroundProcesses.size() > 0) {
11334            synchronized (mPidsSelfLocked) {
11335                boolean printed = false;
11336                for (int i=0; i<mForegroundProcesses.size(); i++) {
11337                    ProcessRecord r = mPidsSelfLocked.get(
11338                            mForegroundProcesses.valueAt(i).pid);
11339                    if (dumpPackage != null && (r == null
11340                            || !r.pkgList.containsKey(dumpPackage))) {
11341                        continue;
11342                    }
11343                    if (!printed) {
11344                        if (needSep) pw.println();
11345                        needSep = true;
11346                        pw.println("  Foreground Processes:");
11347                        printed = true;
11348                        printedAnything = true;
11349                    }
11350                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11351                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11352                }
11353            }
11354        }
11355
11356        if (mPersistentStartingProcesses.size() > 0) {
11357            if (needSep) pw.println();
11358            needSep = true;
11359            printedAnything = true;
11360            pw.println("  Persisent processes that are starting:");
11361            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11362                    "Starting Norm", "Restarting PERS", dumpPackage);
11363        }
11364
11365        if (mRemovedProcesses.size() > 0) {
11366            if (needSep) pw.println();
11367            needSep = true;
11368            printedAnything = true;
11369            pw.println("  Processes that are being removed:");
11370            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11371                    "Removed Norm", "Removed PERS", dumpPackage);
11372        }
11373
11374        if (mProcessesOnHold.size() > 0) {
11375            if (needSep) pw.println();
11376            needSep = true;
11377            printedAnything = true;
11378            pw.println("  Processes that are on old until the system is ready:");
11379            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11380                    "OnHold Norm", "OnHold PERS", dumpPackage);
11381        }
11382
11383        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11384
11385        if (mProcessCrashTimes.getMap().size() > 0) {
11386            boolean printed = false;
11387            long now = SystemClock.uptimeMillis();
11388            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11389            final int NP = pmap.size();
11390            for (int ip=0; ip<NP; ip++) {
11391                String pname = pmap.keyAt(ip);
11392                SparseArray<Long> uids = pmap.valueAt(ip);
11393                final int N = uids.size();
11394                for (int i=0; i<N; i++) {
11395                    int puid = uids.keyAt(i);
11396                    ProcessRecord r = mProcessNames.get(pname, puid);
11397                    if (dumpPackage != null && (r == null
11398                            || !r.pkgList.containsKey(dumpPackage))) {
11399                        continue;
11400                    }
11401                    if (!printed) {
11402                        if (needSep) pw.println();
11403                        needSep = true;
11404                        pw.println("  Time since processes crashed:");
11405                        printed = true;
11406                        printedAnything = true;
11407                    }
11408                    pw.print("    Process "); pw.print(pname);
11409                            pw.print(" uid "); pw.print(puid);
11410                            pw.print(": last crashed ");
11411                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11412                            pw.println(" ago");
11413                }
11414            }
11415        }
11416
11417        if (mBadProcesses.getMap().size() > 0) {
11418            boolean printed = false;
11419            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11420            final int NP = pmap.size();
11421            for (int ip=0; ip<NP; ip++) {
11422                String pname = pmap.keyAt(ip);
11423                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11424                final int N = uids.size();
11425                for (int i=0; i<N; i++) {
11426                    int puid = uids.keyAt(i);
11427                    ProcessRecord r = mProcessNames.get(pname, puid);
11428                    if (dumpPackage != null && (r == null
11429                            || !r.pkgList.containsKey(dumpPackage))) {
11430                        continue;
11431                    }
11432                    if (!printed) {
11433                        if (needSep) pw.println();
11434                        needSep = true;
11435                        pw.println("  Bad processes:");
11436                        printedAnything = true;
11437                    }
11438                    BadProcessInfo info = uids.valueAt(i);
11439                    pw.print("    Bad process "); pw.print(pname);
11440                            pw.print(" uid "); pw.print(puid);
11441                            pw.print(": crashed at time "); pw.println(info.time);
11442                    if (info.shortMsg != null) {
11443                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11444                    }
11445                    if (info.longMsg != null) {
11446                        pw.print("      Long msg: "); pw.println(info.longMsg);
11447                    }
11448                    if (info.stack != null) {
11449                        pw.println("      Stack:");
11450                        int lastPos = 0;
11451                        for (int pos=0; pos<info.stack.length(); pos++) {
11452                            if (info.stack.charAt(pos) == '\n') {
11453                                pw.print("        ");
11454                                pw.write(info.stack, lastPos, pos-lastPos);
11455                                pw.println();
11456                                lastPos = pos+1;
11457                            }
11458                        }
11459                        if (lastPos < info.stack.length()) {
11460                            pw.print("        ");
11461                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11462                            pw.println();
11463                        }
11464                    }
11465                }
11466            }
11467        }
11468
11469        if (dumpPackage == null) {
11470            pw.println();
11471            needSep = false;
11472            pw.println("  mStartedUsers:");
11473            for (int i=0; i<mStartedUsers.size(); i++) {
11474                UserStartedState uss = mStartedUsers.valueAt(i);
11475                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11476                        pw.print(": "); uss.dump("", pw);
11477            }
11478            pw.print("  mStartedUserArray: [");
11479            for (int i=0; i<mStartedUserArray.length; i++) {
11480                if (i > 0) pw.print(", ");
11481                pw.print(mStartedUserArray[i]);
11482            }
11483            pw.println("]");
11484            pw.print("  mUserLru: [");
11485            for (int i=0; i<mUserLru.size(); i++) {
11486                if (i > 0) pw.print(", ");
11487                pw.print(mUserLru.get(i));
11488            }
11489            pw.println("]");
11490            if (dumpAll) {
11491                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11492            }
11493        }
11494        if (mHomeProcess != null && (dumpPackage == null
11495                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11496            if (needSep) {
11497                pw.println();
11498                needSep = false;
11499            }
11500            pw.println("  mHomeProcess: " + mHomeProcess);
11501        }
11502        if (mPreviousProcess != null && (dumpPackage == null
11503                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11504            if (needSep) {
11505                pw.println();
11506                needSep = false;
11507            }
11508            pw.println("  mPreviousProcess: " + mPreviousProcess);
11509        }
11510        if (dumpAll) {
11511            StringBuilder sb = new StringBuilder(128);
11512            sb.append("  mPreviousProcessVisibleTime: ");
11513            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11514            pw.println(sb);
11515        }
11516        if (mHeavyWeightProcess != null && (dumpPackage == null
11517                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11518            if (needSep) {
11519                pw.println();
11520                needSep = false;
11521            }
11522            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11523        }
11524        if (dumpPackage == null) {
11525            pw.println("  mConfiguration: " + mConfiguration);
11526        }
11527        if (dumpAll) {
11528            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11529            if (mCompatModePackages.getPackages().size() > 0) {
11530                boolean printed = false;
11531                for (Map.Entry<String, Integer> entry
11532                        : mCompatModePackages.getPackages().entrySet()) {
11533                    String pkg = entry.getKey();
11534                    int mode = entry.getValue();
11535                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11536                        continue;
11537                    }
11538                    if (!printed) {
11539                        pw.println("  mScreenCompatPackages:");
11540                        printed = true;
11541                    }
11542                    pw.print("    "); pw.print(pkg); pw.print(": ");
11543                            pw.print(mode); pw.println();
11544                }
11545            }
11546        }
11547        if (dumpPackage == null) {
11548            if (mSleeping || mWentToSleep || mLockScreenShown) {
11549                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11550                        + " mLockScreenShown " + mLockScreenShown);
11551            }
11552            if (mShuttingDown || mRunningVoice) {
11553                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11554            }
11555        }
11556        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11557                || mOrigWaitForDebugger) {
11558            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11559                    || dumpPackage.equals(mOrigDebugApp)) {
11560                if (needSep) {
11561                    pw.println();
11562                    needSep = false;
11563                }
11564                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11565                        + " mDebugTransient=" + mDebugTransient
11566                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11567            }
11568        }
11569        if (mOpenGlTraceApp != null) {
11570            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11571                if (needSep) {
11572                    pw.println();
11573                    needSep = false;
11574                }
11575                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11576            }
11577        }
11578        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11579                || mProfileFd != null) {
11580            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11581                if (needSep) {
11582                    pw.println();
11583                    needSep = false;
11584                }
11585                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11586                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11587                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11588                        + mAutoStopProfiler);
11589            }
11590        }
11591        if (dumpPackage == null) {
11592            if (mAlwaysFinishActivities || mController != null) {
11593                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11594                        + " mController=" + mController);
11595            }
11596            if (dumpAll) {
11597                pw.println("  Total persistent processes: " + numPers);
11598                pw.println("  mProcessesReady=" + mProcessesReady
11599                        + " mSystemReady=" + mSystemReady);
11600                pw.println("  mBooting=" + mBooting
11601                        + " mBooted=" + mBooted
11602                        + " mFactoryTest=" + mFactoryTest);
11603                pw.print("  mLastPowerCheckRealtime=");
11604                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11605                        pw.println("");
11606                pw.print("  mLastPowerCheckUptime=");
11607                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11608                        pw.println("");
11609                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11610                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11611                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11612                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11613                        + " (" + mLruProcesses.size() + " total)"
11614                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11615                        + " mNumServiceProcs=" + mNumServiceProcs
11616                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11617                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11618                        + " mLastMemoryLevel" + mLastMemoryLevel
11619                        + " mLastNumProcesses" + mLastNumProcesses);
11620                long now = SystemClock.uptimeMillis();
11621                pw.print("  mLastIdleTime=");
11622                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11623                        pw.print(" mLowRamSinceLastIdle=");
11624                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11625                        pw.println();
11626            }
11627        }
11628
11629        if (!printedAnything) {
11630            pw.println("  (nothing)");
11631        }
11632    }
11633
11634    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11635            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11636        if (mProcessesToGc.size() > 0) {
11637            boolean printed = false;
11638            long now = SystemClock.uptimeMillis();
11639            for (int i=0; i<mProcessesToGc.size(); i++) {
11640                ProcessRecord proc = mProcessesToGc.get(i);
11641                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11642                    continue;
11643                }
11644                if (!printed) {
11645                    if (needSep) pw.println();
11646                    needSep = true;
11647                    pw.println("  Processes that are waiting to GC:");
11648                    printed = true;
11649                }
11650                pw.print("    Process "); pw.println(proc);
11651                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11652                        pw.print(", last gced=");
11653                        pw.print(now-proc.lastRequestedGc);
11654                        pw.print(" ms ago, last lowMem=");
11655                        pw.print(now-proc.lastLowMemory);
11656                        pw.println(" ms ago");
11657
11658            }
11659        }
11660        return needSep;
11661    }
11662
11663    void printOomLevel(PrintWriter pw, String name, int adj) {
11664        pw.print("    ");
11665        if (adj >= 0) {
11666            pw.print(' ');
11667            if (adj < 10) pw.print(' ');
11668        } else {
11669            if (adj > -10) pw.print(' ');
11670        }
11671        pw.print(adj);
11672        pw.print(": ");
11673        pw.print(name);
11674        pw.print(" (");
11675        pw.print(mProcessList.getMemLevel(adj)/1024);
11676        pw.println(" kB)");
11677    }
11678
11679    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11680            int opti, boolean dumpAll) {
11681        boolean needSep = false;
11682
11683        if (mLruProcesses.size() > 0) {
11684            if (needSep) pw.println();
11685            needSep = true;
11686            pw.println("  OOM levels:");
11687            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11688            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11689            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11690            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11691            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11692            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11693            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11694            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11695            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11696            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11697            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11698            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11699            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11700
11701            if (needSep) pw.println();
11702            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11703                    pw.print(" total, non-act at ");
11704                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11705                    pw.print(", non-svc at ");
11706                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11707                    pw.println("):");
11708            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11709            needSep = true;
11710        }
11711
11712        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11713
11714        pw.println();
11715        pw.println("  mHomeProcess: " + mHomeProcess);
11716        pw.println("  mPreviousProcess: " + mPreviousProcess);
11717        if (mHeavyWeightProcess != null) {
11718            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11719        }
11720
11721        return true;
11722    }
11723
11724    /**
11725     * There are three ways to call this:
11726     *  - no provider specified: dump all the providers
11727     *  - a flattened component name that matched an existing provider was specified as the
11728     *    first arg: dump that one provider
11729     *  - the first arg isn't the flattened component name of an existing provider:
11730     *    dump all providers whose component contains the first arg as a substring
11731     */
11732    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11733            int opti, boolean dumpAll) {
11734        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11735    }
11736
11737    static class ItemMatcher {
11738        ArrayList<ComponentName> components;
11739        ArrayList<String> strings;
11740        ArrayList<Integer> objects;
11741        boolean all;
11742
11743        ItemMatcher() {
11744            all = true;
11745        }
11746
11747        void build(String name) {
11748            ComponentName componentName = ComponentName.unflattenFromString(name);
11749            if (componentName != null) {
11750                if (components == null) {
11751                    components = new ArrayList<ComponentName>();
11752                }
11753                components.add(componentName);
11754                all = false;
11755            } else {
11756                int objectId = 0;
11757                // Not a '/' separated full component name; maybe an object ID?
11758                try {
11759                    objectId = Integer.parseInt(name, 16);
11760                    if (objects == null) {
11761                        objects = new ArrayList<Integer>();
11762                    }
11763                    objects.add(objectId);
11764                    all = false;
11765                } catch (RuntimeException e) {
11766                    // Not an integer; just do string match.
11767                    if (strings == null) {
11768                        strings = new ArrayList<String>();
11769                    }
11770                    strings.add(name);
11771                    all = false;
11772                }
11773            }
11774        }
11775
11776        int build(String[] args, int opti) {
11777            for (; opti<args.length; opti++) {
11778                String name = args[opti];
11779                if ("--".equals(name)) {
11780                    return opti+1;
11781                }
11782                build(name);
11783            }
11784            return opti;
11785        }
11786
11787        boolean match(Object object, ComponentName comp) {
11788            if (all) {
11789                return true;
11790            }
11791            if (components != null) {
11792                for (int i=0; i<components.size(); i++) {
11793                    if (components.get(i).equals(comp)) {
11794                        return true;
11795                    }
11796                }
11797            }
11798            if (objects != null) {
11799                for (int i=0; i<objects.size(); i++) {
11800                    if (System.identityHashCode(object) == objects.get(i)) {
11801                        return true;
11802                    }
11803                }
11804            }
11805            if (strings != null) {
11806                String flat = comp.flattenToString();
11807                for (int i=0; i<strings.size(); i++) {
11808                    if (flat.contains(strings.get(i))) {
11809                        return true;
11810                    }
11811                }
11812            }
11813            return false;
11814        }
11815    }
11816
11817    /**
11818     * There are three things that cmd can be:
11819     *  - a flattened component name that matches an existing activity
11820     *  - the cmd arg isn't the flattened component name of an existing activity:
11821     *    dump all activity whose component contains the cmd as a substring
11822     *  - A hex number of the ActivityRecord object instance.
11823     */
11824    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11825            int opti, boolean dumpAll) {
11826        ArrayList<ActivityRecord> activities;
11827
11828        synchronized (this) {
11829            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11830        }
11831
11832        if (activities.size() <= 0) {
11833            return false;
11834        }
11835
11836        String[] newArgs = new String[args.length - opti];
11837        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11838
11839        TaskRecord lastTask = null;
11840        boolean needSep = false;
11841        for (int i=activities.size()-1; i>=0; i--) {
11842            ActivityRecord r = activities.get(i);
11843            if (needSep) {
11844                pw.println();
11845            }
11846            needSep = true;
11847            synchronized (this) {
11848                if (lastTask != r.task) {
11849                    lastTask = r.task;
11850                    pw.print("TASK "); pw.print(lastTask.affinity);
11851                            pw.print(" id="); pw.println(lastTask.taskId);
11852                    if (dumpAll) {
11853                        lastTask.dump(pw, "  ");
11854                    }
11855                }
11856            }
11857            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11858        }
11859        return true;
11860    }
11861
11862    /**
11863     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11864     * there is a thread associated with the activity.
11865     */
11866    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11867            final ActivityRecord r, String[] args, boolean dumpAll) {
11868        String innerPrefix = prefix + "  ";
11869        synchronized (this) {
11870            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11871                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11872                    pw.print(" pid=");
11873                    if (r.app != null) pw.println(r.app.pid);
11874                    else pw.println("(not running)");
11875            if (dumpAll) {
11876                r.dump(pw, innerPrefix);
11877            }
11878        }
11879        if (r.app != null && r.app.thread != null) {
11880            // flush anything that is already in the PrintWriter since the thread is going
11881            // to write to the file descriptor directly
11882            pw.flush();
11883            try {
11884                TransferPipe tp = new TransferPipe();
11885                try {
11886                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11887                            r.appToken, innerPrefix, args);
11888                    tp.go(fd);
11889                } finally {
11890                    tp.kill();
11891                }
11892            } catch (IOException e) {
11893                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11894            } catch (RemoteException e) {
11895                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11896            }
11897        }
11898    }
11899
11900    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11901            int opti, boolean dumpAll, String dumpPackage) {
11902        boolean needSep = false;
11903        boolean onlyHistory = false;
11904        boolean printedAnything = false;
11905
11906        if ("history".equals(dumpPackage)) {
11907            if (opti < args.length && "-s".equals(args[opti])) {
11908                dumpAll = false;
11909            }
11910            onlyHistory = true;
11911            dumpPackage = null;
11912        }
11913
11914        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11915        if (!onlyHistory && dumpAll) {
11916            if (mRegisteredReceivers.size() > 0) {
11917                boolean printed = false;
11918                Iterator it = mRegisteredReceivers.values().iterator();
11919                while (it.hasNext()) {
11920                    ReceiverList r = (ReceiverList)it.next();
11921                    if (dumpPackage != null && (r.app == null ||
11922                            !dumpPackage.equals(r.app.info.packageName))) {
11923                        continue;
11924                    }
11925                    if (!printed) {
11926                        pw.println("  Registered Receivers:");
11927                        needSep = true;
11928                        printed = true;
11929                        printedAnything = true;
11930                    }
11931                    pw.print("  * "); pw.println(r);
11932                    r.dump(pw, "    ");
11933                }
11934            }
11935
11936            if (mReceiverResolver.dump(pw, needSep ?
11937                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11938                    "    ", dumpPackage, false)) {
11939                needSep = true;
11940                printedAnything = true;
11941            }
11942        }
11943
11944        for (BroadcastQueue q : mBroadcastQueues) {
11945            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11946            printedAnything |= needSep;
11947        }
11948
11949        needSep = true;
11950
11951        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11952            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11953                if (needSep) {
11954                    pw.println();
11955                }
11956                needSep = true;
11957                printedAnything = true;
11958                pw.print("  Sticky broadcasts for user ");
11959                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11960                StringBuilder sb = new StringBuilder(128);
11961                for (Map.Entry<String, ArrayList<Intent>> ent
11962                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11963                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11964                    if (dumpAll) {
11965                        pw.println(":");
11966                        ArrayList<Intent> intents = ent.getValue();
11967                        final int N = intents.size();
11968                        for (int i=0; i<N; i++) {
11969                            sb.setLength(0);
11970                            sb.append("    Intent: ");
11971                            intents.get(i).toShortString(sb, false, true, false, false);
11972                            pw.println(sb.toString());
11973                            Bundle bundle = intents.get(i).getExtras();
11974                            if (bundle != null) {
11975                                pw.print("      ");
11976                                pw.println(bundle.toString());
11977                            }
11978                        }
11979                    } else {
11980                        pw.println("");
11981                    }
11982                }
11983            }
11984        }
11985
11986        if (!onlyHistory && dumpAll) {
11987            pw.println();
11988            for (BroadcastQueue queue : mBroadcastQueues) {
11989                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11990                        + queue.mBroadcastsScheduled);
11991            }
11992            pw.println("  mHandler:");
11993            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11994            needSep = true;
11995            printedAnything = true;
11996        }
11997
11998        if (!printedAnything) {
11999            pw.println("  (nothing)");
12000        }
12001    }
12002
12003    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12004            int opti, boolean dumpAll, String dumpPackage) {
12005        boolean needSep;
12006        boolean printedAnything = false;
12007
12008        ItemMatcher matcher = new ItemMatcher();
12009        matcher.build(args, opti);
12010
12011        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12012
12013        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12014        printedAnything |= needSep;
12015
12016        if (mLaunchingProviders.size() > 0) {
12017            boolean printed = false;
12018            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12019                ContentProviderRecord r = mLaunchingProviders.get(i);
12020                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12021                    continue;
12022                }
12023                if (!printed) {
12024                    if (needSep) pw.println();
12025                    needSep = true;
12026                    pw.println("  Launching content providers:");
12027                    printed = true;
12028                    printedAnything = true;
12029                }
12030                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12031                        pw.println(r);
12032            }
12033        }
12034
12035        if (mGrantedUriPermissions.size() > 0) {
12036            boolean printed = false;
12037            int dumpUid = -2;
12038            if (dumpPackage != null) {
12039                try {
12040                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12041                } catch (NameNotFoundException e) {
12042                    dumpUid = -1;
12043                }
12044            }
12045            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12046                int uid = mGrantedUriPermissions.keyAt(i);
12047                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12048                    continue;
12049                }
12050                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12051                if (!printed) {
12052                    if (needSep) pw.println();
12053                    needSep = true;
12054                    pw.println("  Granted Uri Permissions:");
12055                    printed = true;
12056                    printedAnything = true;
12057                }
12058                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12059                for (UriPermission perm : perms.values()) {
12060                    pw.print("    "); pw.println(perm);
12061                    if (dumpAll) {
12062                        perm.dump(pw, "      ");
12063                    }
12064                }
12065            }
12066        }
12067
12068        if (!printedAnything) {
12069            pw.println("  (nothing)");
12070        }
12071    }
12072
12073    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12074            int opti, boolean dumpAll, String dumpPackage) {
12075        boolean printed = false;
12076
12077        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12078
12079        if (mIntentSenderRecords.size() > 0) {
12080            Iterator<WeakReference<PendingIntentRecord>> it
12081                    = mIntentSenderRecords.values().iterator();
12082            while (it.hasNext()) {
12083                WeakReference<PendingIntentRecord> ref = it.next();
12084                PendingIntentRecord rec = ref != null ? ref.get(): null;
12085                if (dumpPackage != null && (rec == null
12086                        || !dumpPackage.equals(rec.key.packageName))) {
12087                    continue;
12088                }
12089                printed = true;
12090                if (rec != null) {
12091                    pw.print("  * "); pw.println(rec);
12092                    if (dumpAll) {
12093                        rec.dump(pw, "    ");
12094                    }
12095                } else {
12096                    pw.print("  * "); pw.println(ref);
12097                }
12098            }
12099        }
12100
12101        if (!printed) {
12102            pw.println("  (nothing)");
12103        }
12104    }
12105
12106    private static final int dumpProcessList(PrintWriter pw,
12107            ActivityManagerService service, List list,
12108            String prefix, String normalLabel, String persistentLabel,
12109            String dumpPackage) {
12110        int numPers = 0;
12111        final int N = list.size()-1;
12112        for (int i=N; i>=0; i--) {
12113            ProcessRecord r = (ProcessRecord)list.get(i);
12114            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12115                continue;
12116            }
12117            pw.println(String.format("%s%s #%2d: %s",
12118                    prefix, (r.persistent ? persistentLabel : normalLabel),
12119                    i, r.toString()));
12120            if (r.persistent) {
12121                numPers++;
12122            }
12123        }
12124        return numPers;
12125    }
12126
12127    private static final boolean dumpProcessOomList(PrintWriter pw,
12128            ActivityManagerService service, List<ProcessRecord> origList,
12129            String prefix, String normalLabel, String persistentLabel,
12130            boolean inclDetails, String dumpPackage) {
12131
12132        ArrayList<Pair<ProcessRecord, Integer>> list
12133                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12134        for (int i=0; i<origList.size(); i++) {
12135            ProcessRecord r = origList.get(i);
12136            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12137                continue;
12138            }
12139            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12140        }
12141
12142        if (list.size() <= 0) {
12143            return false;
12144        }
12145
12146        Comparator<Pair<ProcessRecord, Integer>> comparator
12147                = new Comparator<Pair<ProcessRecord, Integer>>() {
12148            @Override
12149            public int compare(Pair<ProcessRecord, Integer> object1,
12150                    Pair<ProcessRecord, Integer> object2) {
12151                if (object1.first.setAdj != object2.first.setAdj) {
12152                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12153                }
12154                if (object1.second.intValue() != object2.second.intValue()) {
12155                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12156                }
12157                return 0;
12158            }
12159        };
12160
12161        Collections.sort(list, comparator);
12162
12163        final long curRealtime = SystemClock.elapsedRealtime();
12164        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12165        final long curUptime = SystemClock.uptimeMillis();
12166        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12167
12168        for (int i=list.size()-1; i>=0; i--) {
12169            ProcessRecord r = list.get(i).first;
12170            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12171            char schedGroup;
12172            switch (r.setSchedGroup) {
12173                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12174                    schedGroup = 'B';
12175                    break;
12176                case Process.THREAD_GROUP_DEFAULT:
12177                    schedGroup = 'F';
12178                    break;
12179                default:
12180                    schedGroup = '?';
12181                    break;
12182            }
12183            char foreground;
12184            if (r.foregroundActivities) {
12185                foreground = 'A';
12186            } else if (r.foregroundServices) {
12187                foreground = 'S';
12188            } else {
12189                foreground = ' ';
12190            }
12191            String procState = ProcessList.makeProcStateString(r.curProcState);
12192            pw.print(prefix);
12193            pw.print(r.persistent ? persistentLabel : normalLabel);
12194            pw.print(" #");
12195            int num = (origList.size()-1)-list.get(i).second;
12196            if (num < 10) pw.print(' ');
12197            pw.print(num);
12198            pw.print(": ");
12199            pw.print(oomAdj);
12200            pw.print(' ');
12201            pw.print(schedGroup);
12202            pw.print('/');
12203            pw.print(foreground);
12204            pw.print('/');
12205            pw.print(procState);
12206            pw.print(" trm:");
12207            if (r.trimMemoryLevel < 10) pw.print(' ');
12208            pw.print(r.trimMemoryLevel);
12209            pw.print(' ');
12210            pw.print(r.toShortString());
12211            pw.print(" (");
12212            pw.print(r.adjType);
12213            pw.println(')');
12214            if (r.adjSource != null || r.adjTarget != null) {
12215                pw.print(prefix);
12216                pw.print("    ");
12217                if (r.adjTarget instanceof ComponentName) {
12218                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12219                } else if (r.adjTarget != null) {
12220                    pw.print(r.adjTarget.toString());
12221                } else {
12222                    pw.print("{null}");
12223                }
12224                pw.print("<=");
12225                if (r.adjSource instanceof ProcessRecord) {
12226                    pw.print("Proc{");
12227                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12228                    pw.println("}");
12229                } else if (r.adjSource != null) {
12230                    pw.println(r.adjSource.toString());
12231                } else {
12232                    pw.println("{null}");
12233                }
12234            }
12235            if (inclDetails) {
12236                pw.print(prefix);
12237                pw.print("    ");
12238                pw.print("oom: max="); pw.print(r.maxAdj);
12239                pw.print(" curRaw="); pw.print(r.curRawAdj);
12240                pw.print(" setRaw="); pw.print(r.setRawAdj);
12241                pw.print(" cur="); pw.print(r.curAdj);
12242                pw.print(" set="); pw.println(r.setAdj);
12243                pw.print(prefix);
12244                pw.print("    ");
12245                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12246                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12247                pw.print(" lastPss="); pw.print(r.lastPss);
12248                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12249                pw.print(prefix);
12250                pw.print("    ");
12251                pw.print("keeping="); pw.print(r.keeping);
12252                pw.print(" cached="); pw.print(r.cached);
12253                pw.print(" empty="); pw.print(r.empty);
12254                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12255
12256                if (!r.keeping) {
12257                    if (r.lastWakeTime != 0) {
12258                        long wtime;
12259                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12260                        synchronized (stats) {
12261                            wtime = stats.getProcessWakeTime(r.info.uid,
12262                                    r.pid, curRealtime);
12263                        }
12264                        long timeUsed = wtime - r.lastWakeTime;
12265                        pw.print(prefix);
12266                        pw.print("    ");
12267                        pw.print("keep awake over ");
12268                        TimeUtils.formatDuration(realtimeSince, pw);
12269                        pw.print(" used ");
12270                        TimeUtils.formatDuration(timeUsed, pw);
12271                        pw.print(" (");
12272                        pw.print((timeUsed*100)/realtimeSince);
12273                        pw.println("%)");
12274                    }
12275                    if (r.lastCpuTime != 0) {
12276                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12277                        pw.print(prefix);
12278                        pw.print("    ");
12279                        pw.print("run cpu over ");
12280                        TimeUtils.formatDuration(uptimeSince, pw);
12281                        pw.print(" used ");
12282                        TimeUtils.formatDuration(timeUsed, pw);
12283                        pw.print(" (");
12284                        pw.print((timeUsed*100)/uptimeSince);
12285                        pw.println("%)");
12286                    }
12287                }
12288            }
12289        }
12290        return true;
12291    }
12292
12293    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12294        ArrayList<ProcessRecord> procs;
12295        synchronized (this) {
12296            if (args != null && args.length > start
12297                    && args[start].charAt(0) != '-') {
12298                procs = new ArrayList<ProcessRecord>();
12299                int pid = -1;
12300                try {
12301                    pid = Integer.parseInt(args[start]);
12302                } catch (NumberFormatException e) {
12303                }
12304                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12305                    ProcessRecord proc = mLruProcesses.get(i);
12306                    if (proc.pid == pid) {
12307                        procs.add(proc);
12308                    } else if (proc.processName.equals(args[start])) {
12309                        procs.add(proc);
12310                    }
12311                }
12312                if (procs.size() <= 0) {
12313                    return null;
12314                }
12315            } else {
12316                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12317            }
12318        }
12319        return procs;
12320    }
12321
12322    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12323            PrintWriter pw, String[] args) {
12324        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12325        if (procs == null) {
12326            pw.println("No process found for: " + args[0]);
12327            return;
12328        }
12329
12330        long uptime = SystemClock.uptimeMillis();
12331        long realtime = SystemClock.elapsedRealtime();
12332        pw.println("Applications Graphics Acceleration Info:");
12333        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12334
12335        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12336            ProcessRecord r = procs.get(i);
12337            if (r.thread != null) {
12338                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12339                pw.flush();
12340                try {
12341                    TransferPipe tp = new TransferPipe();
12342                    try {
12343                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12344                        tp.go(fd);
12345                    } finally {
12346                        tp.kill();
12347                    }
12348                } catch (IOException e) {
12349                    pw.println("Failure while dumping the app: " + r);
12350                    pw.flush();
12351                } catch (RemoteException e) {
12352                    pw.println("Got a RemoteException while dumping the app " + r);
12353                    pw.flush();
12354                }
12355            }
12356        }
12357    }
12358
12359    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12360        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12361        if (procs == null) {
12362            pw.println("No process found for: " + args[0]);
12363            return;
12364        }
12365
12366        pw.println("Applications Database Info:");
12367
12368        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12369            ProcessRecord r = procs.get(i);
12370            if (r.thread != null) {
12371                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12372                pw.flush();
12373                try {
12374                    TransferPipe tp = new TransferPipe();
12375                    try {
12376                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12377                        tp.go(fd);
12378                    } finally {
12379                        tp.kill();
12380                    }
12381                } catch (IOException e) {
12382                    pw.println("Failure while dumping the app: " + r);
12383                    pw.flush();
12384                } catch (RemoteException e) {
12385                    pw.println("Got a RemoteException while dumping the app " + r);
12386                    pw.flush();
12387                }
12388            }
12389        }
12390    }
12391
12392    final static class MemItem {
12393        final boolean isProc;
12394        final String label;
12395        final String shortLabel;
12396        final long pss;
12397        final int id;
12398        final boolean hasActivities;
12399        ArrayList<MemItem> subitems;
12400
12401        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12402                boolean _hasActivities) {
12403            isProc = true;
12404            label = _label;
12405            shortLabel = _shortLabel;
12406            pss = _pss;
12407            id = _id;
12408            hasActivities = _hasActivities;
12409        }
12410
12411        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12412            isProc = false;
12413            label = _label;
12414            shortLabel = _shortLabel;
12415            pss = _pss;
12416            id = _id;
12417            hasActivities = false;
12418        }
12419    }
12420
12421    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12422            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12423        if (sort && !isCompact) {
12424            Collections.sort(items, new Comparator<MemItem>() {
12425                @Override
12426                public int compare(MemItem lhs, MemItem rhs) {
12427                    if (lhs.pss < rhs.pss) {
12428                        return 1;
12429                    } else if (lhs.pss > rhs.pss) {
12430                        return -1;
12431                    }
12432                    return 0;
12433                }
12434            });
12435        }
12436
12437        for (int i=0; i<items.size(); i++) {
12438            MemItem mi = items.get(i);
12439            if (!isCompact) {
12440                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12441            } else if (mi.isProc) {
12442                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12443                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12444                pw.println(mi.hasActivities ? ",a" : ",e");
12445            } else {
12446                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12447                pw.println(mi.pss);
12448            }
12449            if (mi.subitems != null) {
12450                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12451                        true, isCompact);
12452            }
12453        }
12454    }
12455
12456    // These are in KB.
12457    static final long[] DUMP_MEM_BUCKETS = new long[] {
12458        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12459        120*1024, 160*1024, 200*1024,
12460        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12461        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12462    };
12463
12464    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12465            boolean stackLike) {
12466        int start = label.lastIndexOf('.');
12467        if (start >= 0) start++;
12468        else start = 0;
12469        int end = label.length();
12470        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12471            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12472                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12473                out.append(bucket);
12474                out.append(stackLike ? "MB." : "MB ");
12475                out.append(label, start, end);
12476                return;
12477            }
12478        }
12479        out.append(memKB/1024);
12480        out.append(stackLike ? "MB." : "MB ");
12481        out.append(label, start, end);
12482    }
12483
12484    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12485            ProcessList.NATIVE_ADJ,
12486            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12487            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12488            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12489            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12490            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12491    };
12492    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12493            "Native",
12494            "System", "Persistent", "Foreground",
12495            "Visible", "Perceptible",
12496            "Heavy Weight", "Backup",
12497            "A Services", "Home",
12498            "Previous", "B Services", "Cached"
12499    };
12500    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12501            "native",
12502            "sys", "pers", "fore",
12503            "vis", "percept",
12504            "heavy", "backup",
12505            "servicea", "home",
12506            "prev", "serviceb", "cached"
12507    };
12508
12509    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12510            long realtime, boolean isCheckinRequest, boolean isCompact) {
12511        if (isCheckinRequest || isCompact) {
12512            // short checkin version
12513            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12514        } else {
12515            pw.println("Applications Memory Usage (kB):");
12516            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12517        }
12518    }
12519
12520    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12521            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12522        boolean dumpDetails = false;
12523        boolean dumpFullDetails = false;
12524        boolean dumpDalvik = false;
12525        boolean oomOnly = false;
12526        boolean isCompact = false;
12527        boolean localOnly = false;
12528
12529        int opti = 0;
12530        while (opti < args.length) {
12531            String opt = args[opti];
12532            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12533                break;
12534            }
12535            opti++;
12536            if ("-a".equals(opt)) {
12537                dumpDetails = true;
12538                dumpFullDetails = true;
12539                dumpDalvik = true;
12540            } else if ("-d".equals(opt)) {
12541                dumpDalvik = true;
12542            } else if ("-c".equals(opt)) {
12543                isCompact = true;
12544            } else if ("--oom".equals(opt)) {
12545                oomOnly = true;
12546            } else if ("--local".equals(opt)) {
12547                localOnly = true;
12548            } else if ("-h".equals(opt)) {
12549                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12550                pw.println("  -a: include all available information for each process.");
12551                pw.println("  -d: include dalvik details when dumping process details.");
12552                pw.println("  -c: dump in a compact machine-parseable representation.");
12553                pw.println("  --oom: only show processes organized by oom adj.");
12554                pw.println("  --local: only collect details locally, don't call process.");
12555                pw.println("If [process] is specified it can be the name or ");
12556                pw.println("pid of a specific process to dump.");
12557                return;
12558            } else {
12559                pw.println("Unknown argument: " + opt + "; use -h for help");
12560            }
12561        }
12562
12563        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12564        long uptime = SystemClock.uptimeMillis();
12565        long realtime = SystemClock.elapsedRealtime();
12566        final long[] tmpLong = new long[1];
12567
12568        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12569        if (procs == null) {
12570            // No Java processes.  Maybe they want to print a native process.
12571            if (args != null && args.length > opti
12572                    && args[opti].charAt(0) != '-') {
12573                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12574                        = new ArrayList<ProcessCpuTracker.Stats>();
12575                updateCpuStatsNow();
12576                int findPid = -1;
12577                try {
12578                    findPid = Integer.parseInt(args[opti]);
12579                } catch (NumberFormatException e) {
12580                }
12581                synchronized (mProcessCpuThread) {
12582                    final int N = mProcessCpuTracker.countStats();
12583                    for (int i=0; i<N; i++) {
12584                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12585                        if (st.pid == findPid || (st.baseName != null
12586                                && st.baseName.equals(args[opti]))) {
12587                            nativeProcs.add(st);
12588                        }
12589                    }
12590                }
12591                if (nativeProcs.size() > 0) {
12592                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12593                            isCompact);
12594                    Debug.MemoryInfo mi = null;
12595                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12596                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12597                        final int pid = r.pid;
12598                        if (!isCheckinRequest && dumpDetails) {
12599                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12600                        }
12601                        if (mi == null) {
12602                            mi = new Debug.MemoryInfo();
12603                        }
12604                        if (dumpDetails || (!brief && !oomOnly)) {
12605                            Debug.getMemoryInfo(pid, mi);
12606                        } else {
12607                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12608                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12609                        }
12610                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12611                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12612                        if (isCheckinRequest) {
12613                            pw.println();
12614                        }
12615                    }
12616                    return;
12617                }
12618            }
12619            pw.println("No process found for: " + args[opti]);
12620            return;
12621        }
12622
12623        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12624            dumpDetails = true;
12625        }
12626
12627        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12628
12629        String[] innerArgs = new String[args.length-opti];
12630        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12631
12632        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12633        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12634        long nativePss=0, dalvikPss=0, otherPss=0;
12635        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12636
12637        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12638        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12639                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12640
12641        long totalPss = 0;
12642        long cachedPss = 0;
12643
12644        Debug.MemoryInfo mi = null;
12645        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12646            final ProcessRecord r = procs.get(i);
12647            final IApplicationThread thread;
12648            final int pid;
12649            final int oomAdj;
12650            final boolean hasActivities;
12651            synchronized (this) {
12652                thread = r.thread;
12653                pid = r.pid;
12654                oomAdj = r.getSetAdjWithServices();
12655                hasActivities = r.activities.size() > 0;
12656            }
12657            if (thread != null) {
12658                if (!isCheckinRequest && dumpDetails) {
12659                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12660                }
12661                if (mi == null) {
12662                    mi = new Debug.MemoryInfo();
12663                }
12664                if (dumpDetails || (!brief && !oomOnly)) {
12665                    Debug.getMemoryInfo(pid, mi);
12666                } else {
12667                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12668                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12669                }
12670                if (dumpDetails) {
12671                    if (localOnly) {
12672                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12673                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12674                        if (isCheckinRequest) {
12675                            pw.println();
12676                        }
12677                    } else {
12678                        try {
12679                            pw.flush();
12680                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12681                                    dumpDalvik, innerArgs);
12682                        } catch (RemoteException e) {
12683                            if (!isCheckinRequest) {
12684                                pw.println("Got RemoteException!");
12685                                pw.flush();
12686                            }
12687                        }
12688                    }
12689                }
12690
12691                final long myTotalPss = mi.getTotalPss();
12692                final long myTotalUss = mi.getTotalUss();
12693
12694                synchronized (this) {
12695                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12696                        // Record this for posterity if the process has been stable.
12697                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12698                    }
12699                }
12700
12701                if (!isCheckinRequest && mi != null) {
12702                    totalPss += myTotalPss;
12703                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12704                            (hasActivities ? " / activities)" : ")"),
12705                            r.processName, myTotalPss, pid, hasActivities);
12706                    procMems.add(pssItem);
12707                    procMemsMap.put(pid, pssItem);
12708
12709                    nativePss += mi.nativePss;
12710                    dalvikPss += mi.dalvikPss;
12711                    otherPss += mi.otherPss;
12712                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12713                        long mem = mi.getOtherPss(j);
12714                        miscPss[j] += mem;
12715                        otherPss -= mem;
12716                    }
12717
12718                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12719                        cachedPss += myTotalPss;
12720                    }
12721
12722                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12723                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12724                                || oomIndex == (oomPss.length-1)) {
12725                            oomPss[oomIndex] += myTotalPss;
12726                            if (oomProcs[oomIndex] == null) {
12727                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12728                            }
12729                            oomProcs[oomIndex].add(pssItem);
12730                            break;
12731                        }
12732                    }
12733                }
12734            }
12735        }
12736
12737        long nativeProcTotalPss = 0;
12738
12739        if (!isCheckinRequest && procs.size() > 1) {
12740            // If we are showing aggregations, also look for native processes to
12741            // include so that our aggregations are more accurate.
12742            updateCpuStatsNow();
12743            synchronized (mProcessCpuThread) {
12744                final int N = mProcessCpuTracker.countStats();
12745                for (int i=0; i<N; i++) {
12746                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12747                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12748                        if (mi == null) {
12749                            mi = new Debug.MemoryInfo();
12750                        }
12751                        if (!brief && !oomOnly) {
12752                            Debug.getMemoryInfo(st.pid, mi);
12753                        } else {
12754                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12755                            mi.nativePrivateDirty = (int)tmpLong[0];
12756                        }
12757
12758                        final long myTotalPss = mi.getTotalPss();
12759                        totalPss += myTotalPss;
12760                        nativeProcTotalPss += myTotalPss;
12761
12762                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12763                                st.name, myTotalPss, st.pid, false);
12764                        procMems.add(pssItem);
12765
12766                        nativePss += mi.nativePss;
12767                        dalvikPss += mi.dalvikPss;
12768                        otherPss += mi.otherPss;
12769                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12770                            long mem = mi.getOtherPss(j);
12771                            miscPss[j] += mem;
12772                            otherPss -= mem;
12773                        }
12774                        oomPss[0] += myTotalPss;
12775                        if (oomProcs[0] == null) {
12776                            oomProcs[0] = new ArrayList<MemItem>();
12777                        }
12778                        oomProcs[0].add(pssItem);
12779                    }
12780                }
12781            }
12782
12783            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12784
12785            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12786            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12787            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12788            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12789                String label = Debug.MemoryInfo.getOtherLabel(j);
12790                catMems.add(new MemItem(label, label, miscPss[j], j));
12791            }
12792
12793            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12794            for (int j=0; j<oomPss.length; j++) {
12795                if (oomPss[j] != 0) {
12796                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12797                            : DUMP_MEM_OOM_LABEL[j];
12798                    MemItem item = new MemItem(label, label, oomPss[j],
12799                            DUMP_MEM_OOM_ADJ[j]);
12800                    item.subitems = oomProcs[j];
12801                    oomMems.add(item);
12802                }
12803            }
12804
12805            if (!brief && !oomOnly && !isCompact) {
12806                pw.println();
12807                pw.println("Total PSS by process:");
12808                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12809                pw.println();
12810            }
12811            if (!isCompact) {
12812                pw.println("Total PSS by OOM adjustment:");
12813            }
12814            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12815            if (!brief && !oomOnly) {
12816                PrintWriter out = categoryPw != null ? categoryPw : pw;
12817                if (!isCompact) {
12818                    out.println();
12819                    out.println("Total PSS by category:");
12820                }
12821                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12822            }
12823            if (!isCompact) {
12824                pw.println();
12825            }
12826            MemInfoReader memInfo = new MemInfoReader();
12827            memInfo.readMemInfo();
12828            if (nativeProcTotalPss > 0) {
12829                synchronized (this) {
12830                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12831                            memInfo.getFreeSizeKb(),
12832                            memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
12833                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12834                            nativeProcTotalPss);
12835                }
12836            }
12837            if (!brief) {
12838                if (!isCompact) {
12839                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12840                    pw.print(" kB (status ");
12841                    switch (mLastMemoryLevel) {
12842                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12843                            pw.println("normal)");
12844                            break;
12845                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12846                            pw.println("moderate)");
12847                            break;
12848                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12849                            pw.println("low)");
12850                            break;
12851                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12852                            pw.println("critical)");
12853                            break;
12854                        default:
12855                            pw.print(mLastMemoryLevel);
12856                            pw.println(")");
12857                            break;
12858                    }
12859                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12860                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12861                            pw.print(cachedPss); pw.print(" cached pss + ");
12862                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12863                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12864                } else {
12865                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12866                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12867                            + memInfo.getFreeSizeKb()); pw.print(",");
12868                    pw.println(totalPss - cachedPss);
12869                }
12870            }
12871            if (!isCompact) {
12872                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12873                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12874                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12875                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12876                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12877                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12878                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12879                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12880                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12881                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12882                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12883            }
12884            if (!brief) {
12885                if (memInfo.getZramTotalSizeKb() != 0) {
12886                    if (!isCompact) {
12887                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12888                                pw.print(" kB physical used for ");
12889                                pw.print(memInfo.getSwapTotalSizeKb()
12890                                        - memInfo.getSwapFreeSizeKb());
12891                                pw.print(" kB in swap (");
12892                                pw.print(memInfo.getSwapTotalSizeKb());
12893                                pw.println(" kB total swap)");
12894                    } else {
12895                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12896                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12897                                pw.println(memInfo.getSwapFreeSizeKb());
12898                    }
12899                }
12900                final int[] SINGLE_LONG_FORMAT = new int[] {
12901                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12902                };
12903                long[] longOut = new long[1];
12904                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12905                        SINGLE_LONG_FORMAT, null, longOut, null);
12906                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12907                longOut[0] = 0;
12908                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12909                        SINGLE_LONG_FORMAT, null, longOut, null);
12910                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12911                longOut[0] = 0;
12912                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12913                        SINGLE_LONG_FORMAT, null, longOut, null);
12914                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12915                longOut[0] = 0;
12916                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12917                        SINGLE_LONG_FORMAT, null, longOut, null);
12918                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12919                if (!isCompact) {
12920                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12921                        pw.print("      KSM: "); pw.print(sharing);
12922                                pw.print(" kB saved from shared ");
12923                                pw.print(shared); pw.println(" kB");
12924                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12925                                pw.print(voltile); pw.println(" kB volatile");
12926                    }
12927                    pw.print("   Tuning: ");
12928                    pw.print(ActivityManager.staticGetMemoryClass());
12929                    pw.print(" (large ");
12930                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12931                    pw.print("), oom ");
12932                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12933                    pw.print(" kB");
12934                    pw.print(", restore limit ");
12935                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12936                    pw.print(" kB");
12937                    if (ActivityManager.isLowRamDeviceStatic()) {
12938                        pw.print(" (low-ram)");
12939                    }
12940                    if (ActivityManager.isHighEndGfx()) {
12941                        pw.print(" (high-end-gfx)");
12942                    }
12943                    pw.println();
12944                } else {
12945                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12946                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12947                    pw.println(voltile);
12948                    pw.print("tuning,");
12949                    pw.print(ActivityManager.staticGetMemoryClass());
12950                    pw.print(',');
12951                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12952                    pw.print(',');
12953                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12954                    if (ActivityManager.isLowRamDeviceStatic()) {
12955                        pw.print(",low-ram");
12956                    }
12957                    if (ActivityManager.isHighEndGfx()) {
12958                        pw.print(",high-end-gfx");
12959                    }
12960                    pw.println();
12961                }
12962            }
12963        }
12964    }
12965
12966    /**
12967     * Searches array of arguments for the specified string
12968     * @param args array of argument strings
12969     * @param value value to search for
12970     * @return true if the value is contained in the array
12971     */
12972    private static boolean scanArgs(String[] args, String value) {
12973        if (args != null) {
12974            for (String arg : args) {
12975                if (value.equals(arg)) {
12976                    return true;
12977                }
12978            }
12979        }
12980        return false;
12981    }
12982
12983    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12984            ContentProviderRecord cpr, boolean always) {
12985        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12986
12987        if (!inLaunching || always) {
12988            synchronized (cpr) {
12989                cpr.launchingApp = null;
12990                cpr.notifyAll();
12991            }
12992            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12993            String names[] = cpr.info.authority.split(";");
12994            for (int j = 0; j < names.length; j++) {
12995                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12996            }
12997        }
12998
12999        for (int i=0; i<cpr.connections.size(); i++) {
13000            ContentProviderConnection conn = cpr.connections.get(i);
13001            if (conn.waiting) {
13002                // If this connection is waiting for the provider, then we don't
13003                // need to mess with its process unless we are always removing
13004                // or for some reason the provider is not currently launching.
13005                if (inLaunching && !always) {
13006                    continue;
13007                }
13008            }
13009            ProcessRecord capp = conn.client;
13010            conn.dead = true;
13011            if (conn.stableCount > 0) {
13012                if (!capp.persistent && capp.thread != null
13013                        && capp.pid != 0
13014                        && capp.pid != MY_PID) {
13015                    killUnneededProcessLocked(capp, "depends on provider "
13016                            + cpr.name.flattenToShortString()
13017                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13018                }
13019            } else if (capp.thread != null && conn.provider.provider != null) {
13020                try {
13021                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13022                } catch (RemoteException e) {
13023                }
13024                // In the protocol here, we don't expect the client to correctly
13025                // clean up this connection, we'll just remove it.
13026                cpr.connections.remove(i);
13027                conn.client.conProviders.remove(conn);
13028            }
13029        }
13030
13031        if (inLaunching && always) {
13032            mLaunchingProviders.remove(cpr);
13033        }
13034        return inLaunching;
13035    }
13036
13037    /**
13038     * Main code for cleaning up a process when it has gone away.  This is
13039     * called both as a result of the process dying, or directly when stopping
13040     * a process when running in single process mode.
13041     */
13042    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13043            boolean restarting, boolean allowRestart, int index) {
13044        if (index >= 0) {
13045            removeLruProcessLocked(app);
13046            ProcessList.remove(app.pid);
13047        }
13048
13049        mProcessesToGc.remove(app);
13050        mPendingPssProcesses.remove(app);
13051
13052        // Dismiss any open dialogs.
13053        if (app.crashDialog != null && !app.forceCrashReport) {
13054            app.crashDialog.dismiss();
13055            app.crashDialog = null;
13056        }
13057        if (app.anrDialog != null) {
13058            app.anrDialog.dismiss();
13059            app.anrDialog = null;
13060        }
13061        if (app.waitDialog != null) {
13062            app.waitDialog.dismiss();
13063            app.waitDialog = null;
13064        }
13065
13066        app.crashing = false;
13067        app.notResponding = false;
13068
13069        app.resetPackageList(mProcessStats);
13070        app.unlinkDeathRecipient();
13071        app.makeInactive(mProcessStats);
13072        app.forcingToForeground = null;
13073        updateProcessForegroundLocked(app, false, false);
13074        app.foregroundActivities = false;
13075        app.hasShownUi = false;
13076        app.treatLikeActivity = false;
13077        app.hasAboveClient = false;
13078        app.hasClientActivities = false;
13079
13080        mServices.killServicesLocked(app, allowRestart);
13081
13082        boolean restart = false;
13083
13084        // Remove published content providers.
13085        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13086            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13087            final boolean always = app.bad || !allowRestart;
13088            if (removeDyingProviderLocked(app, cpr, always) || always) {
13089                // We left the provider in the launching list, need to
13090                // restart it.
13091                restart = true;
13092            }
13093
13094            cpr.provider = null;
13095            cpr.proc = null;
13096        }
13097        app.pubProviders.clear();
13098
13099        // Take care of any launching providers waiting for this process.
13100        if (checkAppInLaunchingProvidersLocked(app, false)) {
13101            restart = true;
13102        }
13103
13104        // Unregister from connected content providers.
13105        if (!app.conProviders.isEmpty()) {
13106            for (int i=0; i<app.conProviders.size(); i++) {
13107                ContentProviderConnection conn = app.conProviders.get(i);
13108                conn.provider.connections.remove(conn);
13109            }
13110            app.conProviders.clear();
13111        }
13112
13113        // At this point there may be remaining entries in mLaunchingProviders
13114        // where we were the only one waiting, so they are no longer of use.
13115        // Look for these and clean up if found.
13116        // XXX Commented out for now.  Trying to figure out a way to reproduce
13117        // the actual situation to identify what is actually going on.
13118        if (false) {
13119            for (int i=0; i<mLaunchingProviders.size(); i++) {
13120                ContentProviderRecord cpr = (ContentProviderRecord)
13121                        mLaunchingProviders.get(i);
13122                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13123                    synchronized (cpr) {
13124                        cpr.launchingApp = null;
13125                        cpr.notifyAll();
13126                    }
13127                }
13128            }
13129        }
13130
13131        skipCurrentReceiverLocked(app);
13132
13133        // Unregister any receivers.
13134        for (int i=app.receivers.size()-1; i>=0; i--) {
13135            removeReceiverLocked(app.receivers.valueAt(i));
13136        }
13137        app.receivers.clear();
13138
13139        // If the app is undergoing backup, tell the backup manager about it
13140        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13141            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13142                    + mBackupTarget.appInfo + " died during backup");
13143            try {
13144                IBackupManager bm = IBackupManager.Stub.asInterface(
13145                        ServiceManager.getService(Context.BACKUP_SERVICE));
13146                bm.agentDisconnected(app.info.packageName);
13147            } catch (RemoteException e) {
13148                // can't happen; backup manager is local
13149            }
13150        }
13151
13152        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13153            ProcessChangeItem item = mPendingProcessChanges.get(i);
13154            if (item.pid == app.pid) {
13155                mPendingProcessChanges.remove(i);
13156                mAvailProcessChanges.add(item);
13157            }
13158        }
13159        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13160
13161        // If the caller is restarting this app, then leave it in its
13162        // current lists and let the caller take care of it.
13163        if (restarting) {
13164            return;
13165        }
13166
13167        if (!app.persistent || app.isolated) {
13168            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13169                    "Removing non-persistent process during cleanup: " + app);
13170            mProcessNames.remove(app.processName, app.uid);
13171            mIsolatedProcesses.remove(app.uid);
13172            if (mHeavyWeightProcess == app) {
13173                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13174                        mHeavyWeightProcess.userId, 0));
13175                mHeavyWeightProcess = null;
13176            }
13177        } else if (!app.removed) {
13178            // This app is persistent, so we need to keep its record around.
13179            // If it is not already on the pending app list, add it there
13180            // and start a new process for it.
13181            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13182                mPersistentStartingProcesses.add(app);
13183                restart = true;
13184            }
13185        }
13186        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13187                "Clean-up removing on hold: " + app);
13188        mProcessesOnHold.remove(app);
13189
13190        if (app == mHomeProcess) {
13191            mHomeProcess = null;
13192        }
13193        if (app == mPreviousProcess) {
13194            mPreviousProcess = null;
13195        }
13196
13197        if (restart && !app.isolated) {
13198            // We have components that still need to be running in the
13199            // process, so re-launch it.
13200            mProcessNames.put(app.processName, app.uid, app);
13201            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13202        } else if (app.pid > 0 && app.pid != MY_PID) {
13203            // Goodbye!
13204            boolean removed;
13205            synchronized (mPidsSelfLocked) {
13206                mPidsSelfLocked.remove(app.pid);
13207                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13208            }
13209            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13210                    app.processName, app.info.uid);
13211            if (app.isolated) {
13212                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13213            }
13214            app.setPid(0);
13215        }
13216    }
13217
13218    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13219        // Look through the content providers we are waiting to have launched,
13220        // and if any run in this process then either schedule a restart of
13221        // the process or kill the client waiting for it if this process has
13222        // gone bad.
13223        int NL = mLaunchingProviders.size();
13224        boolean restart = false;
13225        for (int i=0; i<NL; i++) {
13226            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13227            if (cpr.launchingApp == app) {
13228                if (!alwaysBad && !app.bad) {
13229                    restart = true;
13230                } else {
13231                    removeDyingProviderLocked(app, cpr, true);
13232                    // cpr should have been removed from mLaunchingProviders
13233                    NL = mLaunchingProviders.size();
13234                    i--;
13235                }
13236            }
13237        }
13238        return restart;
13239    }
13240
13241    // =========================================================
13242    // SERVICES
13243    // =========================================================
13244
13245    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13246            int flags) {
13247        enforceNotIsolatedCaller("getServices");
13248        synchronized (this) {
13249            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13250        }
13251    }
13252
13253    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13254        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13255        synchronized (this) {
13256            return mServices.getRunningServiceControlPanelLocked(name);
13257        }
13258    }
13259
13260    public ComponentName startService(IApplicationThread caller, Intent service,
13261            String resolvedType, int userId) {
13262        enforceNotIsolatedCaller("startService");
13263        // Refuse possible leaked file descriptors
13264        if (service != null && service.hasFileDescriptors() == true) {
13265            throw new IllegalArgumentException("File descriptors passed in Intent");
13266        }
13267
13268        if (DEBUG_SERVICE)
13269            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13270        synchronized(this) {
13271            final int callingPid = Binder.getCallingPid();
13272            final int callingUid = Binder.getCallingUid();
13273            final long origId = Binder.clearCallingIdentity();
13274            ComponentName res = mServices.startServiceLocked(caller, service,
13275                    resolvedType, callingPid, callingUid, userId);
13276            Binder.restoreCallingIdentity(origId);
13277            return res;
13278        }
13279    }
13280
13281    ComponentName startServiceInPackage(int uid,
13282            Intent service, String resolvedType, int userId) {
13283        synchronized(this) {
13284            if (DEBUG_SERVICE)
13285                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13286            final long origId = Binder.clearCallingIdentity();
13287            ComponentName res = mServices.startServiceLocked(null, service,
13288                    resolvedType, -1, uid, userId);
13289            Binder.restoreCallingIdentity(origId);
13290            return res;
13291        }
13292    }
13293
13294    public int stopService(IApplicationThread caller, Intent service,
13295            String resolvedType, int userId) {
13296        enforceNotIsolatedCaller("stopService");
13297        // Refuse possible leaked file descriptors
13298        if (service != null && service.hasFileDescriptors() == true) {
13299            throw new IllegalArgumentException("File descriptors passed in Intent");
13300        }
13301
13302        synchronized(this) {
13303            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13304        }
13305    }
13306
13307    public IBinder peekService(Intent service, String resolvedType) {
13308        enforceNotIsolatedCaller("peekService");
13309        // Refuse possible leaked file descriptors
13310        if (service != null && service.hasFileDescriptors() == true) {
13311            throw new IllegalArgumentException("File descriptors passed in Intent");
13312        }
13313        synchronized(this) {
13314            return mServices.peekServiceLocked(service, resolvedType);
13315        }
13316    }
13317
13318    public boolean stopServiceToken(ComponentName className, IBinder token,
13319            int startId) {
13320        synchronized(this) {
13321            return mServices.stopServiceTokenLocked(className, token, startId);
13322        }
13323    }
13324
13325    public void setServiceForeground(ComponentName className, IBinder token,
13326            int id, Notification notification, boolean removeNotification) {
13327        synchronized(this) {
13328            mServices.setServiceForegroundLocked(className, token, id, notification,
13329                    removeNotification);
13330        }
13331    }
13332
13333    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13334            boolean requireFull, String name, String callerPackage) {
13335        final int callingUserId = UserHandle.getUserId(callingUid);
13336        if (callingUserId != userId) {
13337            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13338                if ((requireFull || checkComponentPermission(
13339                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13340                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13341                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13342                                callingPid, callingUid, -1, true)
13343                                != PackageManager.PERMISSION_GRANTED) {
13344                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13345                        // In this case, they would like to just execute as their
13346                        // owner user instead of failing.
13347                        userId = callingUserId;
13348                    } else {
13349                        StringBuilder builder = new StringBuilder(128);
13350                        builder.append("Permission Denial: ");
13351                        builder.append(name);
13352                        if (callerPackage != null) {
13353                            builder.append(" from ");
13354                            builder.append(callerPackage);
13355                        }
13356                        builder.append(" asks to run as user ");
13357                        builder.append(userId);
13358                        builder.append(" but is calling from user ");
13359                        builder.append(UserHandle.getUserId(callingUid));
13360                        builder.append("; this requires ");
13361                        builder.append(INTERACT_ACROSS_USERS_FULL);
13362                        if (!requireFull) {
13363                            builder.append(" or ");
13364                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13365                        }
13366                        String msg = builder.toString();
13367                        Slog.w(TAG, msg);
13368                        throw new SecurityException(msg);
13369                    }
13370                }
13371            }
13372            if (userId == UserHandle.USER_CURRENT
13373                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13374                // Note that we may be accessing this outside of a lock...
13375                // shouldn't be a big deal, if this is being called outside
13376                // of a locked context there is intrinsically a race with
13377                // the value the caller will receive and someone else changing it.
13378                userId = mCurrentUserId;
13379            }
13380            if (!allowAll && userId < 0) {
13381                throw new IllegalArgumentException(
13382                        "Call does not support special user #" + userId);
13383            }
13384        }
13385        return userId;
13386    }
13387
13388    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13389            String className, int flags) {
13390        boolean result = false;
13391        // For apps that don't have pre-defined UIDs, check for permission
13392        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13393            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13394                if (ActivityManager.checkUidPermission(
13395                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13396                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13397                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13398                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13399                            + " requests FLAG_SINGLE_USER, but app does not hold "
13400                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13401                    Slog.w(TAG, msg);
13402                    throw new SecurityException(msg);
13403                }
13404                // Permission passed
13405                result = true;
13406            }
13407        } else if ("system".equals(componentProcessName)) {
13408            result = true;
13409        } else {
13410            // App with pre-defined UID, check if it's a persistent app
13411            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13412        }
13413        if (DEBUG_MU) {
13414            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13415                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13416        }
13417        return result;
13418    }
13419
13420    /**
13421     * Checks to see if the caller is in the same app as the singleton
13422     * component, or the component is in a special app. It allows special apps
13423     * to export singleton components but prevents exporting singleton
13424     * components for regular apps.
13425     */
13426    boolean isValidSingletonCall(int callingUid, int componentUid) {
13427        int componentAppId = UserHandle.getAppId(componentUid);
13428        return UserHandle.isSameApp(callingUid, componentUid)
13429                || componentAppId == Process.SYSTEM_UID
13430                || componentAppId == Process.PHONE_UID
13431                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13432                        == PackageManager.PERMISSION_GRANTED;
13433    }
13434
13435    public int bindService(IApplicationThread caller, IBinder token,
13436            Intent service, String resolvedType,
13437            IServiceConnection connection, int flags, int userId) {
13438        enforceNotIsolatedCaller("bindService");
13439        // Refuse possible leaked file descriptors
13440        if (service != null && service.hasFileDescriptors() == true) {
13441            throw new IllegalArgumentException("File descriptors passed in Intent");
13442        }
13443
13444        synchronized(this) {
13445            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13446                    connection, flags, userId);
13447        }
13448    }
13449
13450    public boolean unbindService(IServiceConnection connection) {
13451        synchronized (this) {
13452            return mServices.unbindServiceLocked(connection);
13453        }
13454    }
13455
13456    public void publishService(IBinder token, Intent intent, IBinder service) {
13457        // Refuse possible leaked file descriptors
13458        if (intent != null && intent.hasFileDescriptors() == true) {
13459            throw new IllegalArgumentException("File descriptors passed in Intent");
13460        }
13461
13462        synchronized(this) {
13463            if (!(token instanceof ServiceRecord)) {
13464                throw new IllegalArgumentException("Invalid service token");
13465            }
13466            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13467        }
13468    }
13469
13470    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13471        // Refuse possible leaked file descriptors
13472        if (intent != null && intent.hasFileDescriptors() == true) {
13473            throw new IllegalArgumentException("File descriptors passed in Intent");
13474        }
13475
13476        synchronized(this) {
13477            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13478        }
13479    }
13480
13481    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13482        synchronized(this) {
13483            if (!(token instanceof ServiceRecord)) {
13484                throw new IllegalArgumentException("Invalid service token");
13485            }
13486            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13487        }
13488    }
13489
13490    // =========================================================
13491    // BACKUP AND RESTORE
13492    // =========================================================
13493
13494    // Cause the target app to be launched if necessary and its backup agent
13495    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13496    // activity manager to announce its creation.
13497    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13498        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13499        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13500
13501        synchronized(this) {
13502            // !!! TODO: currently no check here that we're already bound
13503            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13504            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13505            synchronized (stats) {
13506                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13507            }
13508
13509            // Backup agent is now in use, its package can't be stopped.
13510            try {
13511                AppGlobals.getPackageManager().setPackageStoppedState(
13512                        app.packageName, false, UserHandle.getUserId(app.uid));
13513            } catch (RemoteException e) {
13514            } catch (IllegalArgumentException e) {
13515                Slog.w(TAG, "Failed trying to unstop package "
13516                        + app.packageName + ": " + e);
13517            }
13518
13519            BackupRecord r = new BackupRecord(ss, app, backupMode);
13520            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13521                    ? new ComponentName(app.packageName, app.backupAgentName)
13522                    : new ComponentName("android", "FullBackupAgent");
13523            // startProcessLocked() returns existing proc's record if it's already running
13524            ProcessRecord proc = startProcessLocked(app.processName, app,
13525                    false, 0, "backup", hostingName, false, false, false);
13526            if (proc == null) {
13527                Slog.e(TAG, "Unable to start backup agent process " + r);
13528                return false;
13529            }
13530
13531            r.app = proc;
13532            mBackupTarget = r;
13533            mBackupAppName = app.packageName;
13534
13535            // Try not to kill the process during backup
13536            updateOomAdjLocked(proc);
13537
13538            // If the process is already attached, schedule the creation of the backup agent now.
13539            // If it is not yet live, this will be done when it attaches to the framework.
13540            if (proc.thread != null) {
13541                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13542                try {
13543                    proc.thread.scheduleCreateBackupAgent(app,
13544                            compatibilityInfoForPackageLocked(app), backupMode);
13545                } catch (RemoteException e) {
13546                    // Will time out on the backup manager side
13547                }
13548            } else {
13549                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13550            }
13551            // Invariants: at this point, the target app process exists and the application
13552            // is either already running or in the process of coming up.  mBackupTarget and
13553            // mBackupAppName describe the app, so that when it binds back to the AM we
13554            // know that it's scheduled for a backup-agent operation.
13555        }
13556
13557        return true;
13558    }
13559
13560    @Override
13561    public void clearPendingBackup() {
13562        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13563        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13564
13565        synchronized (this) {
13566            mBackupTarget = null;
13567            mBackupAppName = null;
13568        }
13569    }
13570
13571    // A backup agent has just come up
13572    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13573        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13574                + " = " + agent);
13575
13576        synchronized(this) {
13577            if (!agentPackageName.equals(mBackupAppName)) {
13578                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13579                return;
13580            }
13581        }
13582
13583        long oldIdent = Binder.clearCallingIdentity();
13584        try {
13585            IBackupManager bm = IBackupManager.Stub.asInterface(
13586                    ServiceManager.getService(Context.BACKUP_SERVICE));
13587            bm.agentConnected(agentPackageName, agent);
13588        } catch (RemoteException e) {
13589            // can't happen; the backup manager service is local
13590        } catch (Exception e) {
13591            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13592            e.printStackTrace();
13593        } finally {
13594            Binder.restoreCallingIdentity(oldIdent);
13595        }
13596    }
13597
13598    // done with this agent
13599    public void unbindBackupAgent(ApplicationInfo appInfo) {
13600        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13601        if (appInfo == null) {
13602            Slog.w(TAG, "unbind backup agent for null app");
13603            return;
13604        }
13605
13606        synchronized(this) {
13607            try {
13608                if (mBackupAppName == null) {
13609                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13610                    return;
13611                }
13612
13613                if (!mBackupAppName.equals(appInfo.packageName)) {
13614                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13615                    return;
13616                }
13617
13618                // Not backing this app up any more; reset its OOM adjustment
13619                final ProcessRecord proc = mBackupTarget.app;
13620                updateOomAdjLocked(proc);
13621
13622                // If the app crashed during backup, 'thread' will be null here
13623                if (proc.thread != null) {
13624                    try {
13625                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13626                                compatibilityInfoForPackageLocked(appInfo));
13627                    } catch (Exception e) {
13628                        Slog.e(TAG, "Exception when unbinding backup agent:");
13629                        e.printStackTrace();
13630                    }
13631                }
13632            } finally {
13633                mBackupTarget = null;
13634                mBackupAppName = null;
13635            }
13636        }
13637    }
13638    // =========================================================
13639    // BROADCASTS
13640    // =========================================================
13641
13642    private final List getStickiesLocked(String action, IntentFilter filter,
13643            List cur, int userId) {
13644        final ContentResolver resolver = mContext.getContentResolver();
13645        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13646        if (stickies == null) {
13647            return cur;
13648        }
13649        final ArrayList<Intent> list = stickies.get(action);
13650        if (list == null) {
13651            return cur;
13652        }
13653        int N = list.size();
13654        for (int i=0; i<N; i++) {
13655            Intent intent = list.get(i);
13656            if (filter.match(resolver, intent, true, TAG) >= 0) {
13657                if (cur == null) {
13658                    cur = new ArrayList<Intent>();
13659                }
13660                cur.add(intent);
13661            }
13662        }
13663        return cur;
13664    }
13665
13666    boolean isPendingBroadcastProcessLocked(int pid) {
13667        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13668                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13669    }
13670
13671    void skipPendingBroadcastLocked(int pid) {
13672            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13673            for (BroadcastQueue queue : mBroadcastQueues) {
13674                queue.skipPendingBroadcastLocked(pid);
13675            }
13676    }
13677
13678    // The app just attached; send any pending broadcasts that it should receive
13679    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13680        boolean didSomething = false;
13681        for (BroadcastQueue queue : mBroadcastQueues) {
13682            didSomething |= queue.sendPendingBroadcastsLocked(app);
13683        }
13684        return didSomething;
13685    }
13686
13687    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13688            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13689        enforceNotIsolatedCaller("registerReceiver");
13690        int callingUid;
13691        int callingPid;
13692        synchronized(this) {
13693            ProcessRecord callerApp = null;
13694            if (caller != null) {
13695                callerApp = getRecordForAppLocked(caller);
13696                if (callerApp == null) {
13697                    throw new SecurityException(
13698                            "Unable to find app for caller " + caller
13699                            + " (pid=" + Binder.getCallingPid()
13700                            + ") when registering receiver " + receiver);
13701                }
13702                if (callerApp.info.uid != Process.SYSTEM_UID &&
13703                        !callerApp.pkgList.containsKey(callerPackage) &&
13704                        !"android".equals(callerPackage)) {
13705                    throw new SecurityException("Given caller package " + callerPackage
13706                            + " is not running in process " + callerApp);
13707                }
13708                callingUid = callerApp.info.uid;
13709                callingPid = callerApp.pid;
13710            } else {
13711                callerPackage = null;
13712                callingUid = Binder.getCallingUid();
13713                callingPid = Binder.getCallingPid();
13714            }
13715
13716            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13717                    true, true, "registerReceiver", callerPackage);
13718
13719            List allSticky = null;
13720
13721            // Look for any matching sticky broadcasts...
13722            Iterator actions = filter.actionsIterator();
13723            if (actions != null) {
13724                while (actions.hasNext()) {
13725                    String action = (String)actions.next();
13726                    allSticky = getStickiesLocked(action, filter, allSticky,
13727                            UserHandle.USER_ALL);
13728                    allSticky = getStickiesLocked(action, filter, allSticky,
13729                            UserHandle.getUserId(callingUid));
13730                }
13731            } else {
13732                allSticky = getStickiesLocked(null, filter, allSticky,
13733                        UserHandle.USER_ALL);
13734                allSticky = getStickiesLocked(null, filter, allSticky,
13735                        UserHandle.getUserId(callingUid));
13736            }
13737
13738            // The first sticky in the list is returned directly back to
13739            // the client.
13740            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13741
13742            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13743                    + ": " + sticky);
13744
13745            if (receiver == null) {
13746                return sticky;
13747            }
13748
13749            ReceiverList rl
13750                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13751            if (rl == null) {
13752                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13753                        userId, receiver);
13754                if (rl.app != null) {
13755                    rl.app.receivers.add(rl);
13756                } else {
13757                    try {
13758                        receiver.asBinder().linkToDeath(rl, 0);
13759                    } catch (RemoteException e) {
13760                        return sticky;
13761                    }
13762                    rl.linkedToDeath = true;
13763                }
13764                mRegisteredReceivers.put(receiver.asBinder(), rl);
13765            } else if (rl.uid != callingUid) {
13766                throw new IllegalArgumentException(
13767                        "Receiver requested to register for uid " + callingUid
13768                        + " was previously registered for uid " + rl.uid);
13769            } else if (rl.pid != callingPid) {
13770                throw new IllegalArgumentException(
13771                        "Receiver requested to register for pid " + callingPid
13772                        + " was previously registered for pid " + rl.pid);
13773            } else if (rl.userId != userId) {
13774                throw new IllegalArgumentException(
13775                        "Receiver requested to register for user " + userId
13776                        + " was previously registered for user " + rl.userId);
13777            }
13778            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13779                    permission, callingUid, userId);
13780            rl.add(bf);
13781            if (!bf.debugCheck()) {
13782                Slog.w(TAG, "==> For Dynamic broadast");
13783            }
13784            mReceiverResolver.addFilter(bf);
13785
13786            // Enqueue broadcasts for all existing stickies that match
13787            // this filter.
13788            if (allSticky != null) {
13789                ArrayList receivers = new ArrayList();
13790                receivers.add(bf);
13791
13792                int N = allSticky.size();
13793                for (int i=0; i<N; i++) {
13794                    Intent intent = (Intent)allSticky.get(i);
13795                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13796                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13797                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13798                            null, null, false, true, true, -1);
13799                    queue.enqueueParallelBroadcastLocked(r);
13800                    queue.scheduleBroadcastsLocked();
13801                }
13802            }
13803
13804            return sticky;
13805        }
13806    }
13807
13808    public void unregisterReceiver(IIntentReceiver receiver) {
13809        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13810
13811        final long origId = Binder.clearCallingIdentity();
13812        try {
13813            boolean doTrim = false;
13814
13815            synchronized(this) {
13816                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13817                if (rl != null) {
13818                    if (rl.curBroadcast != null) {
13819                        BroadcastRecord r = rl.curBroadcast;
13820                        final boolean doNext = finishReceiverLocked(
13821                                receiver.asBinder(), r.resultCode, r.resultData,
13822                                r.resultExtras, r.resultAbort);
13823                        if (doNext) {
13824                            doTrim = true;
13825                            r.queue.processNextBroadcast(false);
13826                        }
13827                    }
13828
13829                    if (rl.app != null) {
13830                        rl.app.receivers.remove(rl);
13831                    }
13832                    removeReceiverLocked(rl);
13833                    if (rl.linkedToDeath) {
13834                        rl.linkedToDeath = false;
13835                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13836                    }
13837                }
13838            }
13839
13840            // If we actually concluded any broadcasts, we might now be able
13841            // to trim the recipients' apps from our working set
13842            if (doTrim) {
13843                trimApplications();
13844                return;
13845            }
13846
13847        } finally {
13848            Binder.restoreCallingIdentity(origId);
13849        }
13850    }
13851
13852    void removeReceiverLocked(ReceiverList rl) {
13853        mRegisteredReceivers.remove(rl.receiver.asBinder());
13854        int N = rl.size();
13855        for (int i=0; i<N; i++) {
13856            mReceiverResolver.removeFilter(rl.get(i));
13857        }
13858    }
13859
13860    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13861        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13862            ProcessRecord r = mLruProcesses.get(i);
13863            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13864                try {
13865                    r.thread.dispatchPackageBroadcast(cmd, packages);
13866                } catch (RemoteException ex) {
13867                }
13868            }
13869        }
13870    }
13871
13872    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13873            int[] users) {
13874        List<ResolveInfo> receivers = null;
13875        try {
13876            HashSet<ComponentName> singleUserReceivers = null;
13877            boolean scannedFirstReceivers = false;
13878            for (int user : users) {
13879                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13880                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13881                if (user != 0 && newReceivers != null) {
13882                    // If this is not the primary user, we need to check for
13883                    // any receivers that should be filtered out.
13884                    for (int i=0; i<newReceivers.size(); i++) {
13885                        ResolveInfo ri = newReceivers.get(i);
13886                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13887                            newReceivers.remove(i);
13888                            i--;
13889                        }
13890                    }
13891                }
13892                if (newReceivers != null && newReceivers.size() == 0) {
13893                    newReceivers = null;
13894                }
13895                if (receivers == null) {
13896                    receivers = newReceivers;
13897                } else if (newReceivers != null) {
13898                    // We need to concatenate the additional receivers
13899                    // found with what we have do far.  This would be easy,
13900                    // but we also need to de-dup any receivers that are
13901                    // singleUser.
13902                    if (!scannedFirstReceivers) {
13903                        // Collect any single user receivers we had already retrieved.
13904                        scannedFirstReceivers = true;
13905                        for (int i=0; i<receivers.size(); i++) {
13906                            ResolveInfo ri = receivers.get(i);
13907                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13908                                ComponentName cn = new ComponentName(
13909                                        ri.activityInfo.packageName, ri.activityInfo.name);
13910                                if (singleUserReceivers == null) {
13911                                    singleUserReceivers = new HashSet<ComponentName>();
13912                                }
13913                                singleUserReceivers.add(cn);
13914                            }
13915                        }
13916                    }
13917                    // Add the new results to the existing results, tracking
13918                    // and de-dupping single user receivers.
13919                    for (int i=0; i<newReceivers.size(); i++) {
13920                        ResolveInfo ri = newReceivers.get(i);
13921                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13922                            ComponentName cn = new ComponentName(
13923                                    ri.activityInfo.packageName, ri.activityInfo.name);
13924                            if (singleUserReceivers == null) {
13925                                singleUserReceivers = new HashSet<ComponentName>();
13926                            }
13927                            if (!singleUserReceivers.contains(cn)) {
13928                                singleUserReceivers.add(cn);
13929                                receivers.add(ri);
13930                            }
13931                        } else {
13932                            receivers.add(ri);
13933                        }
13934                    }
13935                }
13936            }
13937        } catch (RemoteException ex) {
13938            // pm is in same process, this will never happen.
13939        }
13940        return receivers;
13941    }
13942
13943    private final int broadcastIntentLocked(ProcessRecord callerApp,
13944            String callerPackage, Intent intent, String resolvedType,
13945            IIntentReceiver resultTo, int resultCode, String resultData,
13946            Bundle map, String requiredPermission, int appOp,
13947            boolean ordered, boolean sticky, int callingPid, int callingUid,
13948            int userId) {
13949        intent = new Intent(intent);
13950
13951        // By default broadcasts do not go to stopped apps.
13952        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13953
13954        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13955            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13956            + " ordered=" + ordered + " userid=" + userId);
13957        if ((resultTo != null) && !ordered) {
13958            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13959        }
13960
13961        userId = handleIncomingUser(callingPid, callingUid, userId,
13962                true, false, "broadcast", callerPackage);
13963
13964        // Make sure that the user who is receiving this broadcast is started.
13965        // If not, we will just skip it.
13966        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13967            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13968                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13969                Slog.w(TAG, "Skipping broadcast of " + intent
13970                        + ": user " + userId + " is stopped");
13971                return ActivityManager.BROADCAST_SUCCESS;
13972            }
13973        }
13974
13975        /*
13976         * Prevent non-system code (defined here to be non-persistent
13977         * processes) from sending protected broadcasts.
13978         */
13979        int callingAppId = UserHandle.getAppId(callingUid);
13980        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13981                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13982                || callingUid == 0) {
13983            // Always okay.
13984        } else if (callerApp == null || !callerApp.persistent) {
13985            try {
13986                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13987                        intent.getAction())) {
13988                    String msg = "Permission Denial: not allowed to send broadcast "
13989                            + intent.getAction() + " from pid="
13990                            + callingPid + ", uid=" + callingUid;
13991                    Slog.w(TAG, msg);
13992                    throw new SecurityException(msg);
13993                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13994                    // Special case for compatibility: we don't want apps to send this,
13995                    // but historically it has not been protected and apps may be using it
13996                    // to poke their own app widget.  So, instead of making it protected,
13997                    // just limit it to the caller.
13998                    if (callerApp == null) {
13999                        String msg = "Permission Denial: not allowed to send broadcast "
14000                                + intent.getAction() + " from unknown caller.";
14001                        Slog.w(TAG, msg);
14002                        throw new SecurityException(msg);
14003                    } else if (intent.getComponent() != null) {
14004                        // They are good enough to send to an explicit component...  verify
14005                        // it is being sent to the calling app.
14006                        if (!intent.getComponent().getPackageName().equals(
14007                                callerApp.info.packageName)) {
14008                            String msg = "Permission Denial: not allowed to send broadcast "
14009                                    + intent.getAction() + " to "
14010                                    + intent.getComponent().getPackageName() + " from "
14011                                    + callerApp.info.packageName;
14012                            Slog.w(TAG, msg);
14013                            throw new SecurityException(msg);
14014                        }
14015                    } else {
14016                        // Limit broadcast to their own package.
14017                        intent.setPackage(callerApp.info.packageName);
14018                    }
14019                }
14020            } catch (RemoteException e) {
14021                Slog.w(TAG, "Remote exception", e);
14022                return ActivityManager.BROADCAST_SUCCESS;
14023            }
14024        }
14025
14026        // Handle special intents: if this broadcast is from the package
14027        // manager about a package being removed, we need to remove all of
14028        // its activities from the history stack.
14029        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14030                intent.getAction());
14031        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14032                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14033                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14034                || uidRemoved) {
14035            if (checkComponentPermission(
14036                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14037                    callingPid, callingUid, -1, true)
14038                    == PackageManager.PERMISSION_GRANTED) {
14039                if (uidRemoved) {
14040                    final Bundle intentExtras = intent.getExtras();
14041                    final int uid = intentExtras != null
14042                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14043                    if (uid >= 0) {
14044                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14045                        synchronized (bs) {
14046                            bs.removeUidStatsLocked(uid);
14047                        }
14048                        mAppOpsService.uidRemoved(uid);
14049                    }
14050                } else {
14051                    // If resources are unavailable just force stop all
14052                    // those packages and flush the attribute cache as well.
14053                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14054                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14055                        if (list != null && (list.length > 0)) {
14056                            for (String pkg : list) {
14057                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14058                                        "storage unmount");
14059                            }
14060                            sendPackageBroadcastLocked(
14061                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14062                        }
14063                    } else {
14064                        Uri data = intent.getData();
14065                        String ssp;
14066                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14067                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14068                                    intent.getAction());
14069                            boolean fullUninstall = removed &&
14070                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14071                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14072                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14073                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14074                                        false, fullUninstall, userId,
14075                                        removed ? "pkg removed" : "pkg changed");
14076                            }
14077                            if (removed) {
14078                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14079                                        new String[] {ssp}, userId);
14080                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14081                                    mAppOpsService.packageRemoved(
14082                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14083
14084                                    // Remove all permissions granted from/to this package
14085                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14086                                }
14087                            }
14088                        }
14089                    }
14090                }
14091            } else {
14092                String msg = "Permission Denial: " + intent.getAction()
14093                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14094                        + ", uid=" + callingUid + ")"
14095                        + " requires "
14096                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14097                Slog.w(TAG, msg);
14098                throw new SecurityException(msg);
14099            }
14100
14101        // Special case for adding a package: by default turn on compatibility
14102        // mode.
14103        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14104            Uri data = intent.getData();
14105            String ssp;
14106            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14107                mCompatModePackages.handlePackageAddedLocked(ssp,
14108                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14109            }
14110        }
14111
14112        /*
14113         * If this is the time zone changed action, queue up a message that will reset the timezone
14114         * of all currently running processes. This message will get queued up before the broadcast
14115         * happens.
14116         */
14117        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14118            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14119        }
14120
14121        /*
14122         * If the user set the time, let all running processes know.
14123         */
14124        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14125            final int is24Hour = intent.getBooleanExtra(
14126                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14127            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14128        }
14129
14130        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14131            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14132        }
14133
14134        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14135            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14136            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14137        }
14138
14139        // Add to the sticky list if requested.
14140        if (sticky) {
14141            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14142                    callingPid, callingUid)
14143                    != PackageManager.PERMISSION_GRANTED) {
14144                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14145                        + callingPid + ", uid=" + callingUid
14146                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14147                Slog.w(TAG, msg);
14148                throw new SecurityException(msg);
14149            }
14150            if (requiredPermission != null) {
14151                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14152                        + " and enforce permission " + requiredPermission);
14153                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14154            }
14155            if (intent.getComponent() != null) {
14156                throw new SecurityException(
14157                        "Sticky broadcasts can't target a specific component");
14158            }
14159            // We use userId directly here, since the "all" target is maintained
14160            // as a separate set of sticky broadcasts.
14161            if (userId != UserHandle.USER_ALL) {
14162                // But first, if this is not a broadcast to all users, then
14163                // make sure it doesn't conflict with an existing broadcast to
14164                // all users.
14165                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14166                        UserHandle.USER_ALL);
14167                if (stickies != null) {
14168                    ArrayList<Intent> list = stickies.get(intent.getAction());
14169                    if (list != null) {
14170                        int N = list.size();
14171                        int i;
14172                        for (i=0; i<N; i++) {
14173                            if (intent.filterEquals(list.get(i))) {
14174                                throw new IllegalArgumentException(
14175                                        "Sticky broadcast " + intent + " for user "
14176                                        + userId + " conflicts with existing global broadcast");
14177                            }
14178                        }
14179                    }
14180                }
14181            }
14182            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14183            if (stickies == null) {
14184                stickies = new ArrayMap<String, ArrayList<Intent>>();
14185                mStickyBroadcasts.put(userId, stickies);
14186            }
14187            ArrayList<Intent> list = stickies.get(intent.getAction());
14188            if (list == null) {
14189                list = new ArrayList<Intent>();
14190                stickies.put(intent.getAction(), list);
14191            }
14192            int N = list.size();
14193            int i;
14194            for (i=0; i<N; i++) {
14195                if (intent.filterEquals(list.get(i))) {
14196                    // This sticky already exists, replace it.
14197                    list.set(i, new Intent(intent));
14198                    break;
14199                }
14200            }
14201            if (i >= N) {
14202                list.add(new Intent(intent));
14203            }
14204        }
14205
14206        int[] users;
14207        if (userId == UserHandle.USER_ALL) {
14208            // Caller wants broadcast to go to all started users.
14209            users = mStartedUserArray;
14210        } else {
14211            // Caller wants broadcast to go to one specific user.
14212            users = new int[] {userId};
14213        }
14214
14215        // Figure out who all will receive this broadcast.
14216        List receivers = null;
14217        List<BroadcastFilter> registeredReceivers = null;
14218        // Need to resolve the intent to interested receivers...
14219        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14220                 == 0) {
14221            receivers = collectReceiverComponents(intent, resolvedType, users);
14222        }
14223        if (intent.getComponent() == null) {
14224            registeredReceivers = mReceiverResolver.queryIntent(intent,
14225                    resolvedType, false, userId);
14226        }
14227
14228        final boolean replacePending =
14229                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14230
14231        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14232                + " replacePending=" + replacePending);
14233
14234        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14235        if (!ordered && NR > 0) {
14236            // If we are not serializing this broadcast, then send the
14237            // registered receivers separately so they don't wait for the
14238            // components to be launched.
14239            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14240            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14241                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14242                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14243                    ordered, sticky, false, userId);
14244            if (DEBUG_BROADCAST) Slog.v(
14245                    TAG, "Enqueueing parallel broadcast " + r);
14246            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14247            if (!replaced) {
14248                queue.enqueueParallelBroadcastLocked(r);
14249                queue.scheduleBroadcastsLocked();
14250            }
14251            registeredReceivers = null;
14252            NR = 0;
14253        }
14254
14255        // Merge into one list.
14256        int ir = 0;
14257        if (receivers != null) {
14258            // A special case for PACKAGE_ADDED: do not allow the package
14259            // being added to see this broadcast.  This prevents them from
14260            // using this as a back door to get run as soon as they are
14261            // installed.  Maybe in the future we want to have a special install
14262            // broadcast or such for apps, but we'd like to deliberately make
14263            // this decision.
14264            String skipPackages[] = null;
14265            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14266                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14267                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14268                Uri data = intent.getData();
14269                if (data != null) {
14270                    String pkgName = data.getSchemeSpecificPart();
14271                    if (pkgName != null) {
14272                        skipPackages = new String[] { pkgName };
14273                    }
14274                }
14275            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14276                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14277            }
14278            if (skipPackages != null && (skipPackages.length > 0)) {
14279                for (String skipPackage : skipPackages) {
14280                    if (skipPackage != null) {
14281                        int NT = receivers.size();
14282                        for (int it=0; it<NT; it++) {
14283                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14284                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14285                                receivers.remove(it);
14286                                it--;
14287                                NT--;
14288                            }
14289                        }
14290                    }
14291                }
14292            }
14293
14294            int NT = receivers != null ? receivers.size() : 0;
14295            int it = 0;
14296            ResolveInfo curt = null;
14297            BroadcastFilter curr = null;
14298            while (it < NT && ir < NR) {
14299                if (curt == null) {
14300                    curt = (ResolveInfo)receivers.get(it);
14301                }
14302                if (curr == null) {
14303                    curr = registeredReceivers.get(ir);
14304                }
14305                if (curr.getPriority() >= curt.priority) {
14306                    // Insert this broadcast record into the final list.
14307                    receivers.add(it, curr);
14308                    ir++;
14309                    curr = null;
14310                    it++;
14311                    NT++;
14312                } else {
14313                    // Skip to the next ResolveInfo in the final list.
14314                    it++;
14315                    curt = null;
14316                }
14317            }
14318        }
14319        while (ir < NR) {
14320            if (receivers == null) {
14321                receivers = new ArrayList();
14322            }
14323            receivers.add(registeredReceivers.get(ir));
14324            ir++;
14325        }
14326
14327        if ((receivers != null && receivers.size() > 0)
14328                || resultTo != null) {
14329            BroadcastQueue queue = broadcastQueueForIntent(intent);
14330            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14331                    callerPackage, callingPid, callingUid, resolvedType,
14332                    requiredPermission, appOp, receivers, resultTo, resultCode,
14333                    resultData, map, ordered, sticky, false, userId);
14334            if (DEBUG_BROADCAST) Slog.v(
14335                    TAG, "Enqueueing ordered broadcast " + r
14336                    + ": prev had " + queue.mOrderedBroadcasts.size());
14337            if (DEBUG_BROADCAST) {
14338                int seq = r.intent.getIntExtra("seq", -1);
14339                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14340            }
14341            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14342            if (!replaced) {
14343                queue.enqueueOrderedBroadcastLocked(r);
14344                queue.scheduleBroadcastsLocked();
14345            }
14346        }
14347
14348        return ActivityManager.BROADCAST_SUCCESS;
14349    }
14350
14351    final Intent verifyBroadcastLocked(Intent intent) {
14352        // Refuse possible leaked file descriptors
14353        if (intent != null && intent.hasFileDescriptors() == true) {
14354            throw new IllegalArgumentException("File descriptors passed in Intent");
14355        }
14356
14357        int flags = intent.getFlags();
14358
14359        if (!mProcessesReady) {
14360            // if the caller really truly claims to know what they're doing, go
14361            // ahead and allow the broadcast without launching any receivers
14362            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14363                intent = new Intent(intent);
14364                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14365            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14366                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14367                        + " before boot completion");
14368                throw new IllegalStateException("Cannot broadcast before boot completed");
14369            }
14370        }
14371
14372        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14373            throw new IllegalArgumentException(
14374                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14375        }
14376
14377        return intent;
14378    }
14379
14380    public final int broadcastIntent(IApplicationThread caller,
14381            Intent intent, String resolvedType, IIntentReceiver resultTo,
14382            int resultCode, String resultData, Bundle map,
14383            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14384        enforceNotIsolatedCaller("broadcastIntent");
14385        synchronized(this) {
14386            intent = verifyBroadcastLocked(intent);
14387
14388            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14389            final int callingPid = Binder.getCallingPid();
14390            final int callingUid = Binder.getCallingUid();
14391            final long origId = Binder.clearCallingIdentity();
14392            int res = broadcastIntentLocked(callerApp,
14393                    callerApp != null ? callerApp.info.packageName : null,
14394                    intent, resolvedType, resultTo,
14395                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14396                    callingPid, callingUid, userId);
14397            Binder.restoreCallingIdentity(origId);
14398            return res;
14399        }
14400    }
14401
14402    int broadcastIntentInPackage(String packageName, int uid,
14403            Intent intent, String resolvedType, IIntentReceiver resultTo,
14404            int resultCode, String resultData, Bundle map,
14405            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14406        synchronized(this) {
14407            intent = verifyBroadcastLocked(intent);
14408
14409            final long origId = Binder.clearCallingIdentity();
14410            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14411                    resultTo, resultCode, resultData, map, requiredPermission,
14412                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14413            Binder.restoreCallingIdentity(origId);
14414            return res;
14415        }
14416    }
14417
14418    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14419        // Refuse possible leaked file descriptors
14420        if (intent != null && intent.hasFileDescriptors() == true) {
14421            throw new IllegalArgumentException("File descriptors passed in Intent");
14422        }
14423
14424        userId = handleIncomingUser(Binder.getCallingPid(),
14425                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14426
14427        synchronized(this) {
14428            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14429                    != PackageManager.PERMISSION_GRANTED) {
14430                String msg = "Permission Denial: unbroadcastIntent() from pid="
14431                        + Binder.getCallingPid()
14432                        + ", uid=" + Binder.getCallingUid()
14433                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14434                Slog.w(TAG, msg);
14435                throw new SecurityException(msg);
14436            }
14437            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14438            if (stickies != null) {
14439                ArrayList<Intent> list = stickies.get(intent.getAction());
14440                if (list != null) {
14441                    int N = list.size();
14442                    int i;
14443                    for (i=0; i<N; i++) {
14444                        if (intent.filterEquals(list.get(i))) {
14445                            list.remove(i);
14446                            break;
14447                        }
14448                    }
14449                    if (list.size() <= 0) {
14450                        stickies.remove(intent.getAction());
14451                    }
14452                }
14453                if (stickies.size() <= 0) {
14454                    mStickyBroadcasts.remove(userId);
14455                }
14456            }
14457        }
14458    }
14459
14460    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14461            String resultData, Bundle resultExtras, boolean resultAbort) {
14462        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14463        if (r == null) {
14464            Slog.w(TAG, "finishReceiver called but not found on queue");
14465            return false;
14466        }
14467
14468        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14469    }
14470
14471    void backgroundServicesFinishedLocked(int userId) {
14472        for (BroadcastQueue queue : mBroadcastQueues) {
14473            queue.backgroundServicesFinishedLocked(userId);
14474        }
14475    }
14476
14477    public void finishReceiver(IBinder who, int resultCode, String resultData,
14478            Bundle resultExtras, boolean resultAbort) {
14479        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14480
14481        // Refuse possible leaked file descriptors
14482        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14483            throw new IllegalArgumentException("File descriptors passed in Bundle");
14484        }
14485
14486        final long origId = Binder.clearCallingIdentity();
14487        try {
14488            boolean doNext = false;
14489            BroadcastRecord r;
14490
14491            synchronized(this) {
14492                r = broadcastRecordForReceiverLocked(who);
14493                if (r != null) {
14494                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14495                        resultData, resultExtras, resultAbort, true);
14496                }
14497            }
14498
14499            if (doNext) {
14500                r.queue.processNextBroadcast(false);
14501            }
14502            trimApplications();
14503        } finally {
14504            Binder.restoreCallingIdentity(origId);
14505        }
14506    }
14507
14508    // =========================================================
14509    // INSTRUMENTATION
14510    // =========================================================
14511
14512    public boolean startInstrumentation(ComponentName className,
14513            String profileFile, int flags, Bundle arguments,
14514            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14515            int userId, String abiOverride) {
14516        enforceNotIsolatedCaller("startInstrumentation");
14517        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14518                userId, false, true, "startInstrumentation", null);
14519        // Refuse possible leaked file descriptors
14520        if (arguments != null && arguments.hasFileDescriptors()) {
14521            throw new IllegalArgumentException("File descriptors passed in Bundle");
14522        }
14523
14524        synchronized(this) {
14525            InstrumentationInfo ii = null;
14526            ApplicationInfo ai = null;
14527            try {
14528                ii = mContext.getPackageManager().getInstrumentationInfo(
14529                    className, STOCK_PM_FLAGS);
14530                ai = AppGlobals.getPackageManager().getApplicationInfo(
14531                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14532            } catch (PackageManager.NameNotFoundException e) {
14533            } catch (RemoteException e) {
14534            }
14535            if (ii == null) {
14536                reportStartInstrumentationFailure(watcher, className,
14537                        "Unable to find instrumentation info for: " + className);
14538                return false;
14539            }
14540            if (ai == null) {
14541                reportStartInstrumentationFailure(watcher, className,
14542                        "Unable to find instrumentation target package: " + ii.targetPackage);
14543                return false;
14544            }
14545
14546            int match = mContext.getPackageManager().checkSignatures(
14547                    ii.targetPackage, ii.packageName);
14548            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14549                String msg = "Permission Denial: starting instrumentation "
14550                        + className + " from pid="
14551                        + Binder.getCallingPid()
14552                        + ", uid=" + Binder.getCallingPid()
14553                        + " not allowed because package " + ii.packageName
14554                        + " does not have a signature matching the target "
14555                        + ii.targetPackage;
14556                reportStartInstrumentationFailure(watcher, className, msg);
14557                throw new SecurityException(msg);
14558            }
14559
14560            final long origId = Binder.clearCallingIdentity();
14561            // Instrumentation can kill and relaunch even persistent processes
14562            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14563                    "start instr");
14564            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14565            app.instrumentationClass = className;
14566            app.instrumentationInfo = ai;
14567            app.instrumentationProfileFile = profileFile;
14568            app.instrumentationArguments = arguments;
14569            app.instrumentationWatcher = watcher;
14570            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14571            app.instrumentationResultClass = className;
14572            Binder.restoreCallingIdentity(origId);
14573        }
14574
14575        return true;
14576    }
14577
14578    /**
14579     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14580     * error to the logs, but if somebody is watching, send the report there too.  This enables
14581     * the "am" command to report errors with more information.
14582     *
14583     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14584     * @param cn The component name of the instrumentation.
14585     * @param report The error report.
14586     */
14587    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14588            ComponentName cn, String report) {
14589        Slog.w(TAG, report);
14590        try {
14591            if (watcher != null) {
14592                Bundle results = new Bundle();
14593                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14594                results.putString("Error", report);
14595                watcher.instrumentationStatus(cn, -1, results);
14596            }
14597        } catch (RemoteException e) {
14598            Slog.w(TAG, e);
14599        }
14600    }
14601
14602    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14603        if (app.instrumentationWatcher != null) {
14604            try {
14605                // NOTE:  IInstrumentationWatcher *must* be oneway here
14606                app.instrumentationWatcher.instrumentationFinished(
14607                    app.instrumentationClass,
14608                    resultCode,
14609                    results);
14610            } catch (RemoteException e) {
14611            }
14612        }
14613        if (app.instrumentationUiAutomationConnection != null) {
14614            try {
14615                app.instrumentationUiAutomationConnection.shutdown();
14616            } catch (RemoteException re) {
14617                /* ignore */
14618            }
14619            // Only a UiAutomation can set this flag and now that
14620            // it is finished we make sure it is reset to its default.
14621            mUserIsMonkey = false;
14622        }
14623        app.instrumentationWatcher = null;
14624        app.instrumentationUiAutomationConnection = null;
14625        app.instrumentationClass = null;
14626        app.instrumentationInfo = null;
14627        app.instrumentationProfileFile = null;
14628        app.instrumentationArguments = null;
14629
14630        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14631                "finished inst");
14632    }
14633
14634    public void finishInstrumentation(IApplicationThread target,
14635            int resultCode, Bundle results) {
14636        int userId = UserHandle.getCallingUserId();
14637        // Refuse possible leaked file descriptors
14638        if (results != null && results.hasFileDescriptors()) {
14639            throw new IllegalArgumentException("File descriptors passed in Intent");
14640        }
14641
14642        synchronized(this) {
14643            ProcessRecord app = getRecordForAppLocked(target);
14644            if (app == null) {
14645                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14646                return;
14647            }
14648            final long origId = Binder.clearCallingIdentity();
14649            finishInstrumentationLocked(app, resultCode, results);
14650            Binder.restoreCallingIdentity(origId);
14651        }
14652    }
14653
14654    // =========================================================
14655    // CONFIGURATION
14656    // =========================================================
14657
14658    public ConfigurationInfo getDeviceConfigurationInfo() {
14659        ConfigurationInfo config = new ConfigurationInfo();
14660        synchronized (this) {
14661            config.reqTouchScreen = mConfiguration.touchscreen;
14662            config.reqKeyboardType = mConfiguration.keyboard;
14663            config.reqNavigation = mConfiguration.navigation;
14664            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14665                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14666                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14667            }
14668            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14669                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14670                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14671            }
14672            config.reqGlEsVersion = GL_ES_VERSION;
14673        }
14674        return config;
14675    }
14676
14677    ActivityStack getFocusedStack() {
14678        return mStackSupervisor.getFocusedStack();
14679    }
14680
14681    public Configuration getConfiguration() {
14682        Configuration ci;
14683        synchronized(this) {
14684            ci = new Configuration(mConfiguration);
14685        }
14686        return ci;
14687    }
14688
14689    public void updatePersistentConfiguration(Configuration values) {
14690        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14691                "updateConfiguration()");
14692        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14693                "updateConfiguration()");
14694        if (values == null) {
14695            throw new NullPointerException("Configuration must not be null");
14696        }
14697
14698        synchronized(this) {
14699            final long origId = Binder.clearCallingIdentity();
14700            updateConfigurationLocked(values, null, true, false);
14701            Binder.restoreCallingIdentity(origId);
14702        }
14703    }
14704
14705    public void updateConfiguration(Configuration values) {
14706        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14707                "updateConfiguration()");
14708
14709        synchronized(this) {
14710            if (values == null && mWindowManager != null) {
14711                // sentinel: fetch the current configuration from the window manager
14712                values = mWindowManager.computeNewConfiguration();
14713            }
14714
14715            if (mWindowManager != null) {
14716                mProcessList.applyDisplaySize(mWindowManager);
14717            }
14718
14719            final long origId = Binder.clearCallingIdentity();
14720            if (values != null) {
14721                Settings.System.clearConfiguration(values);
14722            }
14723            updateConfigurationLocked(values, null, false, false);
14724            Binder.restoreCallingIdentity(origId);
14725        }
14726    }
14727
14728    /**
14729     * Do either or both things: (1) change the current configuration, and (2)
14730     * make sure the given activity is running with the (now) current
14731     * configuration.  Returns true if the activity has been left running, or
14732     * false if <var>starting</var> is being destroyed to match the new
14733     * configuration.
14734     * @param persistent TODO
14735     */
14736    boolean updateConfigurationLocked(Configuration values,
14737            ActivityRecord starting, boolean persistent, boolean initLocale) {
14738        int changes = 0;
14739
14740        if (values != null) {
14741            Configuration newConfig = new Configuration(mConfiguration);
14742            changes = newConfig.updateFrom(values);
14743            if (changes != 0) {
14744                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14745                    Slog.i(TAG, "Updating configuration to: " + values);
14746                }
14747
14748                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14749
14750                if (values.locale != null && !initLocale) {
14751                    saveLocaleLocked(values.locale,
14752                                     !values.locale.equals(mConfiguration.locale),
14753                                     values.userSetLocale);
14754                }
14755
14756                mConfigurationSeq++;
14757                if (mConfigurationSeq <= 0) {
14758                    mConfigurationSeq = 1;
14759                }
14760                newConfig.seq = mConfigurationSeq;
14761                mConfiguration = newConfig;
14762                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14763                mUsageStatsService.noteStartConfig(newConfig);
14764
14765                final Configuration configCopy = new Configuration(mConfiguration);
14766
14767                // TODO: If our config changes, should we auto dismiss any currently
14768                // showing dialogs?
14769                mShowDialogs = shouldShowDialogs(newConfig);
14770
14771                AttributeCache ac = AttributeCache.instance();
14772                if (ac != null) {
14773                    ac.updateConfiguration(configCopy);
14774                }
14775
14776                // Make sure all resources in our process are updated
14777                // right now, so that anyone who is going to retrieve
14778                // resource values after we return will be sure to get
14779                // the new ones.  This is especially important during
14780                // boot, where the first config change needs to guarantee
14781                // all resources have that config before following boot
14782                // code is executed.
14783                mSystemThread.applyConfigurationToResources(configCopy);
14784
14785                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14786                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14787                    msg.obj = new Configuration(configCopy);
14788                    mHandler.sendMessage(msg);
14789                }
14790
14791                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14792                    ProcessRecord app = mLruProcesses.get(i);
14793                    try {
14794                        if (app.thread != null) {
14795                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14796                                    + app.processName + " new config " + mConfiguration);
14797                            app.thread.scheduleConfigurationChanged(configCopy);
14798                        }
14799                    } catch (Exception e) {
14800                    }
14801                }
14802                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14803                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14804                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14805                        | Intent.FLAG_RECEIVER_FOREGROUND);
14806                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14807                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14808                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14809                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14810                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14811                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14812                    broadcastIntentLocked(null, null, intent,
14813                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14814                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14815                }
14816            }
14817        }
14818
14819        boolean kept = true;
14820        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14821        // mainStack is null during startup.
14822        if (mainStack != null) {
14823            if (changes != 0 && starting == null) {
14824                // If the configuration changed, and the caller is not already
14825                // in the process of starting an activity, then find the top
14826                // activity to check if its configuration needs to change.
14827                starting = mainStack.topRunningActivityLocked(null);
14828            }
14829
14830            if (starting != null) {
14831                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14832                // And we need to make sure at this point that all other activities
14833                // are made visible with the correct configuration.
14834                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14835            }
14836        }
14837
14838        if (values != null && mWindowManager != null) {
14839            mWindowManager.setNewConfiguration(mConfiguration);
14840        }
14841
14842        return kept;
14843    }
14844
14845    /**
14846     * Decide based on the configuration whether we should shouw the ANR,
14847     * crash, etc dialogs.  The idea is that if there is no affordnace to
14848     * press the on-screen buttons, we shouldn't show the dialog.
14849     *
14850     * A thought: SystemUI might also want to get told about this, the Power
14851     * dialog / global actions also might want different behaviors.
14852     */
14853    private static final boolean shouldShowDialogs(Configuration config) {
14854        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14855                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14856    }
14857
14858    /**
14859     * Save the locale.  You must be inside a synchronized (this) block.
14860     */
14861    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14862        if(isDiff) {
14863            SystemProperties.set("user.language", l.getLanguage());
14864            SystemProperties.set("user.region", l.getCountry());
14865        }
14866
14867        if(isPersist) {
14868            SystemProperties.set("persist.sys.language", l.getLanguage());
14869            SystemProperties.set("persist.sys.country", l.getCountry());
14870            SystemProperties.set("persist.sys.localevar", l.getVariant());
14871        }
14872    }
14873
14874    @Override
14875    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14876        ActivityRecord srec = ActivityRecord.forToken(token);
14877        return srec != null && srec.task.affinity != null &&
14878                srec.task.affinity.equals(destAffinity);
14879    }
14880
14881    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14882            Intent resultData) {
14883
14884        synchronized (this) {
14885            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14886            if (stack != null) {
14887                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14888            }
14889            return false;
14890        }
14891    }
14892
14893    public int getLaunchedFromUid(IBinder activityToken) {
14894        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14895        if (srec == null) {
14896            return -1;
14897        }
14898        return srec.launchedFromUid;
14899    }
14900
14901    public String getLaunchedFromPackage(IBinder activityToken) {
14902        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14903        if (srec == null) {
14904            return null;
14905        }
14906        return srec.launchedFromPackage;
14907    }
14908
14909    // =========================================================
14910    // LIFETIME MANAGEMENT
14911    // =========================================================
14912
14913    // Returns which broadcast queue the app is the current [or imminent] receiver
14914    // on, or 'null' if the app is not an active broadcast recipient.
14915    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14916        BroadcastRecord r = app.curReceiver;
14917        if (r != null) {
14918            return r.queue;
14919        }
14920
14921        // It's not the current receiver, but it might be starting up to become one
14922        synchronized (this) {
14923            for (BroadcastQueue queue : mBroadcastQueues) {
14924                r = queue.mPendingBroadcast;
14925                if (r != null && r.curApp == app) {
14926                    // found it; report which queue it's in
14927                    return queue;
14928                }
14929            }
14930        }
14931
14932        return null;
14933    }
14934
14935    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14936            boolean doingAll, long now) {
14937        if (mAdjSeq == app.adjSeq) {
14938            // This adjustment has already been computed.
14939            return app.curRawAdj;
14940        }
14941
14942        if (app.thread == null) {
14943            app.adjSeq = mAdjSeq;
14944            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14945            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14946            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14947        }
14948
14949        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14950        app.adjSource = null;
14951        app.adjTarget = null;
14952        app.empty = false;
14953        app.cached = false;
14954
14955        final int activitiesSize = app.activities.size();
14956
14957        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14958            // The max adjustment doesn't allow this app to be anything
14959            // below foreground, so it is not worth doing work for it.
14960            app.adjType = "fixed";
14961            app.adjSeq = mAdjSeq;
14962            app.curRawAdj = app.maxAdj;
14963            app.foregroundActivities = false;
14964            app.keeping = true;
14965            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14966            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14967            // System processes can do UI, and when they do we want to have
14968            // them trim their memory after the user leaves the UI.  To
14969            // facilitate this, here we need to determine whether or not it
14970            // is currently showing UI.
14971            app.systemNoUi = true;
14972            if (app == TOP_APP) {
14973                app.systemNoUi = false;
14974            } else if (activitiesSize > 0) {
14975                for (int j = 0; j < activitiesSize; j++) {
14976                    final ActivityRecord r = app.activities.get(j);
14977                    if (r.visible) {
14978                        app.systemNoUi = false;
14979                    }
14980                }
14981            }
14982            if (!app.systemNoUi) {
14983                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14984            }
14985            return (app.curAdj=app.maxAdj);
14986        }
14987
14988        app.keeping = false;
14989        app.systemNoUi = false;
14990
14991        // Determine the importance of the process, starting with most
14992        // important to least, and assign an appropriate OOM adjustment.
14993        int adj;
14994        int schedGroup;
14995        int procState;
14996        boolean foregroundActivities = false;
14997        boolean interesting = false;
14998        BroadcastQueue queue;
14999        if (app == TOP_APP) {
15000            // The last app on the list is the foreground app.
15001            adj = ProcessList.FOREGROUND_APP_ADJ;
15002            schedGroup = Process.THREAD_GROUP_DEFAULT;
15003            app.adjType = "top-activity";
15004            foregroundActivities = true;
15005            interesting = true;
15006            procState = ActivityManager.PROCESS_STATE_TOP;
15007        } else if (app.instrumentationClass != null) {
15008            // Don't want to kill running instrumentation.
15009            adj = ProcessList.FOREGROUND_APP_ADJ;
15010            schedGroup = Process.THREAD_GROUP_DEFAULT;
15011            app.adjType = "instrumentation";
15012            interesting = true;
15013            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15014        } else if ((queue = isReceivingBroadcast(app)) != null) {
15015            // An app that is currently receiving a broadcast also
15016            // counts as being in the foreground for OOM killer purposes.
15017            // It's placed in a sched group based on the nature of the
15018            // broadcast as reflected by which queue it's active in.
15019            adj = ProcessList.FOREGROUND_APP_ADJ;
15020            schedGroup = (queue == mFgBroadcastQueue)
15021                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15022            app.adjType = "broadcast";
15023            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15024        } else if (app.executingServices.size() > 0) {
15025            // An app that is currently executing a service callback also
15026            // counts as being in the foreground.
15027            adj = ProcessList.FOREGROUND_APP_ADJ;
15028            schedGroup = app.execServicesFg ?
15029                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15030            app.adjType = "exec-service";
15031            procState = ActivityManager.PROCESS_STATE_SERVICE;
15032            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15033        } else {
15034            // As far as we know the process is empty.  We may change our mind later.
15035            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15036            // At this point we don't actually know the adjustment.  Use the cached adj
15037            // value that the caller wants us to.
15038            adj = cachedAdj;
15039            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15040            app.cached = true;
15041            app.empty = true;
15042            app.adjType = "cch-empty";
15043        }
15044
15045        // Examine all activities if not already foreground.
15046        if (!foregroundActivities && activitiesSize > 0) {
15047            for (int j = 0; j < activitiesSize; j++) {
15048                final ActivityRecord r = app.activities.get(j);
15049                if (r.app != app) {
15050                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15051                            + app + "?!?");
15052                    continue;
15053                }
15054                if (r.visible) {
15055                    // App has a visible activity; only upgrade adjustment.
15056                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15057                        adj = ProcessList.VISIBLE_APP_ADJ;
15058                        app.adjType = "visible";
15059                    }
15060                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15061                        procState = ActivityManager.PROCESS_STATE_TOP;
15062                    }
15063                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15064                    app.cached = false;
15065                    app.empty = false;
15066                    foregroundActivities = true;
15067                    break;
15068                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15069                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15070                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15071                        app.adjType = "pausing";
15072                    }
15073                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15074                        procState = ActivityManager.PROCESS_STATE_TOP;
15075                    }
15076                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15077                    app.cached = false;
15078                    app.empty = false;
15079                    foregroundActivities = true;
15080                } else if (r.state == ActivityState.STOPPING) {
15081                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15082                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15083                        app.adjType = "stopping";
15084                    }
15085                    // For the process state, we will at this point consider the
15086                    // process to be cached.  It will be cached either as an activity
15087                    // or empty depending on whether the activity is finishing.  We do
15088                    // this so that we can treat the process as cached for purposes of
15089                    // memory trimming (determing current memory level, trim command to
15090                    // send to process) since there can be an arbitrary number of stopping
15091                    // processes and they should soon all go into the cached state.
15092                    if (!r.finishing) {
15093                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15094                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15095                        }
15096                    }
15097                    app.cached = false;
15098                    app.empty = false;
15099                    foregroundActivities = true;
15100                } else {
15101                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15102                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15103                        app.adjType = "cch-act";
15104                    }
15105                }
15106            }
15107        }
15108
15109        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15110            if (app.foregroundServices) {
15111                // The user is aware of this app, so make it visible.
15112                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15113                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15114                app.cached = false;
15115                app.adjType = "fg-service";
15116                schedGroup = Process.THREAD_GROUP_DEFAULT;
15117            } else if (app.forcingToForeground != null) {
15118                // The user is aware of this app, so make it visible.
15119                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15120                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15121                app.cached = false;
15122                app.adjType = "force-fg";
15123                app.adjSource = app.forcingToForeground;
15124                schedGroup = Process.THREAD_GROUP_DEFAULT;
15125            }
15126        }
15127
15128        if (app.foregroundServices) {
15129            interesting = true;
15130        }
15131
15132        if (app == mHeavyWeightProcess) {
15133            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15134                // We don't want to kill the current heavy-weight process.
15135                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15136                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15137                app.cached = false;
15138                app.adjType = "heavy";
15139            }
15140            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15141                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15142            }
15143        }
15144
15145        if (app == mHomeProcess) {
15146            if (adj > ProcessList.HOME_APP_ADJ) {
15147                // This process is hosting what we currently consider to be the
15148                // home app, so we don't want to let it go into the background.
15149                adj = ProcessList.HOME_APP_ADJ;
15150                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15151                app.cached = false;
15152                app.adjType = "home";
15153            }
15154            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15155                procState = ActivityManager.PROCESS_STATE_HOME;
15156            }
15157        }
15158
15159        if (app == mPreviousProcess && app.activities.size() > 0) {
15160            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15161                // This was the previous process that showed UI to the user.
15162                // We want to try to keep it around more aggressively, to give
15163                // a good experience around switching between two apps.
15164                adj = ProcessList.PREVIOUS_APP_ADJ;
15165                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15166                app.cached = false;
15167                app.adjType = "previous";
15168            }
15169            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15170                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15171            }
15172        }
15173
15174        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15175                + " reason=" + app.adjType);
15176
15177        // By default, we use the computed adjustment.  It may be changed if
15178        // there are applications dependent on our services or providers, but
15179        // this gives us a baseline and makes sure we don't get into an
15180        // infinite recursion.
15181        app.adjSeq = mAdjSeq;
15182        app.curRawAdj = adj;
15183        app.hasStartedServices = false;
15184
15185        if (mBackupTarget != null && app == mBackupTarget.app) {
15186            // If possible we want to avoid killing apps while they're being backed up
15187            if (adj > ProcessList.BACKUP_APP_ADJ) {
15188                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15189                adj = ProcessList.BACKUP_APP_ADJ;
15190                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15191                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15192                }
15193                app.adjType = "backup";
15194                app.cached = false;
15195            }
15196            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15197                procState = ActivityManager.PROCESS_STATE_BACKUP;
15198            }
15199        }
15200
15201        boolean mayBeTop = false;
15202
15203        for (int is = app.services.size()-1;
15204                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15205                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15206                        || procState > ActivityManager.PROCESS_STATE_TOP);
15207                is--) {
15208            ServiceRecord s = app.services.valueAt(is);
15209            if (s.startRequested) {
15210                app.hasStartedServices = true;
15211                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15212                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15213                }
15214                if (app.hasShownUi && app != mHomeProcess) {
15215                    // If this process has shown some UI, let it immediately
15216                    // go to the LRU list because it may be pretty heavy with
15217                    // UI stuff.  We'll tag it with a label just to help
15218                    // debug and understand what is going on.
15219                    if (adj > ProcessList.SERVICE_ADJ) {
15220                        app.adjType = "cch-started-ui-services";
15221                    }
15222                } else {
15223                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15224                        // This service has seen some activity within
15225                        // recent memory, so we will keep its process ahead
15226                        // of the background processes.
15227                        if (adj > ProcessList.SERVICE_ADJ) {
15228                            adj = ProcessList.SERVICE_ADJ;
15229                            app.adjType = "started-services";
15230                            app.cached = false;
15231                        }
15232                    }
15233                    // If we have let the service slide into the background
15234                    // state, still have some text describing what it is doing
15235                    // even though the service no longer has an impact.
15236                    if (adj > ProcessList.SERVICE_ADJ) {
15237                        app.adjType = "cch-started-services";
15238                    }
15239                }
15240                // Don't kill this process because it is doing work; it
15241                // has said it is doing work.
15242                app.keeping = true;
15243            }
15244            for (int conni = s.connections.size()-1;
15245                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15246                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15247                            || procState > ActivityManager.PROCESS_STATE_TOP);
15248                    conni--) {
15249                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15250                for (int i = 0;
15251                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15252                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15253                                || procState > ActivityManager.PROCESS_STATE_TOP);
15254                        i++) {
15255                    // XXX should compute this based on the max of
15256                    // all connected clients.
15257                    ConnectionRecord cr = clist.get(i);
15258                    if (cr.binding.client == app) {
15259                        // Binding to ourself is not interesting.
15260                        continue;
15261                    }
15262                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15263                        ProcessRecord client = cr.binding.client;
15264                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15265                                TOP_APP, doingAll, now);
15266                        int clientProcState = client.curProcState;
15267                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15268                            // If the other app is cached for any reason, for purposes here
15269                            // we are going to consider it empty.  The specific cached state
15270                            // doesn't propagate except under certain conditions.
15271                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15272                        }
15273                        String adjType = null;
15274                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15275                            // Not doing bind OOM management, so treat
15276                            // this guy more like a started service.
15277                            if (app.hasShownUi && app != mHomeProcess) {
15278                                // If this process has shown some UI, let it immediately
15279                                // go to the LRU list because it may be pretty heavy with
15280                                // UI stuff.  We'll tag it with a label just to help
15281                                // debug and understand what is going on.
15282                                if (adj > clientAdj) {
15283                                    adjType = "cch-bound-ui-services";
15284                                }
15285                                app.cached = false;
15286                                clientAdj = adj;
15287                                clientProcState = procState;
15288                            } else {
15289                                if (now >= (s.lastActivity
15290                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15291                                    // This service has not seen activity within
15292                                    // recent memory, so allow it to drop to the
15293                                    // LRU list if there is no other reason to keep
15294                                    // it around.  We'll also tag it with a label just
15295                                    // to help debug and undertand what is going on.
15296                                    if (adj > clientAdj) {
15297                                        adjType = "cch-bound-services";
15298                                    }
15299                                    clientAdj = adj;
15300                                }
15301                            }
15302                        }
15303                        if (adj > clientAdj) {
15304                            // If this process has recently shown UI, and
15305                            // the process that is binding to it is less
15306                            // important than being visible, then we don't
15307                            // care about the binding as much as we care
15308                            // about letting this process get into the LRU
15309                            // list to be killed and restarted if needed for
15310                            // memory.
15311                            if (app.hasShownUi && app != mHomeProcess
15312                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15313                                adjType = "cch-bound-ui-services";
15314                            } else {
15315                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15316                                        |Context.BIND_IMPORTANT)) != 0) {
15317                                    adj = clientAdj;
15318                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15319                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15320                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15321                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15322                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15323                                    adj = clientAdj;
15324                                } else {
15325                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15326                                        adj = ProcessList.VISIBLE_APP_ADJ;
15327                                    }
15328                                }
15329                                if (!client.cached) {
15330                                    app.cached = false;
15331                                }
15332                                if (client.keeping) {
15333                                    app.keeping = true;
15334                                }
15335                                adjType = "service";
15336                            }
15337                        }
15338                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15339                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15340                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15341                            }
15342                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15343                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15344                                    // Special handling of clients who are in the top state.
15345                                    // We *may* want to consider this process to be in the
15346                                    // top state as well, but only if there is not another
15347                                    // reason for it to be running.  Being on the top is a
15348                                    // special state, meaning you are specifically running
15349                                    // for the current top app.  If the process is already
15350                                    // running in the background for some other reason, it
15351                                    // is more important to continue considering it to be
15352                                    // in the background state.
15353                                    mayBeTop = true;
15354                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15355                                } else {
15356                                    // Special handling for above-top states (persistent
15357                                    // processes).  These should not bring the current process
15358                                    // into the top state, since they are not on top.  Instead
15359                                    // give them the best state after that.
15360                                    clientProcState =
15361                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15362                                }
15363                            }
15364                        } else {
15365                            if (clientProcState <
15366                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15367                                clientProcState =
15368                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15369                            }
15370                        }
15371                        if (procState > clientProcState) {
15372                            procState = clientProcState;
15373                        }
15374                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15375                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15376                            app.pendingUiClean = true;
15377                        }
15378                        if (adjType != null) {
15379                            app.adjType = adjType;
15380                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15381                                    .REASON_SERVICE_IN_USE;
15382                            app.adjSource = cr.binding.client;
15383                            app.adjSourceOom = clientAdj;
15384                            app.adjTarget = s.name;
15385                        }
15386                    }
15387                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15388                        app.treatLikeActivity = true;
15389                    }
15390                    final ActivityRecord a = cr.activity;
15391                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15392                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15393                                (a.visible || a.state == ActivityState.RESUMED
15394                                 || a.state == ActivityState.PAUSING)) {
15395                            adj = ProcessList.FOREGROUND_APP_ADJ;
15396                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15397                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15398                            }
15399                            app.cached = false;
15400                            app.adjType = "service";
15401                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15402                                    .REASON_SERVICE_IN_USE;
15403                            app.adjSource = a;
15404                            app.adjSourceOom = adj;
15405                            app.adjTarget = s.name;
15406                        }
15407                    }
15408                }
15409            }
15410        }
15411
15412        for (int provi = app.pubProviders.size()-1;
15413                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15414                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15415                        || procState > ActivityManager.PROCESS_STATE_TOP);
15416                provi--) {
15417            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15418            for (int i = cpr.connections.size()-1;
15419                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15420                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15421                            || procState > ActivityManager.PROCESS_STATE_TOP);
15422                    i--) {
15423                ContentProviderConnection conn = cpr.connections.get(i);
15424                ProcessRecord client = conn.client;
15425                if (client == app) {
15426                    // Being our own client is not interesting.
15427                    continue;
15428                }
15429                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15430                int clientProcState = client.curProcState;
15431                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15432                    // If the other app is cached for any reason, for purposes here
15433                    // we are going to consider it empty.
15434                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15435                }
15436                if (adj > clientAdj) {
15437                    if (app.hasShownUi && app != mHomeProcess
15438                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15439                        app.adjType = "cch-ui-provider";
15440                    } else {
15441                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15442                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15443                        app.adjType = "provider";
15444                    }
15445                    app.cached &= client.cached;
15446                    app.keeping |= client.keeping;
15447                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15448                            .REASON_PROVIDER_IN_USE;
15449                    app.adjSource = client;
15450                    app.adjSourceOom = clientAdj;
15451                    app.adjTarget = cpr.name;
15452                }
15453                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15454                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15455                        // Special handling of clients who are in the top state.
15456                        // We *may* want to consider this process to be in the
15457                        // top state as well, but only if there is not another
15458                        // reason for it to be running.  Being on the top is a
15459                        // special state, meaning you are specifically running
15460                        // for the current top app.  If the process is already
15461                        // running in the background for some other reason, it
15462                        // is more important to continue considering it to be
15463                        // in the background state.
15464                        mayBeTop = true;
15465                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15466                    } else {
15467                        // Special handling for above-top states (persistent
15468                        // processes).  These should not bring the current process
15469                        // into the top state, since they are not on top.  Instead
15470                        // give them the best state after that.
15471                        clientProcState =
15472                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15473                    }
15474                }
15475                if (procState > clientProcState) {
15476                    procState = clientProcState;
15477                }
15478                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15479                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15480                }
15481            }
15482            // If the provider has external (non-framework) process
15483            // dependencies, ensure that its adjustment is at least
15484            // FOREGROUND_APP_ADJ.
15485            if (cpr.hasExternalProcessHandles()) {
15486                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15487                    adj = ProcessList.FOREGROUND_APP_ADJ;
15488                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15489                    app.cached = false;
15490                    app.keeping = true;
15491                    app.adjType = "provider";
15492                    app.adjTarget = cpr.name;
15493                }
15494                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15495                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15496                }
15497            }
15498        }
15499
15500        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15501            // A client of one of our services or providers is in the top state.  We
15502            // *may* want to be in the top state, but not if we are already running in
15503            // the background for some other reason.  For the decision here, we are going
15504            // to pick out a few specific states that we want to remain in when a client
15505            // is top (states that tend to be longer-term) and otherwise allow it to go
15506            // to the top state.
15507            switch (procState) {
15508                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15509                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15510                case ActivityManager.PROCESS_STATE_SERVICE:
15511                    // These all are longer-term states, so pull them up to the top
15512                    // of the background states, but not all the way to the top state.
15513                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15514                    break;
15515                default:
15516                    // Otherwise, top is a better choice, so take it.
15517                    procState = ActivityManager.PROCESS_STATE_TOP;
15518                    break;
15519            }
15520        }
15521
15522        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15523            if (app.hasClientActivities) {
15524                // This is a cached process, but with client activities.  Mark it so.
15525                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15526                app.adjType = "cch-client-act";
15527            } else if (app.treatLikeActivity) {
15528                // This is a cached process, but somebody wants us to treat it like it has
15529                // an activity, okay!
15530                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15531                app.adjType = "cch-as-act";
15532            }
15533        }
15534
15535        if (adj == ProcessList.SERVICE_ADJ) {
15536            if (doingAll) {
15537                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15538                mNewNumServiceProcs++;
15539                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15540                if (!app.serviceb) {
15541                    // This service isn't far enough down on the LRU list to
15542                    // normally be a B service, but if we are low on RAM and it
15543                    // is large we want to force it down since we would prefer to
15544                    // keep launcher over it.
15545                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15546                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15547                        app.serviceHighRam = true;
15548                        app.serviceb = true;
15549                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15550                    } else {
15551                        mNewNumAServiceProcs++;
15552                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15553                    }
15554                } else {
15555                    app.serviceHighRam = false;
15556                }
15557            }
15558            if (app.serviceb) {
15559                adj = ProcessList.SERVICE_B_ADJ;
15560            }
15561        }
15562
15563        app.curRawAdj = adj;
15564
15565        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15566        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15567        if (adj > app.maxAdj) {
15568            adj = app.maxAdj;
15569            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15570                schedGroup = Process.THREAD_GROUP_DEFAULT;
15571            }
15572        }
15573        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15574            app.keeping = true;
15575        }
15576
15577        // Do final modification to adj.  Everything we do between here and applying
15578        // the final setAdj must be done in this function, because we will also use
15579        // it when computing the final cached adj later.  Note that we don't need to
15580        // worry about this for max adj above, since max adj will always be used to
15581        // keep it out of the cached vaues.
15582        app.curAdj = app.modifyRawOomAdj(adj);
15583        app.curSchedGroup = schedGroup;
15584        app.curProcState = procState;
15585        app.foregroundActivities = foregroundActivities;
15586
15587        return app.curRawAdj;
15588    }
15589
15590    /**
15591     * Schedule PSS collection of a process.
15592     */
15593    void requestPssLocked(ProcessRecord proc, int procState) {
15594        if (mPendingPssProcesses.contains(proc)) {
15595            return;
15596        }
15597        if (mPendingPssProcesses.size() == 0) {
15598            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15599        }
15600        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15601        proc.pssProcState = procState;
15602        mPendingPssProcesses.add(proc);
15603    }
15604
15605    /**
15606     * Schedule PSS collection of all processes.
15607     */
15608    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15609        if (!always) {
15610            if (now < (mLastFullPssTime +
15611                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15612                return;
15613            }
15614        }
15615        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15616        mLastFullPssTime = now;
15617        mFullPssPending = true;
15618        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15619        mPendingPssProcesses.clear();
15620        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15621            ProcessRecord app = mLruProcesses.get(i);
15622            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15623                app.pssProcState = app.setProcState;
15624                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15625                        isSleeping(), now);
15626                mPendingPssProcesses.add(app);
15627            }
15628        }
15629        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15630    }
15631
15632    /**
15633     * Ask a given process to GC right now.
15634     */
15635    final void performAppGcLocked(ProcessRecord app) {
15636        try {
15637            app.lastRequestedGc = SystemClock.uptimeMillis();
15638            if (app.thread != null) {
15639                if (app.reportLowMemory) {
15640                    app.reportLowMemory = false;
15641                    app.thread.scheduleLowMemory();
15642                } else {
15643                    app.thread.processInBackground();
15644                }
15645            }
15646        } catch (Exception e) {
15647            // whatever.
15648        }
15649    }
15650
15651    /**
15652     * Returns true if things are idle enough to perform GCs.
15653     */
15654    private final boolean canGcNowLocked() {
15655        boolean processingBroadcasts = false;
15656        for (BroadcastQueue q : mBroadcastQueues) {
15657            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15658                processingBroadcasts = true;
15659            }
15660        }
15661        return !processingBroadcasts
15662                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15663    }
15664
15665    /**
15666     * Perform GCs on all processes that are waiting for it, but only
15667     * if things are idle.
15668     */
15669    final void performAppGcsLocked() {
15670        final int N = mProcessesToGc.size();
15671        if (N <= 0) {
15672            return;
15673        }
15674        if (canGcNowLocked()) {
15675            while (mProcessesToGc.size() > 0) {
15676                ProcessRecord proc = mProcessesToGc.remove(0);
15677                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15678                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15679                            <= SystemClock.uptimeMillis()) {
15680                        // To avoid spamming the system, we will GC processes one
15681                        // at a time, waiting a few seconds between each.
15682                        performAppGcLocked(proc);
15683                        scheduleAppGcsLocked();
15684                        return;
15685                    } else {
15686                        // It hasn't been long enough since we last GCed this
15687                        // process...  put it in the list to wait for its time.
15688                        addProcessToGcListLocked(proc);
15689                        break;
15690                    }
15691                }
15692            }
15693
15694            scheduleAppGcsLocked();
15695        }
15696    }
15697
15698    /**
15699     * If all looks good, perform GCs on all processes waiting for them.
15700     */
15701    final void performAppGcsIfAppropriateLocked() {
15702        if (canGcNowLocked()) {
15703            performAppGcsLocked();
15704            return;
15705        }
15706        // Still not idle, wait some more.
15707        scheduleAppGcsLocked();
15708    }
15709
15710    /**
15711     * Schedule the execution of all pending app GCs.
15712     */
15713    final void scheduleAppGcsLocked() {
15714        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15715
15716        if (mProcessesToGc.size() > 0) {
15717            // Schedule a GC for the time to the next process.
15718            ProcessRecord proc = mProcessesToGc.get(0);
15719            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15720
15721            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15722            long now = SystemClock.uptimeMillis();
15723            if (when < (now+GC_TIMEOUT)) {
15724                when = now + GC_TIMEOUT;
15725            }
15726            mHandler.sendMessageAtTime(msg, when);
15727        }
15728    }
15729
15730    /**
15731     * Add a process to the array of processes waiting to be GCed.  Keeps the
15732     * list in sorted order by the last GC time.  The process can't already be
15733     * on the list.
15734     */
15735    final void addProcessToGcListLocked(ProcessRecord proc) {
15736        boolean added = false;
15737        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15738            if (mProcessesToGc.get(i).lastRequestedGc <
15739                    proc.lastRequestedGc) {
15740                added = true;
15741                mProcessesToGc.add(i+1, proc);
15742                break;
15743            }
15744        }
15745        if (!added) {
15746            mProcessesToGc.add(0, proc);
15747        }
15748    }
15749
15750    /**
15751     * Set up to ask a process to GC itself.  This will either do it
15752     * immediately, or put it on the list of processes to gc the next
15753     * time things are idle.
15754     */
15755    final void scheduleAppGcLocked(ProcessRecord app) {
15756        long now = SystemClock.uptimeMillis();
15757        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15758            return;
15759        }
15760        if (!mProcessesToGc.contains(app)) {
15761            addProcessToGcListLocked(app);
15762            scheduleAppGcsLocked();
15763        }
15764    }
15765
15766    final void checkExcessivePowerUsageLocked(boolean doKills) {
15767        updateCpuStatsNow();
15768
15769        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15770        boolean doWakeKills = doKills;
15771        boolean doCpuKills = doKills;
15772        if (mLastPowerCheckRealtime == 0) {
15773            doWakeKills = false;
15774        }
15775        if (mLastPowerCheckUptime == 0) {
15776            doCpuKills = false;
15777        }
15778        if (stats.isScreenOn()) {
15779            doWakeKills = false;
15780        }
15781        final long curRealtime = SystemClock.elapsedRealtime();
15782        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15783        final long curUptime = SystemClock.uptimeMillis();
15784        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15785        mLastPowerCheckRealtime = curRealtime;
15786        mLastPowerCheckUptime = curUptime;
15787        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15788            doWakeKills = false;
15789        }
15790        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15791            doCpuKills = false;
15792        }
15793        int i = mLruProcesses.size();
15794        while (i > 0) {
15795            i--;
15796            ProcessRecord app = mLruProcesses.get(i);
15797            if (!app.keeping) {
15798                long wtime;
15799                synchronized (stats) {
15800                    wtime = stats.getProcessWakeTime(app.info.uid,
15801                            app.pid, curRealtime);
15802                }
15803                long wtimeUsed = wtime - app.lastWakeTime;
15804                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15805                if (DEBUG_POWER) {
15806                    StringBuilder sb = new StringBuilder(128);
15807                    sb.append("Wake for ");
15808                    app.toShortString(sb);
15809                    sb.append(": over ");
15810                    TimeUtils.formatDuration(realtimeSince, sb);
15811                    sb.append(" used ");
15812                    TimeUtils.formatDuration(wtimeUsed, sb);
15813                    sb.append(" (");
15814                    sb.append((wtimeUsed*100)/realtimeSince);
15815                    sb.append("%)");
15816                    Slog.i(TAG, sb.toString());
15817                    sb.setLength(0);
15818                    sb.append("CPU for ");
15819                    app.toShortString(sb);
15820                    sb.append(": over ");
15821                    TimeUtils.formatDuration(uptimeSince, sb);
15822                    sb.append(" used ");
15823                    TimeUtils.formatDuration(cputimeUsed, sb);
15824                    sb.append(" (");
15825                    sb.append((cputimeUsed*100)/uptimeSince);
15826                    sb.append("%)");
15827                    Slog.i(TAG, sb.toString());
15828                }
15829                // If a process has held a wake lock for more
15830                // than 50% of the time during this period,
15831                // that sounds bad.  Kill!
15832                if (doWakeKills && realtimeSince > 0
15833                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15834                    synchronized (stats) {
15835                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15836                                realtimeSince, wtimeUsed);
15837                    }
15838                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15839                            + " during " + realtimeSince);
15840                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15841                } else if (doCpuKills && uptimeSince > 0
15842                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15843                    synchronized (stats) {
15844                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15845                                uptimeSince, cputimeUsed);
15846                    }
15847                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15848                            + " during " + uptimeSince);
15849                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15850                } else {
15851                    app.lastWakeTime = wtime;
15852                    app.lastCpuTime = app.curCpuTime;
15853                }
15854            }
15855        }
15856    }
15857
15858    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15859            ProcessRecord TOP_APP, boolean doingAll, long now) {
15860        boolean success = true;
15861
15862        if (app.curRawAdj != app.setRawAdj) {
15863            if (wasKeeping && !app.keeping) {
15864                // This app is no longer something we want to keep.  Note
15865                // its current wake lock time to later know to kill it if
15866                // it is not behaving well.
15867                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15868                synchronized (stats) {
15869                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15870                            app.pid, SystemClock.elapsedRealtime());
15871                }
15872                app.lastCpuTime = app.curCpuTime;
15873            }
15874
15875            app.setRawAdj = app.curRawAdj;
15876        }
15877
15878        int changes = 0;
15879
15880        if (app.curAdj != app.setAdj) {
15881            ProcessList.setOomAdj(app.pid, app.curAdj);
15882            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15883                TAG, "Set " + app.pid + " " + app.processName +
15884                " adj " + app.curAdj + ": " + app.adjType);
15885            app.setAdj = app.curAdj;
15886        }
15887
15888        if (app.setSchedGroup != app.curSchedGroup) {
15889            app.setSchedGroup = app.curSchedGroup;
15890            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15891                    "Setting process group of " + app.processName
15892                    + " to " + app.curSchedGroup);
15893            if (app.waitingToKill != null &&
15894                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15895                killUnneededProcessLocked(app, app.waitingToKill);
15896                success = false;
15897            } else {
15898                if (true) {
15899                    long oldId = Binder.clearCallingIdentity();
15900                    try {
15901                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15902                    } catch (Exception e) {
15903                        Slog.w(TAG, "Failed setting process group of " + app.pid
15904                                + " to " + app.curSchedGroup);
15905                        e.printStackTrace();
15906                    } finally {
15907                        Binder.restoreCallingIdentity(oldId);
15908                    }
15909                } else {
15910                    if (app.thread != null) {
15911                        try {
15912                            app.thread.setSchedulingGroup(app.curSchedGroup);
15913                        } catch (RemoteException e) {
15914                        }
15915                    }
15916                }
15917                Process.setSwappiness(app.pid,
15918                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15919            }
15920        }
15921        if (app.repForegroundActivities != app.foregroundActivities) {
15922            app.repForegroundActivities = app.foregroundActivities;
15923            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15924        }
15925        if (app.repProcState != app.curProcState) {
15926            app.repProcState = app.curProcState;
15927            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15928            if (app.thread != null) {
15929                try {
15930                    if (false) {
15931                        //RuntimeException h = new RuntimeException("here");
15932                        Slog.i(TAG, "Sending new process state " + app.repProcState
15933                                + " to " + app /*, h*/);
15934                    }
15935                    app.thread.setProcessState(app.repProcState);
15936                } catch (RemoteException e) {
15937                }
15938            }
15939        }
15940        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15941                app.setProcState)) {
15942            app.lastStateTime = now;
15943            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15944                    isSleeping(), now);
15945            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15946                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15947                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15948                    + (app.nextPssTime-now) + ": " + app);
15949        } else {
15950            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15951                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15952                requestPssLocked(app, app.setProcState);
15953                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15954                        isSleeping(), now);
15955            } else if (false && DEBUG_PSS) {
15956                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15957            }
15958        }
15959        if (app.setProcState != app.curProcState) {
15960            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15961                    "Proc state change of " + app.processName
15962                    + " to " + app.curProcState);
15963            app.setProcState = app.curProcState;
15964            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15965                app.notCachedSinceIdle = false;
15966            }
15967            if (!doingAll) {
15968                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15969            } else {
15970                app.procStateChanged = true;
15971            }
15972        }
15973
15974        if (changes != 0) {
15975            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15976            int i = mPendingProcessChanges.size()-1;
15977            ProcessChangeItem item = null;
15978            while (i >= 0) {
15979                item = mPendingProcessChanges.get(i);
15980                if (item.pid == app.pid) {
15981                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15982                    break;
15983                }
15984                i--;
15985            }
15986            if (i < 0) {
15987                // No existing item in pending changes; need a new one.
15988                final int NA = mAvailProcessChanges.size();
15989                if (NA > 0) {
15990                    item = mAvailProcessChanges.remove(NA-1);
15991                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15992                } else {
15993                    item = new ProcessChangeItem();
15994                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15995                }
15996                item.changes = 0;
15997                item.pid = app.pid;
15998                item.uid = app.info.uid;
15999                if (mPendingProcessChanges.size() == 0) {
16000                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16001                            "*** Enqueueing dispatch processes changed!");
16002                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16003                }
16004                mPendingProcessChanges.add(item);
16005            }
16006            item.changes |= changes;
16007            item.processState = app.repProcState;
16008            item.foregroundActivities = app.repForegroundActivities;
16009            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16010                    + Integer.toHexString(System.identityHashCode(item))
16011                    + " " + app.toShortString() + ": changes=" + item.changes
16012                    + " procState=" + item.processState
16013                    + " foreground=" + item.foregroundActivities
16014                    + " type=" + app.adjType + " source=" + app.adjSource
16015                    + " target=" + app.adjTarget);
16016        }
16017
16018        return success;
16019    }
16020
16021    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16022        if (proc.thread != null && proc.baseProcessTracker != null) {
16023            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16024        }
16025    }
16026
16027    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16028            ProcessRecord TOP_APP, boolean doingAll, long now) {
16029        if (app.thread == null) {
16030            return false;
16031        }
16032
16033        final boolean wasKeeping = app.keeping;
16034
16035        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16036
16037        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16038    }
16039
16040    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16041            boolean oomAdj) {
16042        if (isForeground != proc.foregroundServices) {
16043            proc.foregroundServices = isForeground;
16044            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16045                    proc.info.uid);
16046            if (isForeground) {
16047                if (curProcs == null) {
16048                    curProcs = new ArrayList<ProcessRecord>();
16049                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16050                }
16051                if (!curProcs.contains(proc)) {
16052                    curProcs.add(proc);
16053                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16054                            proc.info.packageName, proc.info.uid);
16055                }
16056            } else {
16057                if (curProcs != null) {
16058                    if (curProcs.remove(proc)) {
16059                        mBatteryStatsService.noteEvent(
16060                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16061                                proc.info.packageName, proc.info.uid);
16062                        if (curProcs.size() <= 0) {
16063                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16064                        }
16065                    }
16066                }
16067            }
16068            if (oomAdj) {
16069                updateOomAdjLocked();
16070            }
16071        }
16072    }
16073
16074    private final ActivityRecord resumedAppLocked() {
16075        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16076        String pkg;
16077        int uid;
16078        if (act != null && !act.sleeping) {
16079            pkg = act.packageName;
16080            uid = act.info.applicationInfo.uid;
16081        } else {
16082            pkg = null;
16083            uid = -1;
16084        }
16085        // Has the UID or resumed package name changed?
16086        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16087                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16088            if (mCurResumedPackage != null) {
16089                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16090                        mCurResumedPackage, mCurResumedUid);
16091            }
16092            mCurResumedPackage = pkg;
16093            mCurResumedUid = uid;
16094            if (mCurResumedPackage != null) {
16095                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16096                        mCurResumedPackage, mCurResumedUid);
16097            }
16098        }
16099        return act;
16100    }
16101
16102    final boolean updateOomAdjLocked(ProcessRecord app) {
16103        final ActivityRecord TOP_ACT = resumedAppLocked();
16104        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16105        final boolean wasCached = app.cached;
16106
16107        mAdjSeq++;
16108
16109        // This is the desired cached adjusment we want to tell it to use.
16110        // If our app is currently cached, we know it, and that is it.  Otherwise,
16111        // we don't know it yet, and it needs to now be cached we will then
16112        // need to do a complete oom adj.
16113        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16114                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16115        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16116                SystemClock.uptimeMillis());
16117        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16118            // Changed to/from cached state, so apps after it in the LRU
16119            // list may also be changed.
16120            updateOomAdjLocked();
16121        }
16122        return success;
16123    }
16124
16125    final void updateOomAdjLocked() {
16126        final ActivityRecord TOP_ACT = resumedAppLocked();
16127        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16128        final long now = SystemClock.uptimeMillis();
16129        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16130        final int N = mLruProcesses.size();
16131
16132        if (false) {
16133            RuntimeException e = new RuntimeException();
16134            e.fillInStackTrace();
16135            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16136        }
16137
16138        mAdjSeq++;
16139        mNewNumServiceProcs = 0;
16140        mNewNumAServiceProcs = 0;
16141
16142        final int emptyProcessLimit;
16143        final int cachedProcessLimit;
16144        if (mProcessLimit <= 0) {
16145            emptyProcessLimit = cachedProcessLimit = 0;
16146        } else if (mProcessLimit == 1) {
16147            emptyProcessLimit = 1;
16148            cachedProcessLimit = 0;
16149        } else {
16150            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16151            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16152        }
16153
16154        // Let's determine how many processes we have running vs.
16155        // how many slots we have for background processes; we may want
16156        // to put multiple processes in a slot of there are enough of
16157        // them.
16158        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16159                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16160        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16161        if (numEmptyProcs > cachedProcessLimit) {
16162            // If there are more empty processes than our limit on cached
16163            // processes, then use the cached process limit for the factor.
16164            // This ensures that the really old empty processes get pushed
16165            // down to the bottom, so if we are running low on memory we will
16166            // have a better chance at keeping around more cached processes
16167            // instead of a gazillion empty processes.
16168            numEmptyProcs = cachedProcessLimit;
16169        }
16170        int emptyFactor = numEmptyProcs/numSlots;
16171        if (emptyFactor < 1) emptyFactor = 1;
16172        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16173        if (cachedFactor < 1) cachedFactor = 1;
16174        int stepCached = 0;
16175        int stepEmpty = 0;
16176        int numCached = 0;
16177        int numEmpty = 0;
16178        int numTrimming = 0;
16179
16180        mNumNonCachedProcs = 0;
16181        mNumCachedHiddenProcs = 0;
16182
16183        // First update the OOM adjustment for each of the
16184        // application processes based on their current state.
16185        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16186        int nextCachedAdj = curCachedAdj+1;
16187        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16188        int nextEmptyAdj = curEmptyAdj+2;
16189        for (int i=N-1; i>=0; i--) {
16190            ProcessRecord app = mLruProcesses.get(i);
16191            if (!app.killedByAm && app.thread != null) {
16192                app.procStateChanged = false;
16193                final boolean wasKeeping = app.keeping;
16194                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16195
16196                // If we haven't yet assigned the final cached adj
16197                // to the process, do that now.
16198                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16199                    switch (app.curProcState) {
16200                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16201                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16202                            // This process is a cached process holding activities...
16203                            // assign it the next cached value for that type, and then
16204                            // step that cached level.
16205                            app.curRawAdj = curCachedAdj;
16206                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16207                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16208                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16209                                    + ")");
16210                            if (curCachedAdj != nextCachedAdj) {
16211                                stepCached++;
16212                                if (stepCached >= cachedFactor) {
16213                                    stepCached = 0;
16214                                    curCachedAdj = nextCachedAdj;
16215                                    nextCachedAdj += 2;
16216                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16217                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16218                                    }
16219                                }
16220                            }
16221                            break;
16222                        default:
16223                            // For everything else, assign next empty cached process
16224                            // level and bump that up.  Note that this means that
16225                            // long-running services that have dropped down to the
16226                            // cached level will be treated as empty (since their process
16227                            // state is still as a service), which is what we want.
16228                            app.curRawAdj = curEmptyAdj;
16229                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16230                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16231                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16232                                    + ")");
16233                            if (curEmptyAdj != nextEmptyAdj) {
16234                                stepEmpty++;
16235                                if (stepEmpty >= emptyFactor) {
16236                                    stepEmpty = 0;
16237                                    curEmptyAdj = nextEmptyAdj;
16238                                    nextEmptyAdj += 2;
16239                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16240                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16241                                    }
16242                                }
16243                            }
16244                            break;
16245                    }
16246                }
16247
16248                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16249
16250                // Count the number of process types.
16251                switch (app.curProcState) {
16252                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16253                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16254                        mNumCachedHiddenProcs++;
16255                        numCached++;
16256                        if (numCached > cachedProcessLimit) {
16257                            killUnneededProcessLocked(app, "cached #" + numCached);
16258                        }
16259                        break;
16260                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16261                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16262                                && app.lastActivityTime < oldTime) {
16263                            killUnneededProcessLocked(app, "empty for "
16264                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16265                                    / 1000) + "s");
16266                        } else {
16267                            numEmpty++;
16268                            if (numEmpty > emptyProcessLimit) {
16269                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16270                            }
16271                        }
16272                        break;
16273                    default:
16274                        mNumNonCachedProcs++;
16275                        break;
16276                }
16277
16278                if (app.isolated && app.services.size() <= 0) {
16279                    // If this is an isolated process, and there are no
16280                    // services running in it, then the process is no longer
16281                    // needed.  We agressively kill these because we can by
16282                    // definition not re-use the same process again, and it is
16283                    // good to avoid having whatever code was running in them
16284                    // left sitting around after no longer needed.
16285                    killUnneededProcessLocked(app, "isolated not needed");
16286                }
16287
16288                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16289                        && !app.killedByAm) {
16290                    numTrimming++;
16291                }
16292            }
16293        }
16294
16295        mNumServiceProcs = mNewNumServiceProcs;
16296
16297        // Now determine the memory trimming level of background processes.
16298        // Unfortunately we need to start at the back of the list to do this
16299        // properly.  We only do this if the number of background apps we
16300        // are managing to keep around is less than half the maximum we desire;
16301        // if we are keeping a good number around, we'll let them use whatever
16302        // memory they want.
16303        final int numCachedAndEmpty = numCached + numEmpty;
16304        int memFactor;
16305        if (numCached <= ProcessList.TRIM_CACHED_APPS
16306                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16307            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16308                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16309            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16310                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16311            } else {
16312                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16313            }
16314        } else {
16315            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16316        }
16317        // We always allow the memory level to go up (better).  We only allow it to go
16318        // down if we are in a state where that is allowed, *and* the total number of processes
16319        // has gone down since last time.
16320        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16321                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16322                + " last=" + mLastNumProcesses);
16323        if (memFactor > mLastMemoryLevel) {
16324            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16325                memFactor = mLastMemoryLevel;
16326                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16327            }
16328        }
16329        mLastMemoryLevel = memFactor;
16330        mLastNumProcesses = mLruProcesses.size();
16331        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16332        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16333        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16334            if (mLowRamStartTime == 0) {
16335                mLowRamStartTime = now;
16336            }
16337            int step = 0;
16338            int fgTrimLevel;
16339            switch (memFactor) {
16340                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16341                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16342                    break;
16343                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16344                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16345                    break;
16346                default:
16347                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16348                    break;
16349            }
16350            int factor = numTrimming/3;
16351            int minFactor = 2;
16352            if (mHomeProcess != null) minFactor++;
16353            if (mPreviousProcess != null) minFactor++;
16354            if (factor < minFactor) factor = minFactor;
16355            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16356            for (int i=N-1; i>=0; i--) {
16357                ProcessRecord app = mLruProcesses.get(i);
16358                if (allChanged || app.procStateChanged) {
16359                    setProcessTrackerState(app, trackerMemFactor, now);
16360                    app.procStateChanged = false;
16361                }
16362                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16363                        && !app.killedByAm) {
16364                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16365                        try {
16366                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16367                                    "Trimming memory of " + app.processName
16368                                    + " to " + curLevel);
16369                            app.thread.scheduleTrimMemory(curLevel);
16370                        } catch (RemoteException e) {
16371                        }
16372                        if (false) {
16373                            // For now we won't do this; our memory trimming seems
16374                            // to be good enough at this point that destroying
16375                            // activities causes more harm than good.
16376                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16377                                    && app != mHomeProcess && app != mPreviousProcess) {
16378                                // Need to do this on its own message because the stack may not
16379                                // be in a consistent state at this point.
16380                                // For these apps we will also finish their activities
16381                                // to help them free memory.
16382                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16383                            }
16384                        }
16385                    }
16386                    app.trimMemoryLevel = curLevel;
16387                    step++;
16388                    if (step >= factor) {
16389                        step = 0;
16390                        switch (curLevel) {
16391                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16392                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16393                                break;
16394                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16395                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16396                                break;
16397                        }
16398                    }
16399                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16400                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16401                            && app.thread != null) {
16402                        try {
16403                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16404                                    "Trimming memory of heavy-weight " + app.processName
16405                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16406                            app.thread.scheduleTrimMemory(
16407                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16408                        } catch (RemoteException e) {
16409                        }
16410                    }
16411                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16412                } else {
16413                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16414                            || app.systemNoUi) && app.pendingUiClean) {
16415                        // If this application is now in the background and it
16416                        // had done UI, then give it the special trim level to
16417                        // have it free UI resources.
16418                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16419                        if (app.trimMemoryLevel < level && app.thread != null) {
16420                            try {
16421                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16422                                        "Trimming memory of bg-ui " + app.processName
16423                                        + " to " + level);
16424                                app.thread.scheduleTrimMemory(level);
16425                            } catch (RemoteException e) {
16426                            }
16427                        }
16428                        app.pendingUiClean = false;
16429                    }
16430                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16431                        try {
16432                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16433                                    "Trimming memory of fg " + app.processName
16434                                    + " to " + fgTrimLevel);
16435                            app.thread.scheduleTrimMemory(fgTrimLevel);
16436                        } catch (RemoteException e) {
16437                        }
16438                    }
16439                    app.trimMemoryLevel = fgTrimLevel;
16440                }
16441            }
16442        } else {
16443            if (mLowRamStartTime != 0) {
16444                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16445                mLowRamStartTime = 0;
16446            }
16447            for (int i=N-1; i>=0; i--) {
16448                ProcessRecord app = mLruProcesses.get(i);
16449                if (allChanged || app.procStateChanged) {
16450                    setProcessTrackerState(app, trackerMemFactor, now);
16451                    app.procStateChanged = false;
16452                }
16453                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16454                        || app.systemNoUi) && app.pendingUiClean) {
16455                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16456                            && app.thread != null) {
16457                        try {
16458                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16459                                    "Trimming memory of ui hidden " + app.processName
16460                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16461                            app.thread.scheduleTrimMemory(
16462                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16463                        } catch (RemoteException e) {
16464                        }
16465                    }
16466                    app.pendingUiClean = false;
16467                }
16468                app.trimMemoryLevel = 0;
16469            }
16470        }
16471
16472        if (mAlwaysFinishActivities) {
16473            // Need to do this on its own message because the stack may not
16474            // be in a consistent state at this point.
16475            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16476        }
16477
16478        if (allChanged) {
16479            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16480        }
16481
16482        if (mProcessStats.shouldWriteNowLocked(now)) {
16483            mHandler.post(new Runnable() {
16484                @Override public void run() {
16485                    synchronized (ActivityManagerService.this) {
16486                        mProcessStats.writeStateAsyncLocked();
16487                    }
16488                }
16489            });
16490        }
16491
16492        if (DEBUG_OOM_ADJ) {
16493            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16494        }
16495    }
16496
16497    final void trimApplications() {
16498        synchronized (this) {
16499            int i;
16500
16501            // First remove any unused application processes whose package
16502            // has been removed.
16503            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16504                final ProcessRecord app = mRemovedProcesses.get(i);
16505                if (app.activities.size() == 0
16506                        && app.curReceiver == null && app.services.size() == 0) {
16507                    Slog.i(
16508                        TAG, "Exiting empty application process "
16509                        + app.processName + " ("
16510                        + (app.thread != null ? app.thread.asBinder() : null)
16511                        + ")\n");
16512                    if (app.pid > 0 && app.pid != MY_PID) {
16513                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16514                                app.processName, app.setAdj, "empty");
16515                        app.killedByAm = true;
16516                        Process.killProcessQuiet(app.pid);
16517                    } else {
16518                        try {
16519                            app.thread.scheduleExit();
16520                        } catch (Exception e) {
16521                            // Ignore exceptions.
16522                        }
16523                    }
16524                    cleanUpApplicationRecordLocked(app, false, true, -1);
16525                    mRemovedProcesses.remove(i);
16526
16527                    if (app.persistent) {
16528                        if (app.persistent) {
16529                            addAppLocked(app.info, false, null /* ABI override */);
16530                        }
16531                    }
16532                }
16533            }
16534
16535            // Now update the oom adj for all processes.
16536            updateOomAdjLocked();
16537        }
16538    }
16539
16540    /** This method sends the specified signal to each of the persistent apps */
16541    public void signalPersistentProcesses(int sig) throws RemoteException {
16542        if (sig != Process.SIGNAL_USR1) {
16543            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16544        }
16545
16546        synchronized (this) {
16547            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16548                    != PackageManager.PERMISSION_GRANTED) {
16549                throw new SecurityException("Requires permission "
16550                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16551            }
16552
16553            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16554                ProcessRecord r = mLruProcesses.get(i);
16555                if (r.thread != null && r.persistent) {
16556                    Process.sendSignal(r.pid, sig);
16557                }
16558            }
16559        }
16560    }
16561
16562    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16563        if (proc == null || proc == mProfileProc) {
16564            proc = mProfileProc;
16565            path = mProfileFile;
16566            profileType = mProfileType;
16567            clearProfilerLocked();
16568        }
16569        if (proc == null) {
16570            return;
16571        }
16572        try {
16573            proc.thread.profilerControl(false, path, null, profileType);
16574        } catch (RemoteException e) {
16575            throw new IllegalStateException("Process disappeared");
16576        }
16577    }
16578
16579    private void clearProfilerLocked() {
16580        if (mProfileFd != null) {
16581            try {
16582                mProfileFd.close();
16583            } catch (IOException e) {
16584            }
16585        }
16586        mProfileApp = null;
16587        mProfileProc = null;
16588        mProfileFile = null;
16589        mProfileType = 0;
16590        mAutoStopProfiler = false;
16591    }
16592
16593    public boolean profileControl(String process, int userId, boolean start,
16594            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16595
16596        try {
16597            synchronized (this) {
16598                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16599                // its own permission.
16600                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16601                        != PackageManager.PERMISSION_GRANTED) {
16602                    throw new SecurityException("Requires permission "
16603                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16604                }
16605
16606                if (start && fd == null) {
16607                    throw new IllegalArgumentException("null fd");
16608                }
16609
16610                ProcessRecord proc = null;
16611                if (process != null) {
16612                    proc = findProcessLocked(process, userId, "profileControl");
16613                }
16614
16615                if (start && (proc == null || proc.thread == null)) {
16616                    throw new IllegalArgumentException("Unknown process: " + process);
16617                }
16618
16619                if (start) {
16620                    stopProfilerLocked(null, null, 0);
16621                    setProfileApp(proc.info, proc.processName, path, fd, false);
16622                    mProfileProc = proc;
16623                    mProfileType = profileType;
16624                    try {
16625                        fd = fd.dup();
16626                    } catch (IOException e) {
16627                        fd = null;
16628                    }
16629                    proc.thread.profilerControl(start, path, fd, profileType);
16630                    fd = null;
16631                    mProfileFd = null;
16632                } else {
16633                    stopProfilerLocked(proc, path, profileType);
16634                    if (fd != null) {
16635                        try {
16636                            fd.close();
16637                        } catch (IOException e) {
16638                        }
16639                    }
16640                }
16641
16642                return true;
16643            }
16644        } catch (RemoteException e) {
16645            throw new IllegalStateException("Process disappeared");
16646        } finally {
16647            if (fd != null) {
16648                try {
16649                    fd.close();
16650                } catch (IOException e) {
16651                }
16652            }
16653        }
16654    }
16655
16656    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16657        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16658                userId, true, true, callName, null);
16659        ProcessRecord proc = null;
16660        try {
16661            int pid = Integer.parseInt(process);
16662            synchronized (mPidsSelfLocked) {
16663                proc = mPidsSelfLocked.get(pid);
16664            }
16665        } catch (NumberFormatException e) {
16666        }
16667
16668        if (proc == null) {
16669            ArrayMap<String, SparseArray<ProcessRecord>> all
16670                    = mProcessNames.getMap();
16671            SparseArray<ProcessRecord> procs = all.get(process);
16672            if (procs != null && procs.size() > 0) {
16673                proc = procs.valueAt(0);
16674                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16675                    for (int i=1; i<procs.size(); i++) {
16676                        ProcessRecord thisProc = procs.valueAt(i);
16677                        if (thisProc.userId == userId) {
16678                            proc = thisProc;
16679                            break;
16680                        }
16681                    }
16682                }
16683            }
16684        }
16685
16686        return proc;
16687    }
16688
16689    public boolean dumpHeap(String process, int userId, boolean managed,
16690            String path, ParcelFileDescriptor fd) throws RemoteException {
16691
16692        try {
16693            synchronized (this) {
16694                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16695                // its own permission (same as profileControl).
16696                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16697                        != PackageManager.PERMISSION_GRANTED) {
16698                    throw new SecurityException("Requires permission "
16699                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16700                }
16701
16702                if (fd == null) {
16703                    throw new IllegalArgumentException("null fd");
16704                }
16705
16706                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16707                if (proc == null || proc.thread == null) {
16708                    throw new IllegalArgumentException("Unknown process: " + process);
16709                }
16710
16711                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16712                if (!isDebuggable) {
16713                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16714                        throw new SecurityException("Process not debuggable: " + proc);
16715                    }
16716                }
16717
16718                proc.thread.dumpHeap(managed, path, fd);
16719                fd = null;
16720                return true;
16721            }
16722        } catch (RemoteException e) {
16723            throw new IllegalStateException("Process disappeared");
16724        } finally {
16725            if (fd != null) {
16726                try {
16727                    fd.close();
16728                } catch (IOException e) {
16729                }
16730            }
16731        }
16732    }
16733
16734    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16735    public void monitor() {
16736        synchronized (this) { }
16737    }
16738
16739    void onCoreSettingsChange(Bundle settings) {
16740        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16741            ProcessRecord processRecord = mLruProcesses.get(i);
16742            try {
16743                if (processRecord.thread != null) {
16744                    processRecord.thread.setCoreSettings(settings);
16745                }
16746            } catch (RemoteException re) {
16747                /* ignore */
16748            }
16749        }
16750    }
16751
16752    // Multi-user methods
16753
16754    /**
16755     * Start user, if its not already running, but don't bring it to foreground.
16756     */
16757    @Override
16758    public boolean startUserInBackground(final int userId) {
16759        return startUser(userId, /* foreground */ false);
16760    }
16761
16762    /**
16763     * Refreshes the list of users related to the current user when either a
16764     * user switch happens or when a new related user is started in the
16765     * background.
16766     */
16767    private void updateCurrentProfileIdsLocked() {
16768        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16769                mCurrentUserId, false /* enabledOnly */);
16770        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16771        for (int i = 0; i < currentProfileIds.length; i++) {
16772            currentProfileIds[i] = profiles.get(i).id;
16773        }
16774        mCurrentProfileIds = currentProfileIds;
16775    }
16776
16777    private Set getProfileIdsLocked(int userId) {
16778        Set userIds = new HashSet<Integer>();
16779        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16780                userId, false /* enabledOnly */);
16781        for (UserInfo user : profiles) {
16782            userIds.add(Integer.valueOf(user.id));
16783        }
16784        return userIds;
16785    }
16786
16787    @Override
16788    public boolean switchUser(final int userId) {
16789        return startUser(userId, /* foregound */ true);
16790    }
16791
16792    private boolean startUser(final int userId, boolean foreground) {
16793        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16794                != PackageManager.PERMISSION_GRANTED) {
16795            String msg = "Permission Denial: switchUser() from pid="
16796                    + Binder.getCallingPid()
16797                    + ", uid=" + Binder.getCallingUid()
16798                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16799            Slog.w(TAG, msg);
16800            throw new SecurityException(msg);
16801        }
16802
16803        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16804
16805        final long ident = Binder.clearCallingIdentity();
16806        try {
16807            synchronized (this) {
16808                final int oldUserId = mCurrentUserId;
16809                if (oldUserId == userId) {
16810                    return true;
16811                }
16812
16813                mStackSupervisor.setLockTaskModeLocked(null, false);
16814
16815                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16816                if (userInfo == null) {
16817                    Slog.w(TAG, "No user info for user #" + userId);
16818                    return false;
16819                }
16820
16821                if (foreground) {
16822                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16823                            R.anim.screen_user_enter);
16824                }
16825
16826                boolean needStart = false;
16827
16828                // If the user we are switching to is not currently started, then
16829                // we need to start it now.
16830                if (mStartedUsers.get(userId) == null) {
16831                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16832                    updateStartedUserArrayLocked();
16833                    needStart = true;
16834                }
16835
16836                final Integer userIdInt = Integer.valueOf(userId);
16837                mUserLru.remove(userIdInt);
16838                mUserLru.add(userIdInt);
16839
16840                if (foreground) {
16841                    mCurrentUserId = userId;
16842                    updateCurrentProfileIdsLocked();
16843                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16844                    // Once the internal notion of the active user has switched, we lock the device
16845                    // with the option to show the user switcher on the keyguard.
16846                    mWindowManager.lockNow(null);
16847                } else {
16848                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16849                    updateCurrentProfileIdsLocked();
16850                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16851                    mUserLru.remove(currentUserIdInt);
16852                    mUserLru.add(currentUserIdInt);
16853                }
16854
16855                final UserStartedState uss = mStartedUsers.get(userId);
16856
16857                // Make sure user is in the started state.  If it is currently
16858                // stopping, we need to knock that off.
16859                if (uss.mState == UserStartedState.STATE_STOPPING) {
16860                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16861                    // so we can just fairly silently bring the user back from
16862                    // the almost-dead.
16863                    uss.mState = UserStartedState.STATE_RUNNING;
16864                    updateStartedUserArrayLocked();
16865                    needStart = true;
16866                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16867                    // This means ACTION_SHUTDOWN has been sent, so we will
16868                    // need to treat this as a new boot of the user.
16869                    uss.mState = UserStartedState.STATE_BOOTING;
16870                    updateStartedUserArrayLocked();
16871                    needStart = true;
16872                }
16873
16874                if (uss.mState == UserStartedState.STATE_BOOTING) {
16875                    // Booting up a new user, need to tell system services about it.
16876                    // Note that this is on the same handler as scheduling of broadcasts,
16877                    // which is important because it needs to go first.
16878                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16879                }
16880
16881                if (foreground) {
16882                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16883                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16884                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16885                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16886                            oldUserId, userId, uss));
16887                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16888                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16889                }
16890
16891                if (needStart) {
16892                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16893                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16894                            | Intent.FLAG_RECEIVER_FOREGROUND);
16895                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16896                    broadcastIntentLocked(null, null, intent,
16897                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16898                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16899                }
16900
16901                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16902                    if (userId != UserHandle.USER_OWNER) {
16903                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16904                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16905                        broadcastIntentLocked(null, null, intent, null,
16906                                new IIntentReceiver.Stub() {
16907                                    public void performReceive(Intent intent, int resultCode,
16908                                            String data, Bundle extras, boolean ordered,
16909                                            boolean sticky, int sendingUser) {
16910                                        userInitialized(uss, userId);
16911                                    }
16912                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16913                                true, false, MY_PID, Process.SYSTEM_UID,
16914                                userId);
16915                        uss.initializing = true;
16916                    } else {
16917                        getUserManagerLocked().makeInitialized(userInfo.id);
16918                    }
16919                }
16920
16921                if (foreground) {
16922                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16923                    if (homeInFront) {
16924                        startHomeActivityLocked(userId);
16925                    } else {
16926                        mStackSupervisor.resumeTopActivitiesLocked();
16927                    }
16928                    EventLogTags.writeAmSwitchUser(userId);
16929                    getUserManagerLocked().userForeground(userId);
16930                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16931                } else {
16932                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16933                }
16934
16935                if (needStart) {
16936                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16937                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16938                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16939                    broadcastIntentLocked(null, null, intent,
16940                            null, new IIntentReceiver.Stub() {
16941                                @Override
16942                                public void performReceive(Intent intent, int resultCode, String data,
16943                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16944                                        throws RemoteException {
16945                                }
16946                            }, 0, null, null,
16947                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16948                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16949                }
16950            }
16951        } finally {
16952            Binder.restoreCallingIdentity(ident);
16953        }
16954
16955        return true;
16956    }
16957
16958    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16959        long ident = Binder.clearCallingIdentity();
16960        try {
16961            Intent intent;
16962            if (oldUserId >= 0) {
16963                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16964                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16965                        | Intent.FLAG_RECEIVER_FOREGROUND);
16966                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16967                broadcastIntentLocked(null, null, intent,
16968                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16969                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16970            }
16971            if (newUserId >= 0) {
16972                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16973                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16974                        | Intent.FLAG_RECEIVER_FOREGROUND);
16975                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16976                broadcastIntentLocked(null, null, intent,
16977                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16978                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16979                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16980                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16981                        | Intent.FLAG_RECEIVER_FOREGROUND);
16982                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16983                broadcastIntentLocked(null, null, intent,
16984                        null, null, 0, null, null,
16985                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16986                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16987            }
16988        } finally {
16989            Binder.restoreCallingIdentity(ident);
16990        }
16991    }
16992
16993    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16994            final int newUserId) {
16995        final int N = mUserSwitchObservers.beginBroadcast();
16996        if (N > 0) {
16997            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16998                int mCount = 0;
16999                @Override
17000                public void sendResult(Bundle data) throws RemoteException {
17001                    synchronized (ActivityManagerService.this) {
17002                        if (mCurUserSwitchCallback == this) {
17003                            mCount++;
17004                            if (mCount == N) {
17005                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17006                            }
17007                        }
17008                    }
17009                }
17010            };
17011            synchronized (this) {
17012                uss.switching = true;
17013                mCurUserSwitchCallback = callback;
17014            }
17015            for (int i=0; i<N; i++) {
17016                try {
17017                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17018                            newUserId, callback);
17019                } catch (RemoteException e) {
17020                }
17021            }
17022        } else {
17023            synchronized (this) {
17024                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17025            }
17026        }
17027        mUserSwitchObservers.finishBroadcast();
17028    }
17029
17030    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17031        synchronized (this) {
17032            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17033            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17034        }
17035    }
17036
17037    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17038        mCurUserSwitchCallback = null;
17039        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17040        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17041                oldUserId, newUserId, uss));
17042    }
17043
17044    void userInitialized(UserStartedState uss, int newUserId) {
17045        completeSwitchAndInitalize(uss, newUserId, true, false);
17046    }
17047
17048    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17049        completeSwitchAndInitalize(uss, newUserId, false, true);
17050    }
17051
17052    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17053            boolean clearInitializing, boolean clearSwitching) {
17054        boolean unfrozen = false;
17055        synchronized (this) {
17056            if (clearInitializing) {
17057                uss.initializing = false;
17058                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17059            }
17060            if (clearSwitching) {
17061                uss.switching = false;
17062            }
17063            if (!uss.switching && !uss.initializing) {
17064                mWindowManager.stopFreezingScreen();
17065                unfrozen = true;
17066            }
17067        }
17068        if (unfrozen) {
17069            final int N = mUserSwitchObservers.beginBroadcast();
17070            for (int i=0; i<N; i++) {
17071                try {
17072                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17073                } catch (RemoteException e) {
17074                }
17075            }
17076            mUserSwitchObservers.finishBroadcast();
17077        }
17078    }
17079
17080    void scheduleStartProfilesLocked() {
17081        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17082            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17083                    DateUtils.SECOND_IN_MILLIS);
17084        }
17085    }
17086
17087    void startProfilesLocked() {
17088        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17089        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17090                mCurrentUserId, false /* enabledOnly */);
17091        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17092        for (UserInfo user : profiles) {
17093            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17094                    && user.id != mCurrentUserId) {
17095                toStart.add(user);
17096            }
17097        }
17098        final int n = toStart.size();
17099        int i = 0;
17100        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17101            startUserInBackground(toStart.get(i).id);
17102        }
17103        if (i < n) {
17104            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17105        }
17106    }
17107
17108    void finishUserBoot(UserStartedState uss) {
17109        synchronized (this) {
17110            if (uss.mState == UserStartedState.STATE_BOOTING
17111                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17112                uss.mState = UserStartedState.STATE_RUNNING;
17113                final int userId = uss.mHandle.getIdentifier();
17114                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17115                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17116                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17117                broadcastIntentLocked(null, null, intent,
17118                        null, null, 0, null, null,
17119                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17120                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17121            }
17122        }
17123    }
17124
17125    void finishUserSwitch(UserStartedState uss) {
17126        synchronized (this) {
17127            finishUserBoot(uss);
17128
17129            startProfilesLocked();
17130
17131            int num = mUserLru.size();
17132            int i = 0;
17133            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17134                Integer oldUserId = mUserLru.get(i);
17135                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17136                if (oldUss == null) {
17137                    // Shouldn't happen, but be sane if it does.
17138                    mUserLru.remove(i);
17139                    num--;
17140                    continue;
17141                }
17142                if (oldUss.mState == UserStartedState.STATE_STOPPING
17143                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17144                    // This user is already stopping, doesn't count.
17145                    num--;
17146                    i++;
17147                    continue;
17148                }
17149                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17150                    // Owner and current can't be stopped, but count as running.
17151                    i++;
17152                    continue;
17153                }
17154                // This is a user to be stopped.
17155                stopUserLocked(oldUserId, null);
17156                num--;
17157                i++;
17158            }
17159        }
17160    }
17161
17162    @Override
17163    public int stopUser(final int userId, final IStopUserCallback callback) {
17164        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17165                != PackageManager.PERMISSION_GRANTED) {
17166            String msg = "Permission Denial: switchUser() from pid="
17167                    + Binder.getCallingPid()
17168                    + ", uid=" + Binder.getCallingUid()
17169                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17170            Slog.w(TAG, msg);
17171            throw new SecurityException(msg);
17172        }
17173        if (userId <= 0) {
17174            throw new IllegalArgumentException("Can't stop primary user " + userId);
17175        }
17176        synchronized (this) {
17177            return stopUserLocked(userId, callback);
17178        }
17179    }
17180
17181    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17182        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17183        if (mCurrentUserId == userId) {
17184            return ActivityManager.USER_OP_IS_CURRENT;
17185        }
17186
17187        final UserStartedState uss = mStartedUsers.get(userId);
17188        if (uss == null) {
17189            // User is not started, nothing to do...  but we do need to
17190            // callback if requested.
17191            if (callback != null) {
17192                mHandler.post(new Runnable() {
17193                    @Override
17194                    public void run() {
17195                        try {
17196                            callback.userStopped(userId);
17197                        } catch (RemoteException e) {
17198                        }
17199                    }
17200                });
17201            }
17202            return ActivityManager.USER_OP_SUCCESS;
17203        }
17204
17205        if (callback != null) {
17206            uss.mStopCallbacks.add(callback);
17207        }
17208
17209        if (uss.mState != UserStartedState.STATE_STOPPING
17210                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17211            uss.mState = UserStartedState.STATE_STOPPING;
17212            updateStartedUserArrayLocked();
17213
17214            long ident = Binder.clearCallingIdentity();
17215            try {
17216                // We are going to broadcast ACTION_USER_STOPPING and then
17217                // once that is done send a final ACTION_SHUTDOWN and then
17218                // stop the user.
17219                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17220                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17221                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17222                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17223                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17224                // This is the result receiver for the final shutdown broadcast.
17225                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17226                    @Override
17227                    public void performReceive(Intent intent, int resultCode, String data,
17228                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17229                        finishUserStop(uss);
17230                    }
17231                };
17232                // This is the result receiver for the initial stopping broadcast.
17233                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17234                    @Override
17235                    public void performReceive(Intent intent, int resultCode, String data,
17236                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17237                        // On to the next.
17238                        synchronized (ActivityManagerService.this) {
17239                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17240                                // Whoops, we are being started back up.  Abort, abort!
17241                                return;
17242                            }
17243                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17244                        }
17245                        mSystemServiceManager.stopUser(userId);
17246                        broadcastIntentLocked(null, null, shutdownIntent,
17247                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17248                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17249                    }
17250                };
17251                // Kick things off.
17252                broadcastIntentLocked(null, null, stoppingIntent,
17253                        null, stoppingReceiver, 0, null, null,
17254                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17255                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17256            } finally {
17257                Binder.restoreCallingIdentity(ident);
17258            }
17259        }
17260
17261        return ActivityManager.USER_OP_SUCCESS;
17262    }
17263
17264    void finishUserStop(UserStartedState uss) {
17265        final int userId = uss.mHandle.getIdentifier();
17266        boolean stopped;
17267        ArrayList<IStopUserCallback> callbacks;
17268        synchronized (this) {
17269            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17270            if (mStartedUsers.get(userId) != uss) {
17271                stopped = false;
17272            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17273                stopped = false;
17274            } else {
17275                stopped = true;
17276                // User can no longer run.
17277                mStartedUsers.remove(userId);
17278                mUserLru.remove(Integer.valueOf(userId));
17279                updateStartedUserArrayLocked();
17280
17281                // Clean up all state and processes associated with the user.
17282                // Kill all the processes for the user.
17283                forceStopUserLocked(userId, "finish user");
17284            }
17285        }
17286
17287        for (int i=0; i<callbacks.size(); i++) {
17288            try {
17289                if (stopped) callbacks.get(i).userStopped(userId);
17290                else callbacks.get(i).userStopAborted(userId);
17291            } catch (RemoteException e) {
17292            }
17293        }
17294
17295        if (stopped) {
17296            mSystemServiceManager.cleanupUser(userId);
17297            synchronized (this) {
17298                mStackSupervisor.removeUserLocked(userId);
17299            }
17300        }
17301    }
17302
17303    @Override
17304    public UserInfo getCurrentUser() {
17305        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17306                != PackageManager.PERMISSION_GRANTED) && (
17307                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17308                != PackageManager.PERMISSION_GRANTED)) {
17309            String msg = "Permission Denial: getCurrentUser() from pid="
17310                    + Binder.getCallingPid()
17311                    + ", uid=" + Binder.getCallingUid()
17312                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17313            Slog.w(TAG, msg);
17314            throw new SecurityException(msg);
17315        }
17316        synchronized (this) {
17317            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17318        }
17319    }
17320
17321    int getCurrentUserIdLocked() {
17322        return mCurrentUserId;
17323    }
17324
17325    @Override
17326    public boolean isUserRunning(int userId, boolean orStopped) {
17327        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17328                != PackageManager.PERMISSION_GRANTED) {
17329            String msg = "Permission Denial: isUserRunning() from pid="
17330                    + Binder.getCallingPid()
17331                    + ", uid=" + Binder.getCallingUid()
17332                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17333            Slog.w(TAG, msg);
17334            throw new SecurityException(msg);
17335        }
17336        synchronized (this) {
17337            return isUserRunningLocked(userId, orStopped);
17338        }
17339    }
17340
17341    boolean isUserRunningLocked(int userId, boolean orStopped) {
17342        UserStartedState state = mStartedUsers.get(userId);
17343        if (state == null) {
17344            return false;
17345        }
17346        if (orStopped) {
17347            return true;
17348        }
17349        return state.mState != UserStartedState.STATE_STOPPING
17350                && state.mState != UserStartedState.STATE_SHUTDOWN;
17351    }
17352
17353    @Override
17354    public int[] getRunningUserIds() {
17355        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17356                != PackageManager.PERMISSION_GRANTED) {
17357            String msg = "Permission Denial: isUserRunning() from pid="
17358                    + Binder.getCallingPid()
17359                    + ", uid=" + Binder.getCallingUid()
17360                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17361            Slog.w(TAG, msg);
17362            throw new SecurityException(msg);
17363        }
17364        synchronized (this) {
17365            return mStartedUserArray;
17366        }
17367    }
17368
17369    private void updateStartedUserArrayLocked() {
17370        int num = 0;
17371        for (int i=0; i<mStartedUsers.size();  i++) {
17372            UserStartedState uss = mStartedUsers.valueAt(i);
17373            // This list does not include stopping users.
17374            if (uss.mState != UserStartedState.STATE_STOPPING
17375                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17376                num++;
17377            }
17378        }
17379        mStartedUserArray = new int[num];
17380        num = 0;
17381        for (int i=0; i<mStartedUsers.size();  i++) {
17382            UserStartedState uss = mStartedUsers.valueAt(i);
17383            if (uss.mState != UserStartedState.STATE_STOPPING
17384                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17385                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17386                num++;
17387            }
17388        }
17389    }
17390
17391    @Override
17392    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17393        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17394                != PackageManager.PERMISSION_GRANTED) {
17395            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17396                    + Binder.getCallingPid()
17397                    + ", uid=" + Binder.getCallingUid()
17398                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17399            Slog.w(TAG, msg);
17400            throw new SecurityException(msg);
17401        }
17402
17403        mUserSwitchObservers.register(observer);
17404    }
17405
17406    @Override
17407    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17408        mUserSwitchObservers.unregister(observer);
17409    }
17410
17411    private boolean userExists(int userId) {
17412        if (userId == 0) {
17413            return true;
17414        }
17415        UserManagerService ums = getUserManagerLocked();
17416        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17417    }
17418
17419    int[] getUsersLocked() {
17420        UserManagerService ums = getUserManagerLocked();
17421        return ums != null ? ums.getUserIds() : new int[] { 0 };
17422    }
17423
17424    UserManagerService getUserManagerLocked() {
17425        if (mUserManager == null) {
17426            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17427            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17428        }
17429        return mUserManager;
17430    }
17431
17432    private int applyUserId(int uid, int userId) {
17433        return UserHandle.getUid(userId, uid);
17434    }
17435
17436    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17437        if (info == null) return null;
17438        ApplicationInfo newInfo = new ApplicationInfo(info);
17439        newInfo.uid = applyUserId(info.uid, userId);
17440        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17441                + info.packageName;
17442        return newInfo;
17443    }
17444
17445    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17446        if (aInfo == null
17447                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17448            return aInfo;
17449        }
17450
17451        ActivityInfo info = new ActivityInfo(aInfo);
17452        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17453        return info;
17454    }
17455
17456    private final class LocalService extends ActivityManagerInternal {
17457        @Override
17458        public void goingToSleep() {
17459            ActivityManagerService.this.goingToSleep();
17460        }
17461
17462        @Override
17463        public void wakingUp() {
17464            ActivityManagerService.this.wakingUp();
17465        }
17466    }
17467
17468    /**
17469     * An implementation of IAppTask, that allows an app to manage its own tasks via
17470     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17471     * only the process that calls getAppTasks() can call the AppTask methods.
17472     */
17473    class AppTaskImpl extends IAppTask.Stub {
17474        private int mTaskId;
17475        private int mCallingUid;
17476
17477        public AppTaskImpl(int taskId, int callingUid) {
17478            mTaskId = taskId;
17479            mCallingUid = callingUid;
17480        }
17481
17482        @Override
17483        public void finishAndRemoveTask() {
17484            // Ensure that we are called from the same process that created this AppTask
17485            if (mCallingUid != Binder.getCallingUid()) {
17486                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17487                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17488                return;
17489            }
17490
17491            synchronized (ActivityManagerService.this) {
17492                long origId = Binder.clearCallingIdentity();
17493                try {
17494                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17495                    if (tr != null) {
17496                        // Only kill the process if we are not a new document
17497                        int flags = tr.getBaseIntent().getFlags();
17498                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17499                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17500                        removeTaskByIdLocked(mTaskId,
17501                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17502                    }
17503                } finally {
17504                    Binder.restoreCallingIdentity(origId);
17505                }
17506            }
17507        }
17508
17509        @Override
17510        public ActivityManager.RecentTaskInfo getTaskInfo() {
17511            // Ensure that we are called from the same process that created this AppTask
17512            if (mCallingUid != Binder.getCallingUid()) {
17513                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17514                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17515                return null;
17516            }
17517
17518            synchronized (ActivityManagerService.this) {
17519                long origId = Binder.clearCallingIdentity();
17520                try {
17521                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17522                    if (tr != null) {
17523                        return createRecentTaskInfoFromTaskRecord(tr);
17524                    }
17525                } finally {
17526                    Binder.restoreCallingIdentity(origId);
17527                }
17528                return null;
17529            }
17530        }
17531    }
17532}
17533