ActivityManagerService.java revision 409297da182267465adbc21cfb75a23e8d678117
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;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.content.pm.PackageManager.PERMISSION_GRANTED;
22import static com.android.internal.util.XmlUtils.readBooleanAttribute;
23import static com.android.internal.util.XmlUtils.readIntAttribute;
24import static com.android.internal.util.XmlUtils.readLongAttribute;
25import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
26import static com.android.internal.util.XmlUtils.writeIntAttribute;
27import static com.android.internal.util.XmlUtils.writeLongAttribute;
28import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
29import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
30import static org.xmlpull.v1.XmlPullParser.START_TAG;
31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32
33import android.Manifest;
34import android.app.AppOpsManager;
35import android.app.IActivityContainer;
36import android.app.IActivityContainerCallback;
37import android.app.IAppTask;
38import android.app.admin.DevicePolicyManager;
39import android.appwidget.AppWidgetManager;
40import android.graphics.Rect;
41import android.os.BatteryStats;
42import android.os.PersistableBundle;
43import android.service.voice.IVoiceInteractionSession;
44import android.util.ArrayMap;
45
46import android.util.SparseIntArray;
47import com.android.internal.R;
48import com.android.internal.annotations.GuardedBy;
49import com.android.internal.app.IAppOpsService;
50import com.android.internal.app.IVoiceInteractor;
51import com.android.internal.app.ProcessMap;
52import com.android.internal.app.ProcessStats;
53import com.android.internal.content.PackageMonitor;
54import com.android.internal.os.BackgroundThread;
55import com.android.internal.os.BatteryStatsImpl;
56import com.android.internal.os.ProcessCpuTracker;
57import com.android.internal.os.TransferPipe;
58import com.android.internal.os.Zygote;
59import com.android.internal.util.FastPrintWriter;
60import com.android.internal.util.FastXmlSerializer;
61import com.android.internal.util.MemInfoReader;
62import com.android.internal.util.Preconditions;
63import com.android.server.AppOpsService;
64import com.android.server.AttributeCache;
65import com.android.server.IntentResolver;
66import com.android.server.LocalServices;
67import com.android.server.ServiceThread;
68import com.android.server.SystemService;
69import com.android.server.SystemServiceManager;
70import com.android.server.Watchdog;
71import com.android.server.am.ActivityStack.ActivityState;
72import com.android.server.firewall.IntentFirewall;
73import com.android.server.pm.UserManagerService;
74import com.android.server.wm.AppTransition;
75import com.android.server.wm.WindowManagerService;
76import com.google.android.collect.Lists;
77import com.google.android.collect.Maps;
78
79import libcore.io.IoUtils;
80
81import org.xmlpull.v1.XmlPullParser;
82import org.xmlpull.v1.XmlPullParserException;
83import org.xmlpull.v1.XmlSerializer;
84
85import android.app.Activity;
86import android.app.ActivityManager;
87import android.app.ActivityManager.RunningTaskInfo;
88import android.app.ActivityManager.StackInfo;
89import android.app.ActivityManagerInternal;
90import android.app.ActivityManagerNative;
91import android.app.ActivityOptions;
92import android.app.ActivityThread;
93import android.app.AlertDialog;
94import android.app.AppGlobals;
95import android.app.ApplicationErrorReport;
96import android.app.Dialog;
97import android.app.IActivityController;
98import android.app.IApplicationThread;
99import android.app.IInstrumentationWatcher;
100import android.app.INotificationManager;
101import android.app.IProcessObserver;
102import android.app.IServiceConnection;
103import android.app.IStopUserCallback;
104import android.app.IUiAutomationConnection;
105import android.app.IUserSwitchObserver;
106import android.app.Instrumentation;
107import android.app.Notification;
108import android.app.NotificationManager;
109import android.app.PendingIntent;
110import android.app.backup.IBackupManager;
111import android.content.ActivityNotFoundException;
112import android.content.BroadcastReceiver;
113import android.content.ClipData;
114import android.content.ComponentCallbacks2;
115import android.content.ComponentName;
116import android.content.ContentProvider;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.DialogInterface;
120import android.content.IContentProvider;
121import android.content.IIntentReceiver;
122import android.content.IIntentSender;
123import android.content.Intent;
124import android.content.IntentFilter;
125import android.content.IntentSender;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.ConfigurationInfo;
129import android.content.pm.IPackageDataObserver;
130import android.content.pm.IPackageManager;
131import android.content.pm.InstrumentationInfo;
132import android.content.pm.PackageInfo;
133import android.content.pm.PackageManager;
134import android.content.pm.ParceledListSlice;
135import android.content.pm.UserInfo;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PathPermission;
138import android.content.pm.ProviderInfo;
139import android.content.pm.ResolveInfo;
140import android.content.pm.ServiceInfo;
141import android.content.res.CompatibilityInfo;
142import android.content.res.Configuration;
143import android.net.Proxy;
144import android.net.ProxyInfo;
145import android.net.Uri;
146import android.os.Binder;
147import android.os.Build;
148import android.os.Bundle;
149import android.os.Debug;
150import android.os.DropBoxManager;
151import android.os.Environment;
152import android.os.FactoryTest;
153import android.os.FileObserver;
154import android.os.FileUtils;
155import android.os.Handler;
156import android.os.IBinder;
157import android.os.IPermissionController;
158import android.os.IRemoteCallback;
159import android.os.IUserManager;
160import android.os.Looper;
161import android.os.Message;
162import android.os.Parcel;
163import android.os.ParcelFileDescriptor;
164import android.os.Process;
165import android.os.RemoteCallbackList;
166import android.os.RemoteException;
167import android.os.SELinux;
168import android.os.ServiceManager;
169import android.os.StrictMode;
170import android.os.SystemClock;
171import android.os.SystemProperties;
172import android.os.UpdateLock;
173import android.os.UserHandle;
174import android.provider.Settings;
175import android.text.format.DateUtils;
176import android.text.format.Time;
177import android.util.AtomicFile;
178import android.util.EventLog;
179import android.util.Log;
180import android.util.Pair;
181import android.util.PrintWriterPrinter;
182import android.util.Slog;
183import android.util.SparseArray;
184import android.util.TimeUtils;
185import android.util.Xml;
186import android.view.Gravity;
187import android.view.LayoutInflater;
188import android.view.View;
189import android.view.WindowManager;
190
191import java.io.BufferedInputStream;
192import java.io.BufferedOutputStream;
193import java.io.DataInputStream;
194import java.io.DataOutputStream;
195import java.io.File;
196import java.io.FileDescriptor;
197import java.io.FileInputStream;
198import java.io.FileNotFoundException;
199import java.io.FileOutputStream;
200import java.io.IOException;
201import java.io.InputStreamReader;
202import java.io.PrintWriter;
203import java.io.StringWriter;
204import java.lang.ref.WeakReference;
205import java.util.ArrayList;
206import java.util.Arrays;
207import java.util.Collections;
208import java.util.Comparator;
209import java.util.HashMap;
210import java.util.HashSet;
211import java.util.Iterator;
212import java.util.List;
213import java.util.Locale;
214import java.util.Map;
215import java.util.Set;
216import java.util.concurrent.atomic.AtomicBoolean;
217import java.util.concurrent.atomic.AtomicLong;
218
219public final class ActivityManagerService extends ActivityManagerNative
220        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
221    private static final String USER_DATA_DIR = "/data/user/";
222    static final String TAG = "ActivityManager";
223    static final String TAG_MU = "ActivityManagerServiceMU";
224    static final boolean DEBUG = false;
225    static final boolean localLOGV = DEBUG;
226    static final boolean DEBUG_BACKUP = localLOGV || false;
227    static final boolean DEBUG_BROADCAST = localLOGV || false;
228    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
230    static final boolean DEBUG_CLEANUP = localLOGV || false;
231    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
232    static final boolean DEBUG_FOCUS = false;
233    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
234    static final boolean DEBUG_MU = localLOGV || false;
235    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
236    static final boolean DEBUG_LRU = localLOGV || false;
237    static final boolean DEBUG_PAUSE = localLOGV || false;
238    static final boolean DEBUG_POWER = localLOGV || false;
239    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
240    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
241    static final boolean DEBUG_PROCESSES = localLOGV || false;
242    static final boolean DEBUG_PROVIDER = localLOGV || false;
243    static final boolean DEBUG_RESULTS = localLOGV || false;
244    static final boolean DEBUG_SERVICE = localLOGV || false;
245    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
246    static final boolean DEBUG_STACK = localLOGV || false;
247    static final boolean DEBUG_SWITCH = localLOGV || false;
248    static final boolean DEBUG_TASKS = localLOGV || false;
249    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
250    static final boolean DEBUG_TRANSITION = localLOGV || false;
251    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
252    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
253    static final boolean DEBUG_VISBILITY = localLOGV || false;
254    static final boolean DEBUG_PSS = localLOGV || false;
255    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
256    static final boolean VALIDATE_TOKENS = false;
257    static final boolean SHOW_ACTIVITY_START_TIME = true;
258
259    // Control over CPU and battery monitoring.
260    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
261    static final boolean MONITOR_CPU_USAGE = true;
262    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
263    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
264    static final boolean MONITOR_THREAD_CPU_USAGE = false;
265
266    // The flags that are set for all calls we make to the package manager.
267    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
268
269    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
270
271    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
272
273    // Maximum number of recent tasks that we can remember.
274    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
275
276    // Maximum number recent bitmaps to keep in memory.
277    static final int MAX_RECENT_BITMAPS = 5;
278
279    // Amount of time after a call to stopAppSwitches() during which we will
280    // prevent further untrusted switches from happening.
281    static final long APP_SWITCH_DELAY_TIME = 5*1000;
282
283    // How long we wait for a launched process to attach to the activity manager
284    // before we decide it's never going to come up for real.
285    static final int PROC_START_TIMEOUT = 10*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, when the process was
289    // started with a wrapper for instrumentation (such as Valgrind) because it
290    // could take much longer than usual.
291    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
292
293    // How long to wait after going idle before forcing apps to GC.
294    static final int GC_TIMEOUT = 5*1000;
295
296    // The minimum amount of time between successive GC requests for a process.
297    static final int GC_MIN_INTERVAL = 60*1000;
298
299    // The minimum amount of time between successive PSS requests for a process.
300    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
301
302    // The minimum amount of time between successive PSS requests for a process
303    // when the request is due to the memory state being lowered.
304    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
305
306    // The rate at which we check for apps using excessive power -- 15 mins.
307    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
308
309    // The minimum sample duration we will allow before deciding we have
310    // enough data on wake locks to start killing things.
311    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
312
313    // The minimum sample duration we will allow before deciding we have
314    // enough data on CPU usage to start killing things.
315    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
316
317    // How long we allow a receiver to run before giving up on it.
318    static final int BROADCAST_FG_TIMEOUT = 10*1000;
319    static final int BROADCAST_BG_TIMEOUT = 60*1000;
320
321    // How long we wait until we timeout on key dispatching.
322    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
323
324    // How long we wait until we timeout on key dispatching during instrumentation.
325    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
326
327    // Amount of time we wait for observers to handle a user switch before
328    // giving up on them and unfreezing the screen.
329    static final int USER_SWITCH_TIMEOUT = 2*1000;
330
331    // Maximum number of users we allow to be running at a time.
332    static final int MAX_RUNNING_USERS = 3;
333
334    // How long to wait in getAssistContextExtras for the activity and foreground services
335    // to respond with the result.
336    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
337
338    // Maximum number of persisted Uri grants a package is allowed
339    static final int MAX_PERSISTED_URI_GRANTS = 128;
340
341    static final int MY_PID = Process.myPid();
342
343    static final String[] EMPTY_STRING_ARRAY = new String[0];
344
345    // How many bytes to write into the dropbox log before truncating
346    static final int DROPBOX_MAX_SIZE = 256 * 1024;
347
348    // Access modes for handleIncomingUser.
349    static final int ALLOW_NON_FULL = 0;
350    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
351    static final int ALLOW_FULL_ONLY = 2;
352
353    /** All system services */
354    SystemServiceManager mSystemServiceManager;
355
356    /** Run all ActivityStacks through this */
357    ActivityStackSupervisor mStackSupervisor;
358
359    public IntentFirewall mIntentFirewall;
360
361    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
362    // default actuion automatically.  Important for devices without direct input
363    // devices.
364    private boolean mShowDialogs = true;
365
366    /**
367     * Description of a request to start a new activity, which has been held
368     * due to app switches being disabled.
369     */
370    static class PendingActivityLaunch {
371        final ActivityRecord r;
372        final ActivityRecord sourceRecord;
373        final int startFlags;
374        final ActivityStack stack;
375
376        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
377                int _startFlags, ActivityStack _stack) {
378            r = _r;
379            sourceRecord = _sourceRecord;
380            startFlags = _startFlags;
381            stack = _stack;
382        }
383    }
384
385    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
386            = new ArrayList<PendingActivityLaunch>();
387
388    BroadcastQueue mFgBroadcastQueue;
389    BroadcastQueue mBgBroadcastQueue;
390    // Convenient for easy iteration over the queues. Foreground is first
391    // so that dispatch of foreground broadcasts gets precedence.
392    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
393
394    BroadcastQueue broadcastQueueForIntent(Intent intent) {
395        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
396        if (DEBUG_BACKGROUND_BROADCAST) {
397            Slog.i(TAG, "Broadcast intent " + intent + " on "
398                    + (isFg ? "foreground" : "background")
399                    + " queue");
400        }
401        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
402    }
403
404    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
405        for (BroadcastQueue queue : mBroadcastQueues) {
406            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
407            if (r != null) {
408                return r;
409            }
410        }
411        return null;
412    }
413
414    /**
415     * Activity we have told the window manager to have key focus.
416     */
417    ActivityRecord mFocusedActivity = null;
418
419    /**
420     * List of intents that were used to start the most recent tasks.
421     */
422    ArrayList<TaskRecord> mRecentTasks;
423
424    public class PendingAssistExtras extends Binder implements Runnable {
425        public final ActivityRecord activity;
426        public boolean haveResult = false;
427        public Bundle result = null;
428        public PendingAssistExtras(ActivityRecord _activity) {
429            activity = _activity;
430        }
431        @Override
432        public void run() {
433            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
434            synchronized (this) {
435                haveResult = true;
436                notifyAll();
437            }
438        }
439    }
440
441    final ArrayList<PendingAssistExtras> mPendingAssistExtras
442            = new ArrayList<PendingAssistExtras>();
443
444    /**
445     * Process management.
446     */
447    final ProcessList mProcessList = new ProcessList();
448
449    /**
450     * All of the applications we currently have running organized by name.
451     * The keys are strings of the application package name (as
452     * returned by the package manager), and the keys are ApplicationRecord
453     * objects.
454     */
455    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
456
457    /**
458     * Tracking long-term execution of processes to look for abuse and other
459     * bad app behavior.
460     */
461    final ProcessStatsService mProcessStats;
462
463    /**
464     * The currently running isolated processes.
465     */
466    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
467
468    /**
469     * Counter for assigning isolated process uids, to avoid frequently reusing the
470     * same ones.
471     */
472    int mNextIsolatedProcessUid = 0;
473
474    /**
475     * The currently running heavy-weight process, if any.
476     */
477    ProcessRecord mHeavyWeightProcess = null;
478
479    /**
480     * The last time that various processes have crashed.
481     */
482    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
483
484    /**
485     * Information about a process that is currently marked as bad.
486     */
487    static final class BadProcessInfo {
488        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
489            this.time = time;
490            this.shortMsg = shortMsg;
491            this.longMsg = longMsg;
492            this.stack = stack;
493        }
494
495        final long time;
496        final String shortMsg;
497        final String longMsg;
498        final String stack;
499    }
500
501    /**
502     * Set of applications that we consider to be bad, and will reject
503     * incoming broadcasts from (which the user has no control over).
504     * Processes are added to this set when they have crashed twice within
505     * a minimum amount of time; they are removed from it when they are
506     * later restarted (hopefully due to some user action).  The value is the
507     * time it was added to the list.
508     */
509    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
510
511    /**
512     * All of the processes we currently have running organized by pid.
513     * The keys are the pid running the application.
514     *
515     * <p>NOTE: This object is protected by its own lock, NOT the global
516     * activity manager lock!
517     */
518    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
519
520    /**
521     * All of the processes that have been forced to be foreground.  The key
522     * is the pid of the caller who requested it (we hold a death
523     * link on it).
524     */
525    abstract class ForegroundToken implements IBinder.DeathRecipient {
526        int pid;
527        IBinder token;
528    }
529    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
530
531    /**
532     * List of records for processes that someone had tried to start before the
533     * system was ready.  We don't start them at that point, but ensure they
534     * are started by the time booting is complete.
535     */
536    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of persistent applications that are in the process
540     * of being started.
541     */
542    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Processes that are being forcibly torn down.
546     */
547    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
548
549    /**
550     * List of running applications, sorted by recent usage.
551     * The first entry in the list is the least recently used.
552     */
553    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
554
555    /**
556     * Where in mLruProcesses that the processes hosting activities start.
557     */
558    int mLruProcessActivityStart = 0;
559
560    /**
561     * Where in mLruProcesses that the processes hosting services start.
562     * This is after (lower index) than mLruProcessesActivityStart.
563     */
564    int mLruProcessServiceStart = 0;
565
566    /**
567     * List of processes that should gc as soon as things are idle.
568     */
569    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
570
571    /**
572     * Processes we want to collect PSS data from.
573     */
574    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
575
576    /**
577     * Last time we requested PSS data of all processes.
578     */
579    long mLastFullPssTime = SystemClock.uptimeMillis();
580
581    /**
582     * If set, the next time we collect PSS data we should do a full collection
583     * with data from native processes and the kernel.
584     */
585    boolean mFullPssPending = false;
586
587    /**
588     * This is the process holding what we currently consider to be
589     * the "home" activity.
590     */
591    ProcessRecord mHomeProcess;
592
593    /**
594     * This is the process holding the activity the user last visited that
595     * is in a different process from the one they are currently in.
596     */
597    ProcessRecord mPreviousProcess;
598
599    /**
600     * The time at which the previous process was last visible.
601     */
602    long mPreviousProcessVisibleTime;
603
604    /**
605     * Which uses have been started, so are allowed to run code.
606     */
607    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
608
609    /**
610     * LRU list of history of current users.  Most recently current is at the end.
611     */
612    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
613
614    /**
615     * Constant array of the users that are currently started.
616     */
617    int[] mStartedUserArray = new int[] { 0 };
618
619    /**
620     * Registered observers of the user switching mechanics.
621     */
622    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
623            = new RemoteCallbackList<IUserSwitchObserver>();
624
625    /**
626     * Currently active user switch.
627     */
628    Object mCurUserSwitchCallback;
629
630    /**
631     * Packages that the user has asked to have run in screen size
632     * compatibility mode instead of filling the screen.
633     */
634    final CompatModePackages mCompatModePackages;
635
636    /**
637     * Set of IntentSenderRecord objects that are currently active.
638     */
639    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
640            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
641
642    /**
643     * Fingerprints (hashCode()) of stack traces that we've
644     * already logged DropBox entries for.  Guarded by itself.  If
645     * something (rogue user app) forces this over
646     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
647     */
648    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
649    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
650
651    /**
652     * Strict Mode background batched logging state.
653     *
654     * The string buffer is guarded by itself, and its lock is also
655     * used to determine if another batched write is already
656     * in-flight.
657     */
658    private final StringBuilder mStrictModeBuffer = new StringBuilder();
659
660    /**
661     * Keeps track of all IIntentReceivers that have been registered for
662     * broadcasts.  Hash keys are the receiver IBinder, hash value is
663     * a ReceiverList.
664     */
665    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
666            new HashMap<IBinder, ReceiverList>();
667
668    /**
669     * Resolver for broadcast intents to registered receivers.
670     * Holds BroadcastFilter (subclass of IntentFilter).
671     */
672    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
673            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
674        @Override
675        protected boolean allowFilterResult(
676                BroadcastFilter filter, List<BroadcastFilter> dest) {
677            IBinder target = filter.receiverList.receiver.asBinder();
678            for (int i=dest.size()-1; i>=0; i--) {
679                if (dest.get(i).receiverList.receiver.asBinder() == target) {
680                    return false;
681                }
682            }
683            return true;
684        }
685
686        @Override
687        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
688            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
689                    || userId == filter.owningUserId) {
690                return super.newResult(filter, match, userId);
691            }
692            return null;
693        }
694
695        @Override
696        protected BroadcastFilter[] newArray(int size) {
697            return new BroadcastFilter[size];
698        }
699
700        @Override
701        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
702            return packageName.equals(filter.packageName);
703        }
704    };
705
706    /**
707     * State of all active sticky broadcasts per user.  Keys are the action of the
708     * sticky Intent, values are an ArrayList of all broadcasted intents with
709     * that action (which should usually be one).  The SparseArray is keyed
710     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
711     * for stickies that are sent to all users.
712     */
713    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
714            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
715
716    final ActiveServices mServices;
717
718    /**
719     * Backup/restore process management
720     */
721    String mBackupAppName = null;
722    BackupRecord mBackupTarget = null;
723
724    final ProviderMap mProviderMap;
725
726    /**
727     * List of content providers who have clients waiting for them.  The
728     * application is currently being launched and the provider will be
729     * removed from this list once it is published.
730     */
731    final ArrayList<ContentProviderRecord> mLaunchingProviders
732            = new ArrayList<ContentProviderRecord>();
733
734    /**
735     * File storing persisted {@link #mGrantedUriPermissions}.
736     */
737    private final AtomicFile mGrantFile;
738
739    /** XML constants used in {@link #mGrantFile} */
740    private static final String TAG_URI_GRANTS = "uri-grants";
741    private static final String TAG_URI_GRANT = "uri-grant";
742    private static final String ATTR_USER_HANDLE = "userHandle";
743    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
744    private static final String ATTR_TARGET_USER_ID = "targetUserId";
745    private static final String ATTR_SOURCE_PKG = "sourcePkg";
746    private static final String ATTR_TARGET_PKG = "targetPkg";
747    private static final String ATTR_URI = "uri";
748    private static final String ATTR_MODE_FLAGS = "modeFlags";
749    private static final String ATTR_CREATED_TIME = "createdTime";
750    private static final String ATTR_PREFIX = "prefix";
751
752    /**
753     * Global set of specific {@link Uri} permissions that have been granted.
754     * This optimized lookup structure maps from {@link UriPermission#targetUid}
755     * to {@link UriPermission#uri} to {@link UriPermission}.
756     */
757    @GuardedBy("this")
758    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
759            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
760
761    public static class GrantUri {
762        public final int sourceUserId;
763        public final Uri uri;
764        public boolean prefix;
765
766        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
767            this.sourceUserId = sourceUserId;
768            this.uri = uri;
769            this.prefix = prefix;
770        }
771
772        @Override
773        public int hashCode() {
774            return toString().hashCode();
775        }
776
777        @Override
778        public boolean equals(Object o) {
779            if (o instanceof GrantUri) {
780                GrantUri other = (GrantUri) o;
781                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
782                        && prefix == other.prefix;
783            }
784            return false;
785        }
786
787        @Override
788        public String toString() {
789            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
790            if (prefix) result += " [prefix]";
791            return result;
792        }
793
794        public String toSafeString() {
795            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
796            if (prefix) result += " [prefix]";
797            return result;
798        }
799
800        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
801            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
802                    ContentProvider.getUriWithoutUserId(uri), false);
803        }
804    }
805
806    CoreSettingsObserver mCoreSettingsObserver;
807
808    /**
809     * Thread-local storage used to carry caller permissions over through
810     * indirect content-provider access.
811     */
812    private class Identity {
813        public int pid;
814        public int uid;
815
816        Identity(int _pid, int _uid) {
817            pid = _pid;
818            uid = _uid;
819        }
820    }
821
822    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
823
824    /**
825     * All information we have collected about the runtime performance of
826     * any user id that can impact battery performance.
827     */
828    final BatteryStatsService mBatteryStatsService;
829
830    /**
831     * Information about component usage
832     */
833    final UsageStatsService mUsageStatsService;
834
835    /**
836     * Information about and control over application operations
837     */
838    final AppOpsService mAppOpsService;
839
840    /**
841     * Save recent tasks information across reboots.
842     */
843    final TaskPersister mTaskPersister;
844
845    /**
846     * Current configuration information.  HistoryRecord objects are given
847     * a reference to this object to indicate which configuration they are
848     * currently running in, so this object must be kept immutable.
849     */
850    Configuration mConfiguration = new Configuration();
851
852    /**
853     * Current sequencing integer of the configuration, for skipping old
854     * configurations.
855     */
856    int mConfigurationSeq = 0;
857
858    /**
859     * Hardware-reported OpenGLES version.
860     */
861    final int GL_ES_VERSION;
862
863    /**
864     * List of initialization arguments to pass to all processes when binding applications to them.
865     * For example, references to the commonly used services.
866     */
867    HashMap<String, IBinder> mAppBindArgs;
868
869    /**
870     * Temporary to avoid allocations.  Protected by main lock.
871     */
872    final StringBuilder mStringBuilder = new StringBuilder(256);
873
874    /**
875     * Used to control how we initialize the service.
876     */
877    ComponentName mTopComponent;
878    String mTopAction = Intent.ACTION_MAIN;
879    String mTopData;
880    boolean mProcessesReady = false;
881    boolean mSystemReady = false;
882    boolean mBooting = false;
883    boolean mWaitingUpdate = false;
884    boolean mDidUpdate = false;
885    boolean mOnBattery = false;
886    boolean mLaunchWarningShown = false;
887
888    Context mContext;
889
890    int mFactoryTest;
891
892    boolean mCheckedForSetup;
893
894    /**
895     * The time at which we will allow normal application switches again,
896     * after a call to {@link #stopAppSwitches()}.
897     */
898    long mAppSwitchesAllowedTime;
899
900    /**
901     * This is set to true after the first switch after mAppSwitchesAllowedTime
902     * is set; any switches after that will clear the time.
903     */
904    boolean mDidAppSwitch;
905
906    /**
907     * Last time (in realtime) at which we checked for power usage.
908     */
909    long mLastPowerCheckRealtime;
910
911    /**
912     * Last time (in uptime) at which we checked for power usage.
913     */
914    long mLastPowerCheckUptime;
915
916    /**
917     * Set while we are wanting to sleep, to prevent any
918     * activities from being started/resumed.
919     */
920    private boolean mSleeping = false;
921
922    /**
923     * Set while we are running a voice interaction.  This overrides
924     * sleeping while it is active.
925     */
926    private boolean mRunningVoice = false;
927
928    /**
929     * State of external calls telling us if the device is asleep.
930     */
931    private boolean mWentToSleep = false;
932
933    /**
934     * State of external call telling us if the lock screen is shown.
935     */
936    private boolean mLockScreenShown = false;
937
938    /**
939     * Set if we are shutting down the system, similar to sleeping.
940     */
941    boolean mShuttingDown = false;
942
943    /**
944     * Current sequence id for oom_adj computation traversal.
945     */
946    int mAdjSeq = 0;
947
948    /**
949     * Current sequence id for process LRU updating.
950     */
951    int mLruSeq = 0;
952
953    /**
954     * Keep track of the non-cached/empty process we last found, to help
955     * determine how to distribute cached/empty processes next time.
956     */
957    int mNumNonCachedProcs = 0;
958
959    /**
960     * Keep track of the number of cached hidden procs, to balance oom adj
961     * distribution between those and empty procs.
962     */
963    int mNumCachedHiddenProcs = 0;
964
965    /**
966     * Keep track of the number of service processes we last found, to
967     * determine on the next iteration which should be B services.
968     */
969    int mNumServiceProcs = 0;
970    int mNewNumAServiceProcs = 0;
971    int mNewNumServiceProcs = 0;
972
973    /**
974     * Allow the current computed overall memory level of the system to go down?
975     * This is set to false when we are killing processes for reasons other than
976     * memory management, so that the now smaller process list will not be taken as
977     * an indication that memory is tighter.
978     */
979    boolean mAllowLowerMemLevel = false;
980
981    /**
982     * The last computed memory level, for holding when we are in a state that
983     * processes are going away for other reasons.
984     */
985    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
986
987    /**
988     * The last total number of process we have, to determine if changes actually look
989     * like a shrinking number of process due to lower RAM.
990     */
991    int mLastNumProcesses;
992
993    /**
994     * The uptime of the last time we performed idle maintenance.
995     */
996    long mLastIdleTime = SystemClock.uptimeMillis();
997
998    /**
999     * Total time spent with RAM that has been added in the past since the last idle time.
1000     */
1001    long mLowRamTimeSinceLastIdle = 0;
1002
1003    /**
1004     * If RAM is currently low, when that horrible situation started.
1005     */
1006    long mLowRamStartTime = 0;
1007
1008    /**
1009     * For reporting to battery stats the current top application.
1010     */
1011    private String mCurResumedPackage = null;
1012    private int mCurResumedUid = -1;
1013
1014    /**
1015     * For reporting to battery stats the apps currently running foreground
1016     * service.  The ProcessMap is package/uid tuples; each of these contain
1017     * an array of the currently foreground processes.
1018     */
1019    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1020            = new ProcessMap<ArrayList<ProcessRecord>>();
1021
1022    /**
1023     * This is set if we had to do a delayed dexopt of an app before launching
1024     * it, to increase the ANR timeouts in that case.
1025     */
1026    boolean mDidDexOpt;
1027
1028    /**
1029     * Set if the systemServer made a call to enterSafeMode.
1030     */
1031    boolean mSafeMode;
1032
1033    String mDebugApp = null;
1034    boolean mWaitForDebugger = false;
1035    boolean mDebugTransient = false;
1036    String mOrigDebugApp = null;
1037    boolean mOrigWaitForDebugger = false;
1038    boolean mAlwaysFinishActivities = false;
1039    IActivityController mController = null;
1040    String mProfileApp = null;
1041    ProcessRecord mProfileProc = null;
1042    String mProfileFile;
1043    ParcelFileDescriptor mProfileFd;
1044    int mProfileType = 0;
1045    boolean mAutoStopProfiler = false;
1046    String mOpenGlTraceApp = null;
1047
1048    static class ProcessChangeItem {
1049        static final int CHANGE_ACTIVITIES = 1<<0;
1050        static final int CHANGE_PROCESS_STATE = 1<<1;
1051        int changes;
1052        int uid;
1053        int pid;
1054        int processState;
1055        boolean foregroundActivities;
1056    }
1057
1058    final RemoteCallbackList<IProcessObserver> mProcessObservers
1059            = new RemoteCallbackList<IProcessObserver>();
1060    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1061
1062    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1063            = new ArrayList<ProcessChangeItem>();
1064    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1065            = new ArrayList<ProcessChangeItem>();
1066
1067    /**
1068     * Runtime CPU use collection thread.  This object's lock is used to
1069     * protect all related state.
1070     */
1071    final Thread mProcessCpuThread;
1072
1073    /**
1074     * Used to collect process stats when showing not responding dialog.
1075     * Protected by mProcessCpuThread.
1076     */
1077    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1078            MONITOR_THREAD_CPU_USAGE);
1079    final AtomicLong mLastCpuTime = new AtomicLong(0);
1080    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1081
1082    long mLastWriteTime = 0;
1083
1084    /**
1085     * Used to retain an update lock when the foreground activity is in
1086     * immersive mode.
1087     */
1088    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1089
1090    /**
1091     * Set to true after the system has finished booting.
1092     */
1093    boolean mBooted = false;
1094
1095    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1096    int mProcessLimitOverride = -1;
1097
1098    WindowManagerService mWindowManager;
1099
1100    final ActivityThread mSystemThread;
1101
1102    int mCurrentUserId = 0;
1103    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1104
1105    /**
1106     * Mapping from each known user ID to the profile group ID it is associated with.
1107     */
1108    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1109
1110    private UserManagerService mUserManager;
1111
1112    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1113        final ProcessRecord mApp;
1114        final int mPid;
1115        final IApplicationThread mAppThread;
1116
1117        AppDeathRecipient(ProcessRecord app, int pid,
1118                IApplicationThread thread) {
1119            if (localLOGV) Slog.v(
1120                TAG, "New death recipient " + this
1121                + " for thread " + thread.asBinder());
1122            mApp = app;
1123            mPid = pid;
1124            mAppThread = thread;
1125        }
1126
1127        @Override
1128        public void binderDied() {
1129            if (localLOGV) Slog.v(
1130                TAG, "Death received in " + this
1131                + " for thread " + mAppThread.asBinder());
1132            synchronized(ActivityManagerService.this) {
1133                appDiedLocked(mApp, mPid, mAppThread);
1134            }
1135        }
1136    }
1137
1138    static final int SHOW_ERROR_MSG = 1;
1139    static final int SHOW_NOT_RESPONDING_MSG = 2;
1140    static final int SHOW_FACTORY_ERROR_MSG = 3;
1141    static final int UPDATE_CONFIGURATION_MSG = 4;
1142    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1143    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1144    static final int SERVICE_TIMEOUT_MSG = 12;
1145    static final int UPDATE_TIME_ZONE = 13;
1146    static final int SHOW_UID_ERROR_MSG = 14;
1147    static final int IM_FEELING_LUCKY_MSG = 15;
1148    static final int PROC_START_TIMEOUT_MSG = 20;
1149    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1150    static final int KILL_APPLICATION_MSG = 22;
1151    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1152    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1153    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1154    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1155    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1156    static final int CLEAR_DNS_CACHE_MSG = 28;
1157    static final int UPDATE_HTTP_PROXY_MSG = 29;
1158    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1159    static final int DISPATCH_PROCESSES_CHANGED = 31;
1160    static final int DISPATCH_PROCESS_DIED = 32;
1161    static final int REPORT_MEM_USAGE_MSG = 33;
1162    static final int REPORT_USER_SWITCH_MSG = 34;
1163    static final int CONTINUE_USER_SWITCH_MSG = 35;
1164    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1165    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1166    static final int PERSIST_URI_GRANTS_MSG = 38;
1167    static final int REQUEST_ALL_PSS_MSG = 39;
1168    static final int START_PROFILES_MSG = 40;
1169    static final int UPDATE_TIME = 41;
1170    static final int SYSTEM_USER_START_MSG = 42;
1171    static final int SYSTEM_USER_CURRENT_MSG = 43;
1172
1173    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1174    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1175    static final int FIRST_COMPAT_MODE_MSG = 300;
1176    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1177
1178    AlertDialog mUidAlert;
1179    CompatModeDialog mCompatModeDialog;
1180    long mLastMemUsageReportTime = 0;
1181
1182    private LockToAppRequestDialog mLockToAppRequest;
1183
1184    /**
1185     * Flag whether the current user is a "monkey", i.e. whether
1186     * the UI is driven by a UI automation tool.
1187     */
1188    private boolean mUserIsMonkey;
1189
1190    final ServiceThread mHandlerThread;
1191    final MainHandler mHandler;
1192
1193    final class MainHandler extends Handler {
1194        public MainHandler(Looper looper) {
1195            super(looper, null, true);
1196        }
1197
1198        @Override
1199        public void handleMessage(Message msg) {
1200            switch (msg.what) {
1201            case SHOW_ERROR_MSG: {
1202                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1203                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1204                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1205                synchronized (ActivityManagerService.this) {
1206                    ProcessRecord proc = (ProcessRecord)data.get("app");
1207                    AppErrorResult res = (AppErrorResult) data.get("result");
1208                    if (proc != null && proc.crashDialog != null) {
1209                        Slog.e(TAG, "App already has crash dialog: " + proc);
1210                        if (res != null) {
1211                            res.set(0);
1212                        }
1213                        return;
1214                    }
1215                    if (!showBackground && UserHandle.getAppId(proc.uid)
1216                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1217                            && proc.pid != MY_PID) {
1218                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1219                        if (res != null) {
1220                            res.set(0);
1221                        }
1222                        return;
1223                    }
1224                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1225                        Dialog d = new AppErrorDialog(mContext,
1226                                ActivityManagerService.this, res, proc);
1227                        d.show();
1228                        proc.crashDialog = d;
1229                    } else {
1230                        // The device is asleep, so just pretend that the user
1231                        // saw a crash dialog and hit "force quit".
1232                        if (res != null) {
1233                            res.set(0);
1234                        }
1235                    }
1236                }
1237
1238                ensureBootCompleted();
1239            } break;
1240            case SHOW_NOT_RESPONDING_MSG: {
1241                synchronized (ActivityManagerService.this) {
1242                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1243                    ProcessRecord proc = (ProcessRecord)data.get("app");
1244                    if (proc != null && proc.anrDialog != null) {
1245                        Slog.e(TAG, "App already has anr dialog: " + proc);
1246                        return;
1247                    }
1248
1249                    Intent intent = new Intent("android.intent.action.ANR");
1250                    if (!mProcessesReady) {
1251                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1252                                | Intent.FLAG_RECEIVER_FOREGROUND);
1253                    }
1254                    broadcastIntentLocked(null, null, intent,
1255                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1256                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1257
1258                    if (mShowDialogs) {
1259                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1260                                mContext, proc, (ActivityRecord)data.get("activity"),
1261                                msg.arg1 != 0);
1262                        d.show();
1263                        proc.anrDialog = d;
1264                    } else {
1265                        // Just kill the app if there is no dialog to be shown.
1266                        killAppAtUsersRequest(proc, null);
1267                    }
1268                }
1269
1270                ensureBootCompleted();
1271            } break;
1272            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1273                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1274                synchronized (ActivityManagerService.this) {
1275                    ProcessRecord proc = (ProcessRecord) data.get("app");
1276                    if (proc == null) {
1277                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1278                        break;
1279                    }
1280                    if (proc.crashDialog != null) {
1281                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1282                        return;
1283                    }
1284                    AppErrorResult res = (AppErrorResult) data.get("result");
1285                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1286                        Dialog d = new StrictModeViolationDialog(mContext,
1287                                ActivityManagerService.this, res, proc);
1288                        d.show();
1289                        proc.crashDialog = d;
1290                    } else {
1291                        // The device is asleep, so just pretend that the user
1292                        // saw a crash dialog and hit "force quit".
1293                        res.set(0);
1294                    }
1295                }
1296                ensureBootCompleted();
1297            } break;
1298            case SHOW_FACTORY_ERROR_MSG: {
1299                Dialog d = new FactoryErrorDialog(
1300                    mContext, msg.getData().getCharSequence("msg"));
1301                d.show();
1302                ensureBootCompleted();
1303            } break;
1304            case UPDATE_CONFIGURATION_MSG: {
1305                final ContentResolver resolver = mContext.getContentResolver();
1306                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1307            } break;
1308            case GC_BACKGROUND_PROCESSES_MSG: {
1309                synchronized (ActivityManagerService.this) {
1310                    performAppGcsIfAppropriateLocked();
1311                }
1312            } break;
1313            case WAIT_FOR_DEBUGGER_MSG: {
1314                synchronized (ActivityManagerService.this) {
1315                    ProcessRecord app = (ProcessRecord)msg.obj;
1316                    if (msg.arg1 != 0) {
1317                        if (!app.waitedForDebugger) {
1318                            Dialog d = new AppWaitingForDebuggerDialog(
1319                                    ActivityManagerService.this,
1320                                    mContext, app);
1321                            app.waitDialog = d;
1322                            app.waitedForDebugger = true;
1323                            d.show();
1324                        }
1325                    } else {
1326                        if (app.waitDialog != null) {
1327                            app.waitDialog.dismiss();
1328                            app.waitDialog = null;
1329                        }
1330                    }
1331                }
1332            } break;
1333            case SERVICE_TIMEOUT_MSG: {
1334                if (mDidDexOpt) {
1335                    mDidDexOpt = false;
1336                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1337                    nmsg.obj = msg.obj;
1338                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1339                    return;
1340                }
1341                mServices.serviceTimeout((ProcessRecord)msg.obj);
1342            } break;
1343            case UPDATE_TIME_ZONE: {
1344                synchronized (ActivityManagerService.this) {
1345                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1346                        ProcessRecord r = mLruProcesses.get(i);
1347                        if (r.thread != null) {
1348                            try {
1349                                r.thread.updateTimeZone();
1350                            } catch (RemoteException ex) {
1351                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1352                            }
1353                        }
1354                    }
1355                }
1356            } break;
1357            case CLEAR_DNS_CACHE_MSG: {
1358                synchronized (ActivityManagerService.this) {
1359                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1360                        ProcessRecord r = mLruProcesses.get(i);
1361                        if (r.thread != null) {
1362                            try {
1363                                r.thread.clearDnsCache();
1364                            } catch (RemoteException ex) {
1365                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1366                            }
1367                        }
1368                    }
1369                }
1370            } break;
1371            case UPDATE_HTTP_PROXY_MSG: {
1372                ProxyInfo proxy = (ProxyInfo)msg.obj;
1373                String host = "";
1374                String port = "";
1375                String exclList = "";
1376                Uri pacFileUrl = Uri.EMPTY;
1377                if (proxy != null) {
1378                    host = proxy.getHost();
1379                    port = Integer.toString(proxy.getPort());
1380                    exclList = proxy.getExclusionListAsString();
1381                    pacFileUrl = proxy.getPacFileUrl();
1382                }
1383                synchronized (ActivityManagerService.this) {
1384                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1385                        ProcessRecord r = mLruProcesses.get(i);
1386                        if (r.thread != null) {
1387                            try {
1388                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1389                            } catch (RemoteException ex) {
1390                                Slog.w(TAG, "Failed to update http proxy for: " +
1391                                        r.info.processName);
1392                            }
1393                        }
1394                    }
1395                }
1396            } break;
1397            case SHOW_UID_ERROR_MSG: {
1398                String title = "System UIDs Inconsistent";
1399                String text = "UIDs on the system are inconsistent, you need to wipe your"
1400                        + " data partition or your device will be unstable.";
1401                Log.e(TAG, title + ": " + text);
1402                if (mShowDialogs) {
1403                    // XXX This is a temporary dialog, no need to localize.
1404                    AlertDialog d = new BaseErrorDialog(mContext);
1405                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1406                    d.setCancelable(false);
1407                    d.setTitle(title);
1408                    d.setMessage(text);
1409                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1410                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1411                    mUidAlert = d;
1412                    d.show();
1413                }
1414            } break;
1415            case IM_FEELING_LUCKY_MSG: {
1416                if (mUidAlert != null) {
1417                    mUidAlert.dismiss();
1418                    mUidAlert = null;
1419                }
1420            } break;
1421            case PROC_START_TIMEOUT_MSG: {
1422                if (mDidDexOpt) {
1423                    mDidDexOpt = false;
1424                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1425                    nmsg.obj = msg.obj;
1426                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1427                    return;
1428                }
1429                ProcessRecord app = (ProcessRecord)msg.obj;
1430                synchronized (ActivityManagerService.this) {
1431                    processStartTimedOutLocked(app);
1432                }
1433            } break;
1434            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1435                synchronized (ActivityManagerService.this) {
1436                    doPendingActivityLaunchesLocked(true);
1437                }
1438            } break;
1439            case KILL_APPLICATION_MSG: {
1440                synchronized (ActivityManagerService.this) {
1441                    int appid = msg.arg1;
1442                    boolean restart = (msg.arg2 == 1);
1443                    Bundle bundle = (Bundle)msg.obj;
1444                    String pkg = bundle.getString("pkg");
1445                    String reason = bundle.getString("reason");
1446                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1447                            false, UserHandle.USER_ALL, reason);
1448                }
1449            } break;
1450            case FINALIZE_PENDING_INTENT_MSG: {
1451                ((PendingIntentRecord)msg.obj).completeFinalize();
1452            } break;
1453            case POST_HEAVY_NOTIFICATION_MSG: {
1454                INotificationManager inm = NotificationManager.getService();
1455                if (inm == null) {
1456                    return;
1457                }
1458
1459                ActivityRecord root = (ActivityRecord)msg.obj;
1460                ProcessRecord process = root.app;
1461                if (process == null) {
1462                    return;
1463                }
1464
1465                try {
1466                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1467                    String text = mContext.getString(R.string.heavy_weight_notification,
1468                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1469                    Notification notification = new Notification();
1470                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1471                    notification.when = 0;
1472                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1473                    notification.tickerText = text;
1474                    notification.defaults = 0; // please be quiet
1475                    notification.sound = null;
1476                    notification.vibrate = null;
1477                    notification.setLatestEventInfo(context, text,
1478                            mContext.getText(R.string.heavy_weight_notification_detail),
1479                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1480                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1481                                    new UserHandle(root.userId)));
1482
1483                    try {
1484                        int[] outId = new int[1];
1485                        inm.enqueueNotificationWithTag("android", "android", null,
1486                                R.string.heavy_weight_notification,
1487                                notification, outId, root.userId);
1488                    } catch (RuntimeException e) {
1489                        Slog.w(ActivityManagerService.TAG,
1490                                "Error showing notification for heavy-weight app", e);
1491                    } catch (RemoteException e) {
1492                    }
1493                } catch (NameNotFoundException e) {
1494                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1495                }
1496            } break;
1497            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1498                INotificationManager inm = NotificationManager.getService();
1499                if (inm == null) {
1500                    return;
1501                }
1502                try {
1503                    inm.cancelNotificationWithTag("android", null,
1504                            R.string.heavy_weight_notification,  msg.arg1);
1505                } catch (RuntimeException e) {
1506                    Slog.w(ActivityManagerService.TAG,
1507                            "Error canceling notification for service", e);
1508                } catch (RemoteException e) {
1509                }
1510            } break;
1511            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    checkExcessivePowerUsageLocked(true);
1514                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1515                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1516                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1517                }
1518            } break;
1519            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1520                synchronized (ActivityManagerService.this) {
1521                    ActivityRecord ar = (ActivityRecord)msg.obj;
1522                    if (mCompatModeDialog != null) {
1523                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1524                                ar.info.applicationInfo.packageName)) {
1525                            return;
1526                        }
1527                        mCompatModeDialog.dismiss();
1528                        mCompatModeDialog = null;
1529                    }
1530                    if (ar != null && false) {
1531                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1532                                ar.packageName)) {
1533                            int mode = mCompatModePackages.computeCompatModeLocked(
1534                                    ar.info.applicationInfo);
1535                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1536                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1537                                mCompatModeDialog = new CompatModeDialog(
1538                                        ActivityManagerService.this, mContext,
1539                                        ar.info.applicationInfo);
1540                                mCompatModeDialog.show();
1541                            }
1542                        }
1543                    }
1544                }
1545                break;
1546            }
1547            case DISPATCH_PROCESSES_CHANGED: {
1548                dispatchProcessesChanged();
1549                break;
1550            }
1551            case DISPATCH_PROCESS_DIED: {
1552                final int pid = msg.arg1;
1553                final int uid = msg.arg2;
1554                dispatchProcessDied(pid, uid);
1555                break;
1556            }
1557            case REPORT_MEM_USAGE_MSG: {
1558                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1559                Thread thread = new Thread() {
1560                    @Override public void run() {
1561                        final SparseArray<ProcessMemInfo> infoMap
1562                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1563                        for (int i=0, N=memInfos.size(); i<N; i++) {
1564                            ProcessMemInfo mi = memInfos.get(i);
1565                            infoMap.put(mi.pid, mi);
1566                        }
1567                        updateCpuStatsNow();
1568                        synchronized (mProcessCpuThread) {
1569                            final int N = mProcessCpuTracker.countStats();
1570                            for (int i=0; i<N; i++) {
1571                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1572                                if (st.vsize > 0) {
1573                                    long pss = Debug.getPss(st.pid, null);
1574                                    if (pss > 0) {
1575                                        if (infoMap.indexOfKey(st.pid) < 0) {
1576                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1577                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1578                                            mi.pss = pss;
1579                                            memInfos.add(mi);
1580                                        }
1581                                    }
1582                                }
1583                            }
1584                        }
1585
1586                        long totalPss = 0;
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589                            if (mi.pss == 0) {
1590                                mi.pss = Debug.getPss(mi.pid, null);
1591                            }
1592                            totalPss += mi.pss;
1593                        }
1594                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1595                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1596                                if (lhs.oomAdj != rhs.oomAdj) {
1597                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1598                                }
1599                                if (lhs.pss != rhs.pss) {
1600                                    return lhs.pss < rhs.pss ? 1 : -1;
1601                                }
1602                                return 0;
1603                            }
1604                        });
1605
1606                        StringBuilder tag = new StringBuilder(128);
1607                        StringBuilder stack = new StringBuilder(128);
1608                        tag.append("Low on memory -- ");
1609                        appendMemBucket(tag, totalPss, "total", false);
1610                        appendMemBucket(stack, totalPss, "total", true);
1611
1612                        StringBuilder logBuilder = new StringBuilder(1024);
1613                        logBuilder.append("Low on memory:\n");
1614
1615                        boolean firstLine = true;
1616                        int lastOomAdj = Integer.MIN_VALUE;
1617                        for (int i=0, N=memInfos.size(); i<N; i++) {
1618                            ProcessMemInfo mi = memInfos.get(i);
1619
1620                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1621                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1622                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1623                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1624                                if (lastOomAdj != mi.oomAdj) {
1625                                    lastOomAdj = mi.oomAdj;
1626                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1627                                        tag.append(" / ");
1628                                    }
1629                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1630                                        if (firstLine) {
1631                                            stack.append(":");
1632                                            firstLine = false;
1633                                        }
1634                                        stack.append("\n\t at ");
1635                                    } else {
1636                                        stack.append("$");
1637                                    }
1638                                } else {
1639                                    tag.append(" ");
1640                                    stack.append("$");
1641                                }
1642                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1643                                    appendMemBucket(tag, mi.pss, mi.name, false);
1644                                }
1645                                appendMemBucket(stack, mi.pss, mi.name, true);
1646                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1647                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1648                                    stack.append("(");
1649                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1650                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1651                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1652                                            stack.append(":");
1653                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1654                                        }
1655                                    }
1656                                    stack.append(")");
1657                                }
1658                            }
1659
1660                            logBuilder.append("  ");
1661                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1662                            logBuilder.append(' ');
1663                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1664                            logBuilder.append(' ');
1665                            ProcessList.appendRamKb(logBuilder, mi.pss);
1666                            logBuilder.append(" kB: ");
1667                            logBuilder.append(mi.name);
1668                            logBuilder.append(" (");
1669                            logBuilder.append(mi.pid);
1670                            logBuilder.append(") ");
1671                            logBuilder.append(mi.adjType);
1672                            logBuilder.append('\n');
1673                            if (mi.adjReason != null) {
1674                                logBuilder.append("                      ");
1675                                logBuilder.append(mi.adjReason);
1676                                logBuilder.append('\n');
1677                            }
1678                        }
1679
1680                        logBuilder.append("           ");
1681                        ProcessList.appendRamKb(logBuilder, totalPss);
1682                        logBuilder.append(" kB: TOTAL\n");
1683
1684                        long[] infos = new long[Debug.MEMINFO_COUNT];
1685                        Debug.getMemInfo(infos);
1686                        logBuilder.append("  MemInfo: ");
1687                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1690                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1691                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1692                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1693                            logBuilder.append("  ZRAM: ");
1694                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1695                            logBuilder.append(" kB RAM, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1697                            logBuilder.append(" kB swap total, ");
1698                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1699                            logBuilder.append(" kB swap free\n");
1700                        }
1701                        Slog.i(TAG, logBuilder.toString());
1702
1703                        StringBuilder dropBuilder = new StringBuilder(1024);
1704                        /*
1705                        StringWriter oomSw = new StringWriter();
1706                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1707                        StringWriter catSw = new StringWriter();
1708                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1709                        String[] emptyArgs = new String[] { };
1710                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1711                        oomPw.flush();
1712                        String oomString = oomSw.toString();
1713                        */
1714                        dropBuilder.append(stack);
1715                        dropBuilder.append('\n');
1716                        dropBuilder.append('\n');
1717                        dropBuilder.append(logBuilder);
1718                        dropBuilder.append('\n');
1719                        /*
1720                        dropBuilder.append(oomString);
1721                        dropBuilder.append('\n');
1722                        */
1723                        StringWriter catSw = new StringWriter();
1724                        synchronized (ActivityManagerService.this) {
1725                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1726                            String[] emptyArgs = new String[] { };
1727                            catPw.println();
1728                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1729                            catPw.println();
1730                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1731                                    false, false, null);
1732                            catPw.println();
1733                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1734                            catPw.flush();
1735                        }
1736                        dropBuilder.append(catSw.toString());
1737                        addErrorToDropBox("lowmem", null, "system_server", null,
1738                                null, tag.toString(), dropBuilder.toString(), null, null);
1739                        //Slog.i(TAG, "Sent to dropbox:");
1740                        //Slog.i(TAG, dropBuilder.toString());
1741                        synchronized (ActivityManagerService.this) {
1742                            long now = SystemClock.uptimeMillis();
1743                            if (mLastMemUsageReportTime < now) {
1744                                mLastMemUsageReportTime = now;
1745                            }
1746                        }
1747                    }
1748                };
1749                thread.start();
1750                break;
1751            }
1752            case REPORT_USER_SWITCH_MSG: {
1753                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1754                break;
1755            }
1756            case CONTINUE_USER_SWITCH_MSG: {
1757                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1758                break;
1759            }
1760            case USER_SWITCH_TIMEOUT_MSG: {
1761                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1762                break;
1763            }
1764            case IMMERSIVE_MODE_LOCK_MSG: {
1765                final boolean nextState = (msg.arg1 != 0);
1766                if (mUpdateLock.isHeld() != nextState) {
1767                    if (DEBUG_IMMERSIVE) {
1768                        final ActivityRecord r = (ActivityRecord) msg.obj;
1769                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1770                    }
1771                    if (nextState) {
1772                        mUpdateLock.acquire();
1773                    } else {
1774                        mUpdateLock.release();
1775                    }
1776                }
1777                break;
1778            }
1779            case PERSIST_URI_GRANTS_MSG: {
1780                writeGrantedUriPermissions();
1781                break;
1782            }
1783            case REQUEST_ALL_PSS_MSG: {
1784                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1785                break;
1786            }
1787            case START_PROFILES_MSG: {
1788                synchronized (ActivityManagerService.this) {
1789                    startProfilesLocked();
1790                }
1791                break;
1792            }
1793            case UPDATE_TIME: {
1794                synchronized (ActivityManagerService.this) {
1795                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1796                        ProcessRecord r = mLruProcesses.get(i);
1797                        if (r.thread != null) {
1798                            try {
1799                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1800                            } catch (RemoteException ex) {
1801                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1802                            }
1803                        }
1804                    }
1805                }
1806                break;
1807            }
1808            case SYSTEM_USER_START_MSG: {
1809                mSystemServiceManager.startUser(msg.arg1);
1810                break;
1811            }
1812            case SYSTEM_USER_CURRENT_MSG: {
1813                mSystemServiceManager.switchUser(msg.arg1);
1814                break;
1815            }
1816            }
1817        }
1818    };
1819
1820    static final int COLLECT_PSS_BG_MSG = 1;
1821
1822    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1823        @Override
1824        public void handleMessage(Message msg) {
1825            switch (msg.what) {
1826            case COLLECT_PSS_BG_MSG: {
1827                long start = SystemClock.uptimeMillis();
1828                MemInfoReader memInfo = null;
1829                synchronized (ActivityManagerService.this) {
1830                    if (mFullPssPending) {
1831                        mFullPssPending = false;
1832                        memInfo = new MemInfoReader();
1833                    }
1834                }
1835                if (memInfo != null) {
1836                    updateCpuStatsNow();
1837                    long nativeTotalPss = 0;
1838                    synchronized (mProcessCpuThread) {
1839                        final int N = mProcessCpuTracker.countStats();
1840                        for (int j=0; j<N; j++) {
1841                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1842                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1843                                // This is definitely an application process; skip it.
1844                                continue;
1845                            }
1846                            synchronized (mPidsSelfLocked) {
1847                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1848                                    // This is one of our own processes; skip it.
1849                                    continue;
1850                                }
1851                            }
1852                            nativeTotalPss += Debug.getPss(st.pid, null);
1853                        }
1854                    }
1855                    memInfo.readMemInfo();
1856                    synchronized (this) {
1857                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1858                                + (SystemClock.uptimeMillis()-start) + "ms");
1859                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1860                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1861                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1862                                        +memInfo.getSlabSizeKb(),
1863                                nativeTotalPss);
1864                    }
1865                }
1866
1867                int i=0, num=0;
1868                long[] tmp = new long[1];
1869                do {
1870                    ProcessRecord proc;
1871                    int procState;
1872                    int pid;
1873                    synchronized (ActivityManagerService.this) {
1874                        if (i >= mPendingPssProcesses.size()) {
1875                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1876                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1877                            mPendingPssProcesses.clear();
1878                            return;
1879                        }
1880                        proc = mPendingPssProcesses.get(i);
1881                        procState = proc.pssProcState;
1882                        if (proc.thread != null && procState == proc.setProcState) {
1883                            pid = proc.pid;
1884                        } else {
1885                            proc = null;
1886                            pid = 0;
1887                        }
1888                        i++;
1889                    }
1890                    if (proc != null) {
1891                        long pss = Debug.getPss(pid, tmp);
1892                        synchronized (ActivityManagerService.this) {
1893                            if (proc.thread != null && proc.setProcState == procState
1894                                    && proc.pid == pid) {
1895                                num++;
1896                                proc.lastPssTime = SystemClock.uptimeMillis();
1897                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1898                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1899                                        + ": " + pss + " lastPss=" + proc.lastPss
1900                                        + " state=" + ProcessList.makeProcStateString(procState));
1901                                if (proc.initialIdlePss == 0) {
1902                                    proc.initialIdlePss = pss;
1903                                }
1904                                proc.lastPss = pss;
1905                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1906                                    proc.lastCachedPss = pss;
1907                                }
1908                            }
1909                        }
1910                    }
1911                } while (true);
1912            }
1913            }
1914        }
1915    };
1916
1917    /**
1918     * Monitor for package changes and update our internal state.
1919     */
1920    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1921        @Override
1922        public void onPackageRemoved(String packageName, int uid) {
1923            // Remove all tasks with activities in the specified package from the list of recent tasks
1924            synchronized (ActivityManagerService.this) {
1925                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1926                    TaskRecord tr = mRecentTasks.get(i);
1927                    ComponentName cn = tr.intent.getComponent();
1928                    if (cn != null && cn.getPackageName().equals(packageName)) {
1929                        // If the package name matches, remove the task and kill the process
1930                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1931                    }
1932                }
1933            }
1934        }
1935
1936        @Override
1937        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1938            onPackageModified(packageName);
1939            return true;
1940        }
1941
1942        @Override
1943        public void onPackageModified(String packageName) {
1944            final PackageManager pm = mContext.getPackageManager();
1945            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1946                    new ArrayList<Pair<Intent, Integer>>();
1947            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1948            // Copy the list of recent tasks so that we don't hold onto the lock on
1949            // ActivityManagerService for long periods while checking if components exist.
1950            synchronized (ActivityManagerService.this) {
1951                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1952                    TaskRecord tr = mRecentTasks.get(i);
1953                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1954                }
1955            }
1956            // Check the recent tasks and filter out all tasks with components that no longer exist.
1957            Intent tmpI = new Intent();
1958            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1959                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1960                ComponentName cn = p.first.getComponent();
1961                if (cn != null && cn.getPackageName().equals(packageName)) {
1962                    try {
1963                        // Add the task to the list to remove if the component no longer exists
1964                        tmpI.setComponent(cn);
1965                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1966                            tasksToRemove.add(p.second);
1967                        }
1968                    } catch (Exception e) {}
1969                }
1970            }
1971            // Prune all the tasks with removed components from the list of recent tasks
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1974                    // Remove the task but don't kill the process (since other components in that
1975                    // package may still be running and in the background)
1976                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1977                }
1978            }
1979        }
1980
1981        @Override
1982        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1983            // Force stop the specified packages
1984            if (packages != null) {
1985                for (String pkg : packages) {
1986                    synchronized (ActivityManagerService.this) {
1987                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1988                                "finished booting")) {
1989                            return true;
1990                        }
1991                    }
1992                }
1993            }
1994            return false;
1995        }
1996    };
1997
1998    public void setSystemProcess() {
1999        try {
2000            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2001            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2002            ServiceManager.addService("meminfo", new MemBinder(this));
2003            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2004            ServiceManager.addService("dbinfo", new DbBinder(this));
2005            if (MONITOR_CPU_USAGE) {
2006                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2007            }
2008            ServiceManager.addService("permission", new PermissionController(this));
2009
2010            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2011                    "android", STOCK_PM_FLAGS);
2012            mSystemThread.installSystemApplicationInfo(info);
2013
2014            synchronized (this) {
2015                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2016                app.persistent = true;
2017                app.pid = MY_PID;
2018                app.maxAdj = ProcessList.SYSTEM_ADJ;
2019                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2020                mProcessNames.put(app.processName, app.uid, app);
2021                synchronized (mPidsSelfLocked) {
2022                    mPidsSelfLocked.put(app.pid, app);
2023                }
2024                updateLruProcessLocked(app, false, null);
2025                updateOomAdjLocked();
2026            }
2027        } catch (PackageManager.NameNotFoundException e) {
2028            throw new RuntimeException(
2029                    "Unable to find android system package", e);
2030        }
2031    }
2032
2033    public void setWindowManager(WindowManagerService wm) {
2034        mWindowManager = wm;
2035        mStackSupervisor.setWindowManager(wm);
2036    }
2037
2038    public void startObservingNativeCrashes() {
2039        final NativeCrashListener ncl = new NativeCrashListener(this);
2040        ncl.start();
2041    }
2042
2043    public IAppOpsService getAppOpsService() {
2044        return mAppOpsService;
2045    }
2046
2047    static class MemBinder extends Binder {
2048        ActivityManagerService mActivityManagerService;
2049        MemBinder(ActivityManagerService activityManagerService) {
2050            mActivityManagerService = activityManagerService;
2051        }
2052
2053        @Override
2054        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2055            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2056                    != PackageManager.PERMISSION_GRANTED) {
2057                pw.println("Permission Denial: can't dump meminfo from from pid="
2058                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2059                        + " without permission " + android.Manifest.permission.DUMP);
2060                return;
2061            }
2062
2063            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2064        }
2065    }
2066
2067    static class GraphicsBinder extends Binder {
2068        ActivityManagerService mActivityManagerService;
2069        GraphicsBinder(ActivityManagerService activityManagerService) {
2070            mActivityManagerService = activityManagerService;
2071        }
2072
2073        @Override
2074        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2075            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2076                    != PackageManager.PERMISSION_GRANTED) {
2077                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2078                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2079                        + " without permission " + android.Manifest.permission.DUMP);
2080                return;
2081            }
2082
2083            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2084        }
2085    }
2086
2087    static class DbBinder extends Binder {
2088        ActivityManagerService mActivityManagerService;
2089        DbBinder(ActivityManagerService activityManagerService) {
2090            mActivityManagerService = activityManagerService;
2091        }
2092
2093        @Override
2094        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2095            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2096                    != PackageManager.PERMISSION_GRANTED) {
2097                pw.println("Permission Denial: can't dump dbinfo from from pid="
2098                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2099                        + " without permission " + android.Manifest.permission.DUMP);
2100                return;
2101            }
2102
2103            mActivityManagerService.dumpDbInfo(fd, pw, args);
2104        }
2105    }
2106
2107    static class CpuBinder extends Binder {
2108        ActivityManagerService mActivityManagerService;
2109        CpuBinder(ActivityManagerService activityManagerService) {
2110            mActivityManagerService = activityManagerService;
2111        }
2112
2113        @Override
2114        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2115            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2116                    != PackageManager.PERMISSION_GRANTED) {
2117                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2118                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2119                        + " without permission " + android.Manifest.permission.DUMP);
2120                return;
2121            }
2122
2123            synchronized (mActivityManagerService.mProcessCpuThread) {
2124                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2125                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2126                        SystemClock.uptimeMillis()));
2127            }
2128        }
2129    }
2130
2131    public static final class Lifecycle extends SystemService {
2132        private final ActivityManagerService mService;
2133
2134        public Lifecycle(Context context) {
2135            super(context);
2136            mService = new ActivityManagerService(context);
2137        }
2138
2139        @Override
2140        public void onStart() {
2141            mService.start();
2142        }
2143
2144        public ActivityManagerService getService() {
2145            return mService;
2146        }
2147    }
2148
2149    // Note: This method is invoked on the main thread but may need to attach various
2150    // handlers to other threads.  So take care to be explicit about the looper.
2151    public ActivityManagerService(Context systemContext) {
2152        mContext = systemContext;
2153        mFactoryTest = FactoryTest.getMode();
2154        mSystemThread = ActivityThread.currentActivityThread();
2155
2156        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2157
2158        mHandlerThread = new ServiceThread(TAG,
2159                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2160        mHandlerThread.start();
2161        mHandler = new MainHandler(mHandlerThread.getLooper());
2162
2163        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2164                "foreground", BROADCAST_FG_TIMEOUT, false);
2165        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2166                "background", BROADCAST_BG_TIMEOUT, true);
2167        mBroadcastQueues[0] = mFgBroadcastQueue;
2168        mBroadcastQueues[1] = mBgBroadcastQueue;
2169
2170        mServices = new ActiveServices(this);
2171        mProviderMap = new ProviderMap(this);
2172
2173        // TODO: Move creation of battery stats service outside of activity manager service.
2174        File dataDir = Environment.getDataDirectory();
2175        File systemDir = new File(dataDir, "system");
2176        systemDir.mkdirs();
2177        mBatteryStatsService = new BatteryStatsService(new File(
2178                systemDir, "batterystats.bin").toString(), mHandler);
2179        mBatteryStatsService.getActiveStatistics().readLocked();
2180        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2181        mOnBattery = DEBUG_POWER ? true
2182                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2183        mBatteryStatsService.getActiveStatistics().setCallback(this);
2184
2185        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2186
2187        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2188        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2189
2190        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2191
2192        // User 0 is the first and only user that runs at boot.
2193        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2194        mUserLru.add(Integer.valueOf(0));
2195        updateStartedUserArrayLocked();
2196
2197        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2198            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2199
2200        mConfiguration.setToDefaults();
2201        mConfiguration.setLocale(Locale.getDefault());
2202
2203        mConfigurationSeq = mConfiguration.seq = 1;
2204        mProcessCpuTracker.init();
2205
2206        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2207        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2208        mStackSupervisor = new ActivityStackSupervisor(this);
2209        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2210
2211        mProcessCpuThread = new Thread("CpuTracker") {
2212            @Override
2213            public void run() {
2214                while (true) {
2215                    try {
2216                        try {
2217                            synchronized(this) {
2218                                final long now = SystemClock.uptimeMillis();
2219                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2220                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2221                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2222                                //        + ", write delay=" + nextWriteDelay);
2223                                if (nextWriteDelay < nextCpuDelay) {
2224                                    nextCpuDelay = nextWriteDelay;
2225                                }
2226                                if (nextCpuDelay > 0) {
2227                                    mProcessCpuMutexFree.set(true);
2228                                    this.wait(nextCpuDelay);
2229                                }
2230                            }
2231                        } catch (InterruptedException e) {
2232                        }
2233                        updateCpuStatsNow();
2234                    } catch (Exception e) {
2235                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2236                    }
2237                }
2238            }
2239        };
2240
2241        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2242
2243        Watchdog.getInstance().addMonitor(this);
2244        Watchdog.getInstance().addThread(mHandler);
2245    }
2246
2247    public void setSystemServiceManager(SystemServiceManager mgr) {
2248        mSystemServiceManager = mgr;
2249    }
2250
2251    private void start() {
2252        mProcessCpuThread.start();
2253
2254        mBatteryStatsService.publish(mContext);
2255        mUsageStatsService.publish(mContext);
2256        mAppOpsService.publish(mContext);
2257        Slog.d("AppOps", "AppOpsService published");
2258        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2259    }
2260
2261    public void initPowerManagement() {
2262        mStackSupervisor.initPowerManagement();
2263        mBatteryStatsService.initPowerManagement();
2264    }
2265
2266    @Override
2267    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2268            throws RemoteException {
2269        if (code == SYSPROPS_TRANSACTION) {
2270            // We need to tell all apps about the system property change.
2271            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2272            synchronized(this) {
2273                final int NP = mProcessNames.getMap().size();
2274                for (int ip=0; ip<NP; ip++) {
2275                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2276                    final int NA = apps.size();
2277                    for (int ia=0; ia<NA; ia++) {
2278                        ProcessRecord app = apps.valueAt(ia);
2279                        if (app.thread != null) {
2280                            procs.add(app.thread.asBinder());
2281                        }
2282                    }
2283                }
2284            }
2285
2286            int N = procs.size();
2287            for (int i=0; i<N; i++) {
2288                Parcel data2 = Parcel.obtain();
2289                try {
2290                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2291                } catch (RemoteException e) {
2292                }
2293                data2.recycle();
2294            }
2295        }
2296        try {
2297            return super.onTransact(code, data, reply, flags);
2298        } catch (RuntimeException e) {
2299            // The activity manager only throws security exceptions, so let's
2300            // log all others.
2301            if (!(e instanceof SecurityException)) {
2302                Slog.wtf(TAG, "Activity Manager Crash", e);
2303            }
2304            throw e;
2305        }
2306    }
2307
2308    void updateCpuStats() {
2309        final long now = SystemClock.uptimeMillis();
2310        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2311            return;
2312        }
2313        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2314            synchronized (mProcessCpuThread) {
2315                mProcessCpuThread.notify();
2316            }
2317        }
2318    }
2319
2320    void updateCpuStatsNow() {
2321        synchronized (mProcessCpuThread) {
2322            mProcessCpuMutexFree.set(false);
2323            final long now = SystemClock.uptimeMillis();
2324            boolean haveNewCpuStats = false;
2325
2326            if (MONITOR_CPU_USAGE &&
2327                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2328                mLastCpuTime.set(now);
2329                haveNewCpuStats = true;
2330                mProcessCpuTracker.update();
2331                //Slog.i(TAG, mProcessCpu.printCurrentState());
2332                //Slog.i(TAG, "Total CPU usage: "
2333                //        + mProcessCpu.getTotalCpuPercent() + "%");
2334
2335                // Slog the cpu usage if the property is set.
2336                if ("true".equals(SystemProperties.get("events.cpu"))) {
2337                    int user = mProcessCpuTracker.getLastUserTime();
2338                    int system = mProcessCpuTracker.getLastSystemTime();
2339                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2340                    int irq = mProcessCpuTracker.getLastIrqTime();
2341                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2342                    int idle = mProcessCpuTracker.getLastIdleTime();
2343
2344                    int total = user + system + iowait + irq + softIrq + idle;
2345                    if (total == 0) total = 1;
2346
2347                    EventLog.writeEvent(EventLogTags.CPU,
2348                            ((user+system+iowait+irq+softIrq) * 100) / total,
2349                            (user * 100) / total,
2350                            (system * 100) / total,
2351                            (iowait * 100) / total,
2352                            (irq * 100) / total,
2353                            (softIrq * 100) / total);
2354                }
2355            }
2356
2357            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2358            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2359            synchronized(bstats) {
2360                synchronized(mPidsSelfLocked) {
2361                    if (haveNewCpuStats) {
2362                        if (mOnBattery) {
2363                            int perc = bstats.startAddingCpuLocked();
2364                            int totalUTime = 0;
2365                            int totalSTime = 0;
2366                            final int N = mProcessCpuTracker.countStats();
2367                            for (int i=0; i<N; i++) {
2368                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2369                                if (!st.working) {
2370                                    continue;
2371                                }
2372                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2373                                int otherUTime = (st.rel_utime*perc)/100;
2374                                int otherSTime = (st.rel_stime*perc)/100;
2375                                totalUTime += otherUTime;
2376                                totalSTime += otherSTime;
2377                                if (pr != null) {
2378                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2379                                    if (ps == null || !ps.isActive()) {
2380                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2381                                                pr.info.uid, pr.processName);
2382                                    }
2383                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2384                                            st.rel_stime-otherSTime);
2385                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2386                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2387                                } else {
2388                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2389                                    if (ps == null || !ps.isActive()) {
2390                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2391                                                bstats.mapUid(st.uid), st.name);
2392                                    }
2393                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2394                                            st.rel_stime-otherSTime);
2395                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2396                                }
2397                            }
2398                            bstats.finishAddingCpuLocked(perc, totalUTime,
2399                                    totalSTime, cpuSpeedTimes);
2400                        }
2401                    }
2402                }
2403
2404                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2405                    mLastWriteTime = now;
2406                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2407                }
2408            }
2409        }
2410    }
2411
2412    @Override
2413    public void batteryNeedsCpuUpdate() {
2414        updateCpuStatsNow();
2415    }
2416
2417    @Override
2418    public void batteryPowerChanged(boolean onBattery) {
2419        // When plugging in, update the CPU stats first before changing
2420        // the plug state.
2421        updateCpuStatsNow();
2422        synchronized (this) {
2423            synchronized(mPidsSelfLocked) {
2424                mOnBattery = DEBUG_POWER ? true : onBattery;
2425            }
2426        }
2427    }
2428
2429    /**
2430     * Initialize the application bind args. These are passed to each
2431     * process when the bindApplication() IPC is sent to the process. They're
2432     * lazily setup to make sure the services are running when they're asked for.
2433     */
2434    private HashMap<String, IBinder> getCommonServicesLocked() {
2435        if (mAppBindArgs == null) {
2436            mAppBindArgs = new HashMap<String, IBinder>();
2437
2438            // Setup the application init args
2439            mAppBindArgs.put("package", ServiceManager.getService("package"));
2440            mAppBindArgs.put("window", ServiceManager.getService("window"));
2441            mAppBindArgs.put(Context.ALARM_SERVICE,
2442                    ServiceManager.getService(Context.ALARM_SERVICE));
2443        }
2444        return mAppBindArgs;
2445    }
2446
2447    final void setFocusedActivityLocked(ActivityRecord r) {
2448        if (mFocusedActivity != r) {
2449            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2450            mFocusedActivity = r;
2451            if (r.task != null && r.task.voiceInteractor != null) {
2452                startRunningVoiceLocked();
2453            } else {
2454                finishRunningVoiceLocked();
2455            }
2456            mStackSupervisor.setFocusedStack(r);
2457            if (r != null) {
2458                mWindowManager.setFocusedApp(r.appToken, true);
2459            }
2460            applyUpdateLockStateLocked(r);
2461        }
2462    }
2463
2464    final void clearFocusedActivity(ActivityRecord r) {
2465        if (mFocusedActivity == r) {
2466            mFocusedActivity = null;
2467        }
2468    }
2469
2470    @Override
2471    public void setFocusedStack(int stackId) {
2472        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2473        synchronized (ActivityManagerService.this) {
2474            ActivityStack stack = mStackSupervisor.getStack(stackId);
2475            if (stack != null) {
2476                ActivityRecord r = stack.topRunningActivityLocked(null);
2477                if (r != null) {
2478                    setFocusedActivityLocked(r);
2479                }
2480            }
2481        }
2482    }
2483
2484    @Override
2485    public void notifyActivityDrawn(IBinder token) {
2486        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2487        synchronized (this) {
2488            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2489            if (r != null) {
2490                r.task.stack.notifyActivityDrawnLocked(r);
2491            }
2492        }
2493    }
2494
2495    final void applyUpdateLockStateLocked(ActivityRecord r) {
2496        // Modifications to the UpdateLock state are done on our handler, outside
2497        // the activity manager's locks.  The new state is determined based on the
2498        // state *now* of the relevant activity record.  The object is passed to
2499        // the handler solely for logging detail, not to be consulted/modified.
2500        final boolean nextState = r != null && r.immersive;
2501        mHandler.sendMessage(
2502                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2503    }
2504
2505    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2506        Message msg = Message.obtain();
2507        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2508        msg.obj = r.task.askedCompatMode ? null : r;
2509        mHandler.sendMessage(msg);
2510    }
2511
2512    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2513            String what, Object obj, ProcessRecord srcApp) {
2514        app.lastActivityTime = now;
2515
2516        if (app.activities.size() > 0) {
2517            // Don't want to touch dependent processes that are hosting activities.
2518            return index;
2519        }
2520
2521        int lrui = mLruProcesses.lastIndexOf(app);
2522        if (lrui < 0) {
2523            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2524                    + what + " " + obj + " from " + srcApp);
2525            return index;
2526        }
2527
2528        if (lrui >= index) {
2529            // Don't want to cause this to move dependent processes *back* in the
2530            // list as if they were less frequently used.
2531            return index;
2532        }
2533
2534        if (lrui >= mLruProcessActivityStart) {
2535            // Don't want to touch dependent processes that are hosting activities.
2536            return index;
2537        }
2538
2539        mLruProcesses.remove(lrui);
2540        if (index > 0) {
2541            index--;
2542        }
2543        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2544                + " in LRU list: " + app);
2545        mLruProcesses.add(index, app);
2546        return index;
2547    }
2548
2549    final void removeLruProcessLocked(ProcessRecord app) {
2550        int lrui = mLruProcesses.lastIndexOf(app);
2551        if (lrui >= 0) {
2552            if (lrui <= mLruProcessActivityStart) {
2553                mLruProcessActivityStart--;
2554            }
2555            if (lrui <= mLruProcessServiceStart) {
2556                mLruProcessServiceStart--;
2557            }
2558            mLruProcesses.remove(lrui);
2559        }
2560    }
2561
2562    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2563            ProcessRecord client) {
2564        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2565                || app.treatLikeActivity;
2566        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2567        if (!activityChange && hasActivity) {
2568            // The process has activities, so we are only allowing activity-based adjustments
2569            // to move it.  It should be kept in the front of the list with other
2570            // processes that have activities, and we don't want those to change their
2571            // order except due to activity operations.
2572            return;
2573        }
2574
2575        mLruSeq++;
2576        final long now = SystemClock.uptimeMillis();
2577        app.lastActivityTime = now;
2578
2579        // First a quick reject: if the app is already at the position we will
2580        // put it, then there is nothing to do.
2581        if (hasActivity) {
2582            final int N = mLruProcesses.size();
2583            if (N > 0 && mLruProcesses.get(N-1) == app) {
2584                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2585                return;
2586            }
2587        } else {
2588            if (mLruProcessServiceStart > 0
2589                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2590                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2591                return;
2592            }
2593        }
2594
2595        int lrui = mLruProcesses.lastIndexOf(app);
2596
2597        if (app.persistent && lrui >= 0) {
2598            // We don't care about the position of persistent processes, as long as
2599            // they are in the list.
2600            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2601            return;
2602        }
2603
2604        /* In progress: compute new position first, so we can avoid doing work
2605           if the process is not actually going to move.  Not yet working.
2606        int addIndex;
2607        int nextIndex;
2608        boolean inActivity = false, inService = false;
2609        if (hasActivity) {
2610            // Process has activities, put it at the very tipsy-top.
2611            addIndex = mLruProcesses.size();
2612            nextIndex = mLruProcessServiceStart;
2613            inActivity = true;
2614        } else if (hasService) {
2615            // Process has services, put it at the top of the service list.
2616            addIndex = mLruProcessActivityStart;
2617            nextIndex = mLruProcessServiceStart;
2618            inActivity = true;
2619            inService = true;
2620        } else  {
2621            // Process not otherwise of interest, it goes to the top of the non-service area.
2622            addIndex = mLruProcessServiceStart;
2623            if (client != null) {
2624                int clientIndex = mLruProcesses.lastIndexOf(client);
2625                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2626                        + app);
2627                if (clientIndex >= 0 && addIndex > clientIndex) {
2628                    addIndex = clientIndex;
2629                }
2630            }
2631            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2632        }
2633
2634        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2635                + mLruProcessActivityStart + "): " + app);
2636        */
2637
2638        if (lrui >= 0) {
2639            if (lrui < mLruProcessActivityStart) {
2640                mLruProcessActivityStart--;
2641            }
2642            if (lrui < mLruProcessServiceStart) {
2643                mLruProcessServiceStart--;
2644            }
2645            /*
2646            if (addIndex > lrui) {
2647                addIndex--;
2648            }
2649            if (nextIndex > lrui) {
2650                nextIndex--;
2651            }
2652            */
2653            mLruProcesses.remove(lrui);
2654        }
2655
2656        /*
2657        mLruProcesses.add(addIndex, app);
2658        if (inActivity) {
2659            mLruProcessActivityStart++;
2660        }
2661        if (inService) {
2662            mLruProcessActivityStart++;
2663        }
2664        */
2665
2666        int nextIndex;
2667        if (hasActivity) {
2668            final int N = mLruProcesses.size();
2669            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2670                // Process doesn't have activities, but has clients with
2671                // activities...  move it up, but one below the top (the top
2672                // should always have a real activity).
2673                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2674                mLruProcesses.add(N-1, app);
2675                // To keep it from spamming the LRU list (by making a bunch of clients),
2676                // we will push down any other entries owned by the app.
2677                final int uid = app.info.uid;
2678                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2679                    ProcessRecord subProc = mLruProcesses.get(i);
2680                    if (subProc.info.uid == uid) {
2681                        // We want to push this one down the list.  If the process after
2682                        // it is for the same uid, however, don't do so, because we don't
2683                        // want them internally to be re-ordered.
2684                        if (mLruProcesses.get(i-1).info.uid != uid) {
2685                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2686                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2687                            ProcessRecord tmp = mLruProcesses.get(i);
2688                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2689                            mLruProcesses.set(i-1, tmp);
2690                            i--;
2691                        }
2692                    } else {
2693                        // A gap, we can stop here.
2694                        break;
2695                    }
2696                }
2697            } else {
2698                // Process has activities, put it at the very tipsy-top.
2699                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2700                mLruProcesses.add(app);
2701            }
2702            nextIndex = mLruProcessServiceStart;
2703        } else if (hasService) {
2704            // Process has services, put it at the top of the service list.
2705            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2706            mLruProcesses.add(mLruProcessActivityStart, app);
2707            nextIndex = mLruProcessServiceStart;
2708            mLruProcessActivityStart++;
2709        } else  {
2710            // Process not otherwise of interest, it goes to the top of the non-service area.
2711            int index = mLruProcessServiceStart;
2712            if (client != null) {
2713                // If there is a client, don't allow the process to be moved up higher
2714                // in the list than that client.
2715                int clientIndex = mLruProcesses.lastIndexOf(client);
2716                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2717                        + " when updating " + app);
2718                if (clientIndex <= lrui) {
2719                    // Don't allow the client index restriction to push it down farther in the
2720                    // list than it already is.
2721                    clientIndex = lrui;
2722                }
2723                if (clientIndex >= 0 && index > clientIndex) {
2724                    index = clientIndex;
2725                }
2726            }
2727            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2728            mLruProcesses.add(index, app);
2729            nextIndex = index-1;
2730            mLruProcessActivityStart++;
2731            mLruProcessServiceStart++;
2732        }
2733
2734        // If the app is currently using a content provider or service,
2735        // bump those processes as well.
2736        for (int j=app.connections.size()-1; j>=0; j--) {
2737            ConnectionRecord cr = app.connections.valueAt(j);
2738            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2739                    && cr.binding.service.app != null
2740                    && cr.binding.service.app.lruSeq != mLruSeq
2741                    && !cr.binding.service.app.persistent) {
2742                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2743                        "service connection", cr, app);
2744            }
2745        }
2746        for (int j=app.conProviders.size()-1; j>=0; j--) {
2747            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2748            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2749                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2750                        "provider reference", cpr, app);
2751            }
2752        }
2753    }
2754
2755    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2756        if (uid == Process.SYSTEM_UID) {
2757            // The system gets to run in any process.  If there are multiple
2758            // processes with the same uid, just pick the first (this
2759            // should never happen).
2760            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2761            if (procs == null) return null;
2762            final int N = procs.size();
2763            for (int i = 0; i < N; i++) {
2764                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2765            }
2766        }
2767        ProcessRecord proc = mProcessNames.get(processName, uid);
2768        if (false && proc != null && !keepIfLarge
2769                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2770                && proc.lastCachedPss >= 4000) {
2771            // Turn this condition on to cause killing to happen regularly, for testing.
2772            if (proc.baseProcessTracker != null) {
2773                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2774            }
2775            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2776                    + "k from cached");
2777        } else if (proc != null && !keepIfLarge
2778                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2779                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2780            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2781            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2782                if (proc.baseProcessTracker != null) {
2783                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2784                }
2785                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2786                        + "k from cached");
2787            }
2788        }
2789        return proc;
2790    }
2791
2792    void ensurePackageDexOpt(String packageName) {
2793        IPackageManager pm = AppGlobals.getPackageManager();
2794        try {
2795            if (pm.performDexOpt(packageName)) {
2796                mDidDexOpt = true;
2797            }
2798        } catch (RemoteException e) {
2799        }
2800    }
2801
2802    boolean isNextTransitionForward() {
2803        int transit = mWindowManager.getPendingAppTransition();
2804        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2805                || transit == AppTransition.TRANSIT_TASK_OPEN
2806                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2807    }
2808
2809    final ProcessRecord startProcessLocked(String processName,
2810            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2811            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2812            boolean isolated, boolean keepIfLarge) {
2813        ProcessRecord app;
2814        if (!isolated) {
2815            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2816        } else {
2817            // If this is an isolated process, it can't re-use an existing process.
2818            app = null;
2819        }
2820        // We don't have to do anything more if:
2821        // (1) There is an existing application record; and
2822        // (2) The caller doesn't think it is dead, OR there is no thread
2823        //     object attached to it so we know it couldn't have crashed; and
2824        // (3) There is a pid assigned to it, so it is either starting or
2825        //     already running.
2826        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2827                + " app=" + app + " knownToBeDead=" + knownToBeDead
2828                + " thread=" + (app != null ? app.thread : null)
2829                + " pid=" + (app != null ? app.pid : -1));
2830        if (app != null && app.pid > 0) {
2831            if (!knownToBeDead || app.thread == null) {
2832                // We already have the app running, or are waiting for it to
2833                // come up (we have a pid but not yet its thread), so keep it.
2834                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2835                // If this is a new package in the process, add the package to the list
2836                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2837                return app;
2838            }
2839
2840            // An application record is attached to a previous process,
2841            // clean it up now.
2842            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2843            handleAppDiedLocked(app, true, true);
2844        }
2845
2846        String hostingNameStr = hostingName != null
2847                ? hostingName.flattenToShortString() : null;
2848
2849        if (!isolated) {
2850            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2851                // If we are in the background, then check to see if this process
2852                // is bad.  If so, we will just silently fail.
2853                if (mBadProcesses.get(info.processName, info.uid) != null) {
2854                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2855                            + "/" + info.processName);
2856                    return null;
2857                }
2858            } else {
2859                // When the user is explicitly starting a process, then clear its
2860                // crash count so that we won't make it bad until they see at
2861                // least one crash dialog again, and make the process good again
2862                // if it had been bad.
2863                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2864                        + "/" + info.processName);
2865                mProcessCrashTimes.remove(info.processName, info.uid);
2866                if (mBadProcesses.get(info.processName, info.uid) != null) {
2867                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2868                            UserHandle.getUserId(info.uid), info.uid,
2869                            info.processName);
2870                    mBadProcesses.remove(info.processName, info.uid);
2871                    if (app != null) {
2872                        app.bad = false;
2873                    }
2874                }
2875            }
2876        }
2877
2878        if (app == null) {
2879            app = newProcessRecordLocked(info, processName, isolated);
2880            if (app == null) {
2881                Slog.w(TAG, "Failed making new process record for "
2882                        + processName + "/" + info.uid + " isolated=" + isolated);
2883                return null;
2884            }
2885            mProcessNames.put(processName, app.uid, app);
2886            if (isolated) {
2887                mIsolatedProcesses.put(app.uid, app);
2888            }
2889        } else {
2890            // If this is a new package in the process, add the package to the list
2891            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2892        }
2893
2894        // If the system is not ready yet, then hold off on starting this
2895        // process until it is.
2896        if (!mProcessesReady
2897                && !isAllowedWhileBooting(info)
2898                && !allowWhileBooting) {
2899            if (!mProcessesOnHold.contains(app)) {
2900                mProcessesOnHold.add(app);
2901            }
2902            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2903            return app;
2904        }
2905
2906        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2907        return (app.pid != 0) ? app : null;
2908    }
2909
2910    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2911        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2912    }
2913
2914    private final void startProcessLocked(ProcessRecord app,
2915            String hostingType, String hostingNameStr, String abiOverride) {
2916        if (app.pid > 0 && app.pid != MY_PID) {
2917            synchronized (mPidsSelfLocked) {
2918                mPidsSelfLocked.remove(app.pid);
2919                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2920            }
2921            app.setPid(0);
2922        }
2923
2924        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2925                "startProcessLocked removing on hold: " + app);
2926        mProcessesOnHold.remove(app);
2927
2928        updateCpuStats();
2929
2930        try {
2931            int uid = app.uid;
2932
2933            int[] gids = null;
2934            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2935            if (!app.isolated) {
2936                int[] permGids = null;
2937                try {
2938                    final PackageManager pm = mContext.getPackageManager();
2939                    permGids = pm.getPackageGids(app.info.packageName);
2940
2941                    if (Environment.isExternalStorageEmulated()) {
2942                        if (pm.checkPermission(
2943                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2944                                app.info.packageName) == PERMISSION_GRANTED) {
2945                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2946                        } else {
2947                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2948                        }
2949                    }
2950                } catch (PackageManager.NameNotFoundException e) {
2951                    Slog.w(TAG, "Unable to retrieve gids", e);
2952                }
2953
2954                /*
2955                 * Add shared application and profile GIDs so applications can share some
2956                 * resources like shared libraries and access user-wide resources
2957                 */
2958                if (permGids == null) {
2959                    gids = new int[2];
2960                } else {
2961                    gids = new int[permGids.length + 2];
2962                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2963                }
2964                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2965                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2966            }
2967            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2968                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2969                        && mTopComponent != null
2970                        && app.processName.equals(mTopComponent.getPackageName())) {
2971                    uid = 0;
2972                }
2973                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2974                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2975                    uid = 0;
2976                }
2977            }
2978            int debugFlags = 0;
2979            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2980                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2981                // Also turn on CheckJNI for debuggable apps. It's quite
2982                // awkward to turn on otherwise.
2983                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2984            }
2985            // Run the app in safe mode if its manifest requests so or the
2986            // system is booted in safe mode.
2987            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2988                mSafeMode == true) {
2989                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2990            }
2991            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2993            }
2994            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2995                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2996            }
2997            if ("1".equals(SystemProperties.get("debug.assert"))) {
2998                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2999            }
3000
3001            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
3002            if (requiredAbi == null) {
3003                requiredAbi = Build.SUPPORTED_ABIS[0];
3004            }
3005
3006            // Start the process.  It will either succeed and return a result containing
3007            // the PID of the new process, or else throw a RuntimeException.
3008            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3009                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3010                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3011
3012            if (app.isolated) {
3013                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3014            }
3015            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3016
3017            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3018                    UserHandle.getUserId(uid), startResult.pid, uid,
3019                    app.processName, hostingType,
3020                    hostingNameStr != null ? hostingNameStr : "");
3021
3022            if (app.persistent) {
3023                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3024            }
3025
3026            StringBuilder buf = mStringBuilder;
3027            buf.setLength(0);
3028            buf.append("Start proc ");
3029            buf.append(app.processName);
3030            buf.append(" for ");
3031            buf.append(hostingType);
3032            if (hostingNameStr != null) {
3033                buf.append(" ");
3034                buf.append(hostingNameStr);
3035            }
3036            buf.append(": pid=");
3037            buf.append(startResult.pid);
3038            buf.append(" uid=");
3039            buf.append(uid);
3040            buf.append(" gids={");
3041            if (gids != null) {
3042                for (int gi=0; gi<gids.length; gi++) {
3043                    if (gi != 0) buf.append(", ");
3044                    buf.append(gids[gi]);
3045
3046                }
3047            }
3048            buf.append("}");
3049            if (requiredAbi != null) {
3050                buf.append(" abi=");
3051                buf.append(requiredAbi);
3052            }
3053            Slog.i(TAG, buf.toString());
3054            app.setPid(startResult.pid);
3055            app.usingWrapper = startResult.usingWrapper;
3056            app.removed = false;
3057            app.killedByAm = false;
3058            synchronized (mPidsSelfLocked) {
3059                this.mPidsSelfLocked.put(startResult.pid, app);
3060                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3061                msg.obj = app;
3062                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3063                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3064            }
3065        } catch (RuntimeException e) {
3066            // XXX do better error recovery.
3067            app.setPid(0);
3068            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3069            if (app.isolated) {
3070                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3071            }
3072            Slog.e(TAG, "Failure starting process " + app.processName, e);
3073        }
3074    }
3075
3076    void updateUsageStats(ActivityRecord component, boolean resumed) {
3077        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3078        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3079        if (resumed) {
3080            mUsageStatsService.noteResumeComponent(component.realActivity);
3081            synchronized (stats) {
3082                stats.noteActivityResumedLocked(component.app.uid);
3083            }
3084        } else {
3085            mUsageStatsService.notePauseComponent(component.realActivity);
3086            synchronized (stats) {
3087                stats.noteActivityPausedLocked(component.app.uid);
3088            }
3089        }
3090    }
3091
3092    Intent getHomeIntent() {
3093        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3094        intent.setComponent(mTopComponent);
3095        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3096            intent.addCategory(Intent.CATEGORY_HOME);
3097        }
3098        return intent;
3099    }
3100
3101    boolean startHomeActivityLocked(int userId) {
3102        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3103                && mTopAction == null) {
3104            // We are running in factory test mode, but unable to find
3105            // the factory test app, so just sit around displaying the
3106            // error message and don't try to start anything.
3107            return false;
3108        }
3109        Intent intent = getHomeIntent();
3110        ActivityInfo aInfo =
3111            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3112        if (aInfo != null) {
3113            intent.setComponent(new ComponentName(
3114                    aInfo.applicationInfo.packageName, aInfo.name));
3115            // Don't do this if the home app is currently being
3116            // instrumented.
3117            aInfo = new ActivityInfo(aInfo);
3118            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3119            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3120                    aInfo.applicationInfo.uid, true);
3121            if (app == null || app.instrumentationClass == null) {
3122                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3123                mStackSupervisor.startHomeActivity(intent, aInfo);
3124            }
3125        }
3126
3127        return true;
3128    }
3129
3130    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3131        ActivityInfo ai = null;
3132        ComponentName comp = intent.getComponent();
3133        try {
3134            if (comp != null) {
3135                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3136            } else {
3137                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3138                        intent,
3139                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3140                            flags, userId);
3141
3142                if (info != null) {
3143                    ai = info.activityInfo;
3144                }
3145            }
3146        } catch (RemoteException e) {
3147            // ignore
3148        }
3149
3150        return ai;
3151    }
3152
3153    /**
3154     * Starts the "new version setup screen" if appropriate.
3155     */
3156    void startSetupActivityLocked() {
3157        // Only do this once per boot.
3158        if (mCheckedForSetup) {
3159            return;
3160        }
3161
3162        // We will show this screen if the current one is a different
3163        // version than the last one shown, and we are not running in
3164        // low-level factory test mode.
3165        final ContentResolver resolver = mContext.getContentResolver();
3166        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3167                Settings.Global.getInt(resolver,
3168                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3169            mCheckedForSetup = true;
3170
3171            // See if we should be showing the platform update setup UI.
3172            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3173            List<ResolveInfo> ris = mContext.getPackageManager()
3174                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3175
3176            // We don't allow third party apps to replace this.
3177            ResolveInfo ri = null;
3178            for (int i=0; ris != null && i<ris.size(); i++) {
3179                if ((ris.get(i).activityInfo.applicationInfo.flags
3180                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3181                    ri = ris.get(i);
3182                    break;
3183                }
3184            }
3185
3186            if (ri != null) {
3187                String vers = ri.activityInfo.metaData != null
3188                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3189                        : null;
3190                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3191                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3192                            Intent.METADATA_SETUP_VERSION);
3193                }
3194                String lastVers = Settings.Secure.getString(
3195                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3196                if (vers != null && !vers.equals(lastVers)) {
3197                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3198                    intent.setComponent(new ComponentName(
3199                            ri.activityInfo.packageName, ri.activityInfo.name));
3200                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3201                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3202                }
3203            }
3204        }
3205    }
3206
3207    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3208        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3209    }
3210
3211    void enforceNotIsolatedCaller(String caller) {
3212        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3213            throw new SecurityException("Isolated process not allowed to call " + caller);
3214        }
3215    }
3216
3217    @Override
3218    public int getFrontActivityScreenCompatMode() {
3219        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3220        synchronized (this) {
3221            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3222        }
3223    }
3224
3225    @Override
3226    public void setFrontActivityScreenCompatMode(int mode) {
3227        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3228                "setFrontActivityScreenCompatMode");
3229        synchronized (this) {
3230            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3231        }
3232    }
3233
3234    @Override
3235    public int getPackageScreenCompatMode(String packageName) {
3236        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3237        synchronized (this) {
3238            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3239        }
3240    }
3241
3242    @Override
3243    public void setPackageScreenCompatMode(String packageName, int mode) {
3244        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3245                "setPackageScreenCompatMode");
3246        synchronized (this) {
3247            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3248        }
3249    }
3250
3251    @Override
3252    public boolean getPackageAskScreenCompat(String packageName) {
3253        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3254        synchronized (this) {
3255            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3256        }
3257    }
3258
3259    @Override
3260    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3261        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3262                "setPackageAskScreenCompat");
3263        synchronized (this) {
3264            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3265        }
3266    }
3267
3268    private void dispatchProcessesChanged() {
3269        int N;
3270        synchronized (this) {
3271            N = mPendingProcessChanges.size();
3272            if (mActiveProcessChanges.length < N) {
3273                mActiveProcessChanges = new ProcessChangeItem[N];
3274            }
3275            mPendingProcessChanges.toArray(mActiveProcessChanges);
3276            mAvailProcessChanges.addAll(mPendingProcessChanges);
3277            mPendingProcessChanges.clear();
3278            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3279        }
3280
3281        int i = mProcessObservers.beginBroadcast();
3282        while (i > 0) {
3283            i--;
3284            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3285            if (observer != null) {
3286                try {
3287                    for (int j=0; j<N; j++) {
3288                        ProcessChangeItem item = mActiveProcessChanges[j];
3289                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3290                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3291                                    + item.pid + " uid=" + item.uid + ": "
3292                                    + item.foregroundActivities);
3293                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3294                                    item.foregroundActivities);
3295                        }
3296                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3297                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3298                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3299                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3300                        }
3301                    }
3302                } catch (RemoteException e) {
3303                }
3304            }
3305        }
3306        mProcessObservers.finishBroadcast();
3307    }
3308
3309    private void dispatchProcessDied(int pid, int uid) {
3310        int i = mProcessObservers.beginBroadcast();
3311        while (i > 0) {
3312            i--;
3313            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3314            if (observer != null) {
3315                try {
3316                    observer.onProcessDied(pid, uid);
3317                } catch (RemoteException e) {
3318                }
3319            }
3320        }
3321        mProcessObservers.finishBroadcast();
3322    }
3323
3324    final void doPendingActivityLaunchesLocked(boolean doResume) {
3325        final int N = mPendingActivityLaunches.size();
3326        if (N <= 0) {
3327            return;
3328        }
3329        for (int i=0; i<N; i++) {
3330            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3331            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3332                    doResume && i == (N-1), null);
3333        }
3334        mPendingActivityLaunches.clear();
3335    }
3336
3337    @Override
3338    public final int startActivity(IApplicationThread caller, String callingPackage,
3339            Intent intent, String resolvedType, IBinder resultTo,
3340            String resultWho, int requestCode, int startFlags,
3341            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3342        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3343                resultWho, requestCode,
3344                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3345    }
3346
3347    @Override
3348    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3349            Intent intent, String resolvedType, IBinder resultTo,
3350            String resultWho, int requestCode, int startFlags,
3351            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3352        enforceNotIsolatedCaller("startActivity");
3353        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3354                false, ALLOW_FULL_ONLY, "startActivity", null);
3355        // TODO: Switch to user app stacks here.
3356        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3357                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3358                null, null, options, userId, null);
3359    }
3360
3361    @Override
3362    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3363            Intent intent, String resolvedType, IBinder resultTo,
3364            String resultWho, int requestCode, int startFlags, String profileFile,
3365            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3366        enforceNotIsolatedCaller("startActivityAndWait");
3367        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3368                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3369        WaitResult res = new WaitResult();
3370        // TODO: Switch to user app stacks here.
3371        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3372                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3373                res, null, options, userId, null);
3374        return res;
3375    }
3376
3377    @Override
3378    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3379            Intent intent, String resolvedType, IBinder resultTo,
3380            String resultWho, int requestCode, int startFlags, Configuration config,
3381            Bundle options, int userId) {
3382        enforceNotIsolatedCaller("startActivityWithConfig");
3383        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3384                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3385        // TODO: Switch to user app stacks here.
3386        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3387                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3388                null, null, null, config, options, userId, null);
3389        return ret;
3390    }
3391
3392    @Override
3393    public int startActivityIntentSender(IApplicationThread caller,
3394            IntentSender intent, Intent fillInIntent, String resolvedType,
3395            IBinder resultTo, String resultWho, int requestCode,
3396            int flagsMask, int flagsValues, Bundle options) {
3397        enforceNotIsolatedCaller("startActivityIntentSender");
3398        // Refuse possible leaked file descriptors
3399        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3400            throw new IllegalArgumentException("File descriptors passed in Intent");
3401        }
3402
3403        IIntentSender sender = intent.getTarget();
3404        if (!(sender instanceof PendingIntentRecord)) {
3405            throw new IllegalArgumentException("Bad PendingIntent object");
3406        }
3407
3408        PendingIntentRecord pir = (PendingIntentRecord)sender;
3409
3410        synchronized (this) {
3411            // If this is coming from the currently resumed activity, it is
3412            // effectively saying that app switches are allowed at this point.
3413            final ActivityStack stack = getFocusedStack();
3414            if (stack.mResumedActivity != null &&
3415                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3416                mAppSwitchesAllowedTime = 0;
3417            }
3418        }
3419        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3420                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3421        return ret;
3422    }
3423
3424    @Override
3425    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3426            Intent intent, String resolvedType, IVoiceInteractionSession session,
3427            IVoiceInteractor interactor, int startFlags, String profileFile,
3428            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3429        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3430                != PackageManager.PERMISSION_GRANTED) {
3431            String msg = "Permission Denial: startVoiceActivity() from pid="
3432                    + Binder.getCallingPid()
3433                    + ", uid=" + Binder.getCallingUid()
3434                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3435            Slog.w(TAG, msg);
3436            throw new SecurityException(msg);
3437        }
3438        if (session == null || interactor == null) {
3439            throw new NullPointerException("null session or interactor");
3440        }
3441        userId = handleIncomingUser(callingPid, callingUid, userId,
3442                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3443        // TODO: Switch to user app stacks here.
3444        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3445                resolvedType, session, interactor, null, null, 0, startFlags,
3446                profileFile, profileFd, null, null, options, userId, null);
3447    }
3448
3449    @Override
3450    public boolean startNextMatchingActivity(IBinder callingActivity,
3451            Intent intent, Bundle options) {
3452        // Refuse possible leaked file descriptors
3453        if (intent != null && intent.hasFileDescriptors() == true) {
3454            throw new IllegalArgumentException("File descriptors passed in Intent");
3455        }
3456
3457        synchronized (this) {
3458            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3459            if (r == null) {
3460                ActivityOptions.abort(options);
3461                return false;
3462            }
3463            if (r.app == null || r.app.thread == null) {
3464                // The caller is not running...  d'oh!
3465                ActivityOptions.abort(options);
3466                return false;
3467            }
3468            intent = new Intent(intent);
3469            // The caller is not allowed to change the data.
3470            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3471            // And we are resetting to find the next component...
3472            intent.setComponent(null);
3473
3474            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3475
3476            ActivityInfo aInfo = null;
3477            try {
3478                List<ResolveInfo> resolves =
3479                    AppGlobals.getPackageManager().queryIntentActivities(
3480                            intent, r.resolvedType,
3481                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3482                            UserHandle.getCallingUserId());
3483
3484                // Look for the original activity in the list...
3485                final int N = resolves != null ? resolves.size() : 0;
3486                for (int i=0; i<N; i++) {
3487                    ResolveInfo rInfo = resolves.get(i);
3488                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3489                            && rInfo.activityInfo.name.equals(r.info.name)) {
3490                        // We found the current one...  the next matching is
3491                        // after it.
3492                        i++;
3493                        if (i<N) {
3494                            aInfo = resolves.get(i).activityInfo;
3495                        }
3496                        if (debug) {
3497                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3498                                    + "/" + r.info.name);
3499                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3500                                    + "/" + aInfo.name);
3501                        }
3502                        break;
3503                    }
3504                }
3505            } catch (RemoteException e) {
3506            }
3507
3508            if (aInfo == null) {
3509                // Nobody who is next!
3510                ActivityOptions.abort(options);
3511                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3512                return false;
3513            }
3514
3515            intent.setComponent(new ComponentName(
3516                    aInfo.applicationInfo.packageName, aInfo.name));
3517            intent.setFlags(intent.getFlags()&~(
3518                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3519                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3520                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3521                    Intent.FLAG_ACTIVITY_NEW_TASK));
3522
3523            // Okay now we need to start the new activity, replacing the
3524            // currently running activity.  This is a little tricky because
3525            // we want to start the new one as if the current one is finished,
3526            // but not finish the current one first so that there is no flicker.
3527            // And thus...
3528            final boolean wasFinishing = r.finishing;
3529            r.finishing = true;
3530
3531            // Propagate reply information over to the new activity.
3532            final ActivityRecord resultTo = r.resultTo;
3533            final String resultWho = r.resultWho;
3534            final int requestCode = r.requestCode;
3535            r.resultTo = null;
3536            if (resultTo != null) {
3537                resultTo.removeResultsLocked(r, resultWho, requestCode);
3538            }
3539
3540            final long origId = Binder.clearCallingIdentity();
3541            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3542                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3543                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3544                    options, false, null, null);
3545            Binder.restoreCallingIdentity(origId);
3546
3547            r.finishing = wasFinishing;
3548            if (res != ActivityManager.START_SUCCESS) {
3549                return false;
3550            }
3551            return true;
3552        }
3553    }
3554
3555    final int startActivityInPackage(int uid, String callingPackage,
3556            Intent intent, String resolvedType, IBinder resultTo,
3557            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3558                    IActivityContainer container) {
3559
3560        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3561                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3562
3563        // TODO: Switch to user app stacks here.
3564        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3565                null, null, resultTo, resultWho, requestCode, startFlags,
3566                null, null, null, null, options, userId, container);
3567        return ret;
3568    }
3569
3570    @Override
3571    public final int startActivities(IApplicationThread caller, String callingPackage,
3572            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3573            int userId) {
3574        enforceNotIsolatedCaller("startActivities");
3575        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3576                false, ALLOW_FULL_ONLY, "startActivity", null);
3577        // TODO: Switch to user app stacks here.
3578        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3579                resolvedTypes, resultTo, options, userId);
3580        return ret;
3581    }
3582
3583    final int startActivitiesInPackage(int uid, String callingPackage,
3584            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3585            Bundle options, int userId) {
3586
3587        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3588                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3589        // TODO: Switch to user app stacks here.
3590        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3591                resultTo, options, userId);
3592        return ret;
3593    }
3594
3595    final void addRecentTaskLocked(TaskRecord task) {
3596        int N = mRecentTasks.size();
3597        // Quick case: check if the top-most recent task is the same.
3598        if (N > 0 && mRecentTasks.get(0) == task) {
3599            return;
3600        }
3601        // Another quick case: never add voice sessions.
3602        if (task.voiceSession != null) {
3603            return;
3604        }
3605        // Remove any existing entries that are the same kind of task.
3606        final Intent intent = task.intent;
3607        final boolean document = intent != null && intent.isDocument();
3608        final ComponentName comp = intent.getComponent();
3609
3610        int maxRecents = task.maxRecents - 1;
3611        for (int i=0; i<N; i++) {
3612            TaskRecord tr = mRecentTasks.get(i);
3613            if (task != tr) {
3614                if (task.userId != tr.userId) {
3615                    continue;
3616                }
3617                if (i > MAX_RECENT_BITMAPS) {
3618                    tr.freeLastThumbnail();
3619                }
3620                final Intent trIntent = tr.intent;
3621                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3622                    (intent == null || !intent.filterEquals(trIntent))) {
3623                    continue;
3624                }
3625                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3626                if (document && trIsDocument) {
3627                    // These are the same document activity (not necessarily the same doc).
3628                    if (maxRecents > 0) {
3629                        --maxRecents;
3630                        continue;
3631                    }
3632                    // Hit the maximum number of documents for this task. Fall through
3633                    // and remove this document from recents.
3634                } else if (document || trIsDocument) {
3635                    // Only one of these is a document. Not the droid we're looking for.
3636                    continue;
3637                }
3638            }
3639
3640            // Either task and tr are the same or, their affinities match or their intents match
3641            // and neither of them is a document, or they are documents using the same activity
3642            // and their maxRecents has been reached.
3643            tr.disposeThumbnail();
3644            mRecentTasks.remove(i);
3645            i--;
3646            N--;
3647            if (task.intent == null) {
3648                // If the new recent task we are adding is not fully
3649                // specified, then replace it with the existing recent task.
3650                task = tr;
3651            }
3652            mTaskPersister.notify(tr, false);
3653        }
3654        if (N >= MAX_RECENT_TASKS) {
3655            mRecentTasks.remove(N-1).disposeThumbnail();
3656        }
3657        mRecentTasks.add(0, task);
3658    }
3659
3660    @Override
3661    public void reportActivityFullyDrawn(IBinder token) {
3662        synchronized (this) {
3663            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3664            if (r == null) {
3665                return;
3666            }
3667            r.reportFullyDrawnLocked();
3668        }
3669    }
3670
3671    @Override
3672    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3673        synchronized (this) {
3674            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3675            if (r == null) {
3676                return;
3677            }
3678            final long origId = Binder.clearCallingIdentity();
3679            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3680            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3681                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3682            if (config != null) {
3683                r.frozenBeforeDestroy = true;
3684                if (!updateConfigurationLocked(config, r, false, false)) {
3685                    mStackSupervisor.resumeTopActivitiesLocked();
3686                }
3687            }
3688            Binder.restoreCallingIdentity(origId);
3689        }
3690    }
3691
3692    @Override
3693    public int getRequestedOrientation(IBinder token) {
3694        synchronized (this) {
3695            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3696            if (r == null) {
3697                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3698            }
3699            return mWindowManager.getAppOrientation(r.appToken);
3700        }
3701    }
3702
3703    /**
3704     * This is the internal entry point for handling Activity.finish().
3705     *
3706     * @param token The Binder token referencing the Activity we want to finish.
3707     * @param resultCode Result code, if any, from this Activity.
3708     * @param resultData Result data (Intent), if any, from this Activity.
3709     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3710     *            the root Activity in the task.
3711     *
3712     * @return Returns true if the activity successfully finished, or false if it is still running.
3713     */
3714    @Override
3715    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3716            boolean finishTask) {
3717        // Refuse possible leaked file descriptors
3718        if (resultData != null && resultData.hasFileDescriptors() == true) {
3719            throw new IllegalArgumentException("File descriptors passed in Intent");
3720        }
3721
3722        synchronized(this) {
3723            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3724            if (r == null) {
3725                return true;
3726            }
3727            // Keep track of the root activity of the task before we finish it
3728            TaskRecord tr = r.task;
3729            ActivityRecord rootR = tr.getRootActivity();
3730            // Do not allow task to finish in Lock Task mode.
3731            if (tr == mStackSupervisor.mLockTaskModeTask) {
3732                if (rootR == r) {
3733                    mStackSupervisor.showLockTaskToast();
3734                    return false;
3735                }
3736            }
3737            if (mController != null) {
3738                // Find the first activity that is not finishing.
3739                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3740                if (next != null) {
3741                    // ask watcher if this is allowed
3742                    boolean resumeOK = true;
3743                    try {
3744                        resumeOK = mController.activityResuming(next.packageName);
3745                    } catch (RemoteException e) {
3746                        mController = null;
3747                        Watchdog.getInstance().setActivityController(null);
3748                    }
3749
3750                    if (!resumeOK) {
3751                        return false;
3752                    }
3753                }
3754            }
3755            final long origId = Binder.clearCallingIdentity();
3756            try {
3757                boolean res;
3758                if (finishTask && r == rootR) {
3759                    // If requested, remove the task that is associated to this activity only if it
3760                    // was the root activity in the task.  The result code and data is ignored because
3761                    // we don't support returning them across task boundaries.
3762                    res = removeTaskByIdLocked(tr.taskId, 0);
3763                } else {
3764                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3765                            resultData, "app-request", true);
3766                }
3767                return res;
3768            } finally {
3769                Binder.restoreCallingIdentity(origId);
3770            }
3771        }
3772    }
3773
3774    @Override
3775    public final void finishHeavyWeightApp() {
3776        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3777                != PackageManager.PERMISSION_GRANTED) {
3778            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3779                    + Binder.getCallingPid()
3780                    + ", uid=" + Binder.getCallingUid()
3781                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3782            Slog.w(TAG, msg);
3783            throw new SecurityException(msg);
3784        }
3785
3786        synchronized(this) {
3787            if (mHeavyWeightProcess == null) {
3788                return;
3789            }
3790
3791            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3792                    mHeavyWeightProcess.activities);
3793            for (int i=0; i<activities.size(); i++) {
3794                ActivityRecord r = activities.get(i);
3795                if (!r.finishing) {
3796                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3797                            null, "finish-heavy", true);
3798                }
3799            }
3800
3801            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3802                    mHeavyWeightProcess.userId, 0));
3803            mHeavyWeightProcess = null;
3804        }
3805    }
3806
3807    @Override
3808    public void crashApplication(int uid, int initialPid, String packageName,
3809            String message) {
3810        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3811                != PackageManager.PERMISSION_GRANTED) {
3812            String msg = "Permission Denial: crashApplication() from pid="
3813                    + Binder.getCallingPid()
3814                    + ", uid=" + Binder.getCallingUid()
3815                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3816            Slog.w(TAG, msg);
3817            throw new SecurityException(msg);
3818        }
3819
3820        synchronized(this) {
3821            ProcessRecord proc = null;
3822
3823            // Figure out which process to kill.  We don't trust that initialPid
3824            // still has any relation to current pids, so must scan through the
3825            // list.
3826            synchronized (mPidsSelfLocked) {
3827                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3828                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3829                    if (p.uid != uid) {
3830                        continue;
3831                    }
3832                    if (p.pid == initialPid) {
3833                        proc = p;
3834                        break;
3835                    }
3836                    if (p.pkgList.containsKey(packageName)) {
3837                        proc = p;
3838                    }
3839                }
3840            }
3841
3842            if (proc == null) {
3843                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3844                        + " initialPid=" + initialPid
3845                        + " packageName=" + packageName);
3846                return;
3847            }
3848
3849            if (proc.thread != null) {
3850                if (proc.pid == Process.myPid()) {
3851                    Log.w(TAG, "crashApplication: trying to crash self!");
3852                    return;
3853                }
3854                long ident = Binder.clearCallingIdentity();
3855                try {
3856                    proc.thread.scheduleCrash(message);
3857                } catch (RemoteException e) {
3858                }
3859                Binder.restoreCallingIdentity(ident);
3860            }
3861        }
3862    }
3863
3864    @Override
3865    public final void finishSubActivity(IBinder token, String resultWho,
3866            int requestCode) {
3867        synchronized(this) {
3868            final long origId = Binder.clearCallingIdentity();
3869            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3870            if (r != null) {
3871                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3872            }
3873            Binder.restoreCallingIdentity(origId);
3874        }
3875    }
3876
3877    @Override
3878    public boolean finishActivityAffinity(IBinder token) {
3879        synchronized(this) {
3880            final long origId = Binder.clearCallingIdentity();
3881            try {
3882                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3883
3884                ActivityRecord rootR = r.task.getRootActivity();
3885                // Do not allow task to finish in Lock Task mode.
3886                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3887                    if (rootR == r) {
3888                        mStackSupervisor.showLockTaskToast();
3889                        return false;
3890                    }
3891                }
3892                boolean res = false;
3893                if (r != null) {
3894                    res = r.task.stack.finishActivityAffinityLocked(r);
3895                }
3896                return res;
3897            } finally {
3898                Binder.restoreCallingIdentity(origId);
3899            }
3900        }
3901    }
3902
3903    @Override
3904    public void finishVoiceTask(IVoiceInteractionSession session) {
3905        synchronized(this) {
3906            final long origId = Binder.clearCallingIdentity();
3907            try {
3908                mStackSupervisor.finishVoiceTask(session);
3909            } finally {
3910                Binder.restoreCallingIdentity(origId);
3911            }
3912        }
3913
3914    }
3915
3916    @Override
3917    public boolean willActivityBeVisible(IBinder token) {
3918        synchronized(this) {
3919            ActivityStack stack = ActivityRecord.getStackLocked(token);
3920            if (stack != null) {
3921                return stack.willActivityBeVisibleLocked(token);
3922            }
3923            return false;
3924        }
3925    }
3926
3927    @Override
3928    public void overridePendingTransition(IBinder token, String packageName,
3929            int enterAnim, int exitAnim) {
3930        synchronized(this) {
3931            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3932            if (self == null) {
3933                return;
3934            }
3935
3936            final long origId = Binder.clearCallingIdentity();
3937
3938            if (self.state == ActivityState.RESUMED
3939                    || self.state == ActivityState.PAUSING) {
3940                mWindowManager.overridePendingAppTransition(packageName,
3941                        enterAnim, exitAnim, null);
3942            }
3943
3944            Binder.restoreCallingIdentity(origId);
3945        }
3946    }
3947
3948    /**
3949     * Main function for removing an existing process from the activity manager
3950     * as a result of that process going away.  Clears out all connections
3951     * to the process.
3952     */
3953    private final void handleAppDiedLocked(ProcessRecord app,
3954            boolean restarting, boolean allowRestart) {
3955        int pid = app.pid;
3956        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3957        if (!restarting) {
3958            removeLruProcessLocked(app);
3959            if (pid > 0) {
3960                ProcessList.remove(pid);
3961            }
3962        }
3963
3964        if (mProfileProc == app) {
3965            clearProfilerLocked();
3966        }
3967
3968        // Remove this application's activities from active lists.
3969        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3970
3971        app.activities.clear();
3972
3973        if (app.instrumentationClass != null) {
3974            Slog.w(TAG, "Crash of app " + app.processName
3975                  + " running instrumentation " + app.instrumentationClass);
3976            Bundle info = new Bundle();
3977            info.putString("shortMsg", "Process crashed.");
3978            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3979        }
3980
3981        if (!restarting) {
3982            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3983                // If there was nothing to resume, and we are not already
3984                // restarting this process, but there is a visible activity that
3985                // is hosted by the process...  then make sure all visible
3986                // activities are running, taking care of restarting this
3987                // process.
3988                if (hasVisibleActivities) {
3989                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3990                }
3991            }
3992        }
3993    }
3994
3995    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3996        IBinder threadBinder = thread.asBinder();
3997        // Find the application record.
3998        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3999            ProcessRecord rec = mLruProcesses.get(i);
4000            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4001                return i;
4002            }
4003        }
4004        return -1;
4005    }
4006
4007    final ProcessRecord getRecordForAppLocked(
4008            IApplicationThread thread) {
4009        if (thread == null) {
4010            return null;
4011        }
4012
4013        int appIndex = getLRURecordIndexForAppLocked(thread);
4014        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4015    }
4016
4017    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4018        // If there are no longer any background processes running,
4019        // and the app that died was not running instrumentation,
4020        // then tell everyone we are now low on memory.
4021        boolean haveBg = false;
4022        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4023            ProcessRecord rec = mLruProcesses.get(i);
4024            if (rec.thread != null
4025                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4026                haveBg = true;
4027                break;
4028            }
4029        }
4030
4031        if (!haveBg) {
4032            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4033            if (doReport) {
4034                long now = SystemClock.uptimeMillis();
4035                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4036                    doReport = false;
4037                } else {
4038                    mLastMemUsageReportTime = now;
4039                }
4040            }
4041            final ArrayList<ProcessMemInfo> memInfos
4042                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4043            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4044            long now = SystemClock.uptimeMillis();
4045            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4046                ProcessRecord rec = mLruProcesses.get(i);
4047                if (rec == dyingProc || rec.thread == null) {
4048                    continue;
4049                }
4050                if (doReport) {
4051                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4052                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4053                }
4054                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4055                    // The low memory report is overriding any current
4056                    // state for a GC request.  Make sure to do
4057                    // heavy/important/visible/foreground processes first.
4058                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4059                        rec.lastRequestedGc = 0;
4060                    } else {
4061                        rec.lastRequestedGc = rec.lastLowMemory;
4062                    }
4063                    rec.reportLowMemory = true;
4064                    rec.lastLowMemory = now;
4065                    mProcessesToGc.remove(rec);
4066                    addProcessToGcListLocked(rec);
4067                }
4068            }
4069            if (doReport) {
4070                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4071                mHandler.sendMessage(msg);
4072            }
4073            scheduleAppGcsLocked();
4074        }
4075    }
4076
4077    final void appDiedLocked(ProcessRecord app, int pid,
4078            IApplicationThread thread) {
4079
4080        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4081        synchronized (stats) {
4082            stats.noteProcessDiedLocked(app.info.uid, pid);
4083        }
4084
4085        // Clean up already done if the process has been re-started.
4086        if (app.pid == pid && app.thread != null &&
4087                app.thread.asBinder() == thread.asBinder()) {
4088            boolean doLowMem = app.instrumentationClass == null;
4089            boolean doOomAdj = doLowMem;
4090            if (!app.killedByAm) {
4091                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4092                        + ") has died.");
4093                mAllowLowerMemLevel = true;
4094            } else {
4095                // Note that we always want to do oom adj to update our state with the
4096                // new number of procs.
4097                mAllowLowerMemLevel = false;
4098                doLowMem = false;
4099            }
4100            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4101            if (DEBUG_CLEANUP) Slog.v(
4102                TAG, "Dying app: " + app + ", pid: " + pid
4103                + ", thread: " + thread.asBinder());
4104            handleAppDiedLocked(app, false, true);
4105
4106            if (doOomAdj) {
4107                updateOomAdjLocked();
4108            }
4109            if (doLowMem) {
4110                doLowMemReportIfNeededLocked(app);
4111            }
4112        } else if (app.pid != pid) {
4113            // A new process has already been started.
4114            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4115                    + ") has died and restarted (pid " + app.pid + ").");
4116            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4117        } else if (DEBUG_PROCESSES) {
4118            Slog.d(TAG, "Received spurious death notification for thread "
4119                    + thread.asBinder());
4120        }
4121    }
4122
4123    /**
4124     * If a stack trace dump file is configured, dump process stack traces.
4125     * @param clearTraces causes the dump file to be erased prior to the new
4126     *    traces being written, if true; when false, the new traces will be
4127     *    appended to any existing file content.
4128     * @param firstPids of dalvik VM processes to dump stack traces for first
4129     * @param lastPids of dalvik VM processes to dump stack traces for last
4130     * @param nativeProcs optional list of native process names to dump stack crawls
4131     * @return file containing stack traces, or null if no dump file is configured
4132     */
4133    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4134            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4135        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4136        if (tracesPath == null || tracesPath.length() == 0) {
4137            return null;
4138        }
4139
4140        File tracesFile = new File(tracesPath);
4141        try {
4142            File tracesDir = tracesFile.getParentFile();
4143            if (!tracesDir.exists()) {
4144                tracesFile.mkdirs();
4145                if (!SELinux.restorecon(tracesDir)) {
4146                    return null;
4147                }
4148            }
4149            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4150
4151            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4152            tracesFile.createNewFile();
4153            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4154        } catch (IOException e) {
4155            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4156            return null;
4157        }
4158
4159        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4160        return tracesFile;
4161    }
4162
4163    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4164            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4165        // Use a FileObserver to detect when traces finish writing.
4166        // The order of traces is considered important to maintain for legibility.
4167        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4168            @Override
4169            public synchronized void onEvent(int event, String path) { notify(); }
4170        };
4171
4172        try {
4173            observer.startWatching();
4174
4175            // First collect all of the stacks of the most important pids.
4176            if (firstPids != null) {
4177                try {
4178                    int num = firstPids.size();
4179                    for (int i = 0; i < num; i++) {
4180                        synchronized (observer) {
4181                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4182                            observer.wait(200);  // Wait for write-close, give up after 200msec
4183                        }
4184                    }
4185                } catch (InterruptedException e) {
4186                    Log.wtf(TAG, e);
4187                }
4188            }
4189
4190            // Next collect the stacks of the native pids
4191            if (nativeProcs != null) {
4192                int[] pids = Process.getPidsForCommands(nativeProcs);
4193                if (pids != null) {
4194                    for (int pid : pids) {
4195                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4196                    }
4197                }
4198            }
4199
4200            // Lastly, measure CPU usage.
4201            if (processCpuTracker != null) {
4202                processCpuTracker.init();
4203                System.gc();
4204                processCpuTracker.update();
4205                try {
4206                    synchronized (processCpuTracker) {
4207                        processCpuTracker.wait(500); // measure over 1/2 second.
4208                    }
4209                } catch (InterruptedException e) {
4210                }
4211                processCpuTracker.update();
4212
4213                // We'll take the stack crawls of just the top apps using CPU.
4214                final int N = processCpuTracker.countWorkingStats();
4215                int numProcs = 0;
4216                for (int i=0; i<N && numProcs<5; i++) {
4217                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4218                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4219                        numProcs++;
4220                        try {
4221                            synchronized (observer) {
4222                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4223                                observer.wait(200);  // Wait for write-close, give up after 200msec
4224                            }
4225                        } catch (InterruptedException e) {
4226                            Log.wtf(TAG, e);
4227                        }
4228
4229                    }
4230                }
4231            }
4232        } finally {
4233            observer.stopWatching();
4234        }
4235    }
4236
4237    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4238        if (true || IS_USER_BUILD) {
4239            return;
4240        }
4241        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4242        if (tracesPath == null || tracesPath.length() == 0) {
4243            return;
4244        }
4245
4246        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4247        StrictMode.allowThreadDiskWrites();
4248        try {
4249            final File tracesFile = new File(tracesPath);
4250            final File tracesDir = tracesFile.getParentFile();
4251            final File tracesTmp = new File(tracesDir, "__tmp__");
4252            try {
4253                if (!tracesDir.exists()) {
4254                    tracesFile.mkdirs();
4255                    if (!SELinux.restorecon(tracesDir.getPath())) {
4256                        return;
4257                    }
4258                }
4259                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4260
4261                if (tracesFile.exists()) {
4262                    tracesTmp.delete();
4263                    tracesFile.renameTo(tracesTmp);
4264                }
4265                StringBuilder sb = new StringBuilder();
4266                Time tobj = new Time();
4267                tobj.set(System.currentTimeMillis());
4268                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4269                sb.append(": ");
4270                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4271                sb.append(" since ");
4272                sb.append(msg);
4273                FileOutputStream fos = new FileOutputStream(tracesFile);
4274                fos.write(sb.toString().getBytes());
4275                if (app == null) {
4276                    fos.write("\n*** No application process!".getBytes());
4277                }
4278                fos.close();
4279                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4280            } catch (IOException e) {
4281                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4282                return;
4283            }
4284
4285            if (app != null) {
4286                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4287                firstPids.add(app.pid);
4288                dumpStackTraces(tracesPath, firstPids, null, null, null);
4289            }
4290
4291            File lastTracesFile = null;
4292            File curTracesFile = null;
4293            for (int i=9; i>=0; i--) {
4294                String name = String.format(Locale.US, "slow%02d.txt", i);
4295                curTracesFile = new File(tracesDir, name);
4296                if (curTracesFile.exists()) {
4297                    if (lastTracesFile != null) {
4298                        curTracesFile.renameTo(lastTracesFile);
4299                    } else {
4300                        curTracesFile.delete();
4301                    }
4302                }
4303                lastTracesFile = curTracesFile;
4304            }
4305            tracesFile.renameTo(curTracesFile);
4306            if (tracesTmp.exists()) {
4307                tracesTmp.renameTo(tracesFile);
4308            }
4309        } finally {
4310            StrictMode.setThreadPolicy(oldPolicy);
4311        }
4312    }
4313
4314    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4315            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4316        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4317        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4318
4319        if (mController != null) {
4320            try {
4321                // 0 == continue, -1 = kill process immediately
4322                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4323                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4324            } catch (RemoteException e) {
4325                mController = null;
4326                Watchdog.getInstance().setActivityController(null);
4327            }
4328        }
4329
4330        long anrTime = SystemClock.uptimeMillis();
4331        if (MONITOR_CPU_USAGE) {
4332            updateCpuStatsNow();
4333        }
4334
4335        synchronized (this) {
4336            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4337            if (mShuttingDown) {
4338                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4339                return;
4340            } else if (app.notResponding) {
4341                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4342                return;
4343            } else if (app.crashing) {
4344                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4345                return;
4346            }
4347
4348            // In case we come through here for the same app before completing
4349            // this one, mark as anring now so we will bail out.
4350            app.notResponding = true;
4351
4352            // Log the ANR to the event log.
4353            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4354                    app.processName, app.info.flags, annotation);
4355
4356            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4357            firstPids.add(app.pid);
4358
4359            int parentPid = app.pid;
4360            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4361            if (parentPid != app.pid) firstPids.add(parentPid);
4362
4363            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4364
4365            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4366                ProcessRecord r = mLruProcesses.get(i);
4367                if (r != null && r.thread != null) {
4368                    int pid = r.pid;
4369                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4370                        if (r.persistent) {
4371                            firstPids.add(pid);
4372                        } else {
4373                            lastPids.put(pid, Boolean.TRUE);
4374                        }
4375                    }
4376                }
4377            }
4378        }
4379
4380        // Log the ANR to the main log.
4381        StringBuilder info = new StringBuilder();
4382        info.setLength(0);
4383        info.append("ANR in ").append(app.processName);
4384        if (activity != null && activity.shortComponentName != null) {
4385            info.append(" (").append(activity.shortComponentName).append(")");
4386        }
4387        info.append("\n");
4388        info.append("PID: ").append(app.pid).append("\n");
4389        if (annotation != null) {
4390            info.append("Reason: ").append(annotation).append("\n");
4391        }
4392        if (parent != null && parent != activity) {
4393            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4394        }
4395
4396        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4397
4398        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4399                NATIVE_STACKS_OF_INTEREST);
4400
4401        String cpuInfo = null;
4402        if (MONITOR_CPU_USAGE) {
4403            updateCpuStatsNow();
4404            synchronized (mProcessCpuThread) {
4405                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4406            }
4407            info.append(processCpuTracker.printCurrentLoad());
4408            info.append(cpuInfo);
4409        }
4410
4411        info.append(processCpuTracker.printCurrentState(anrTime));
4412
4413        Slog.e(TAG, info.toString());
4414        if (tracesFile == null) {
4415            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4416            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4417        }
4418
4419        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4420                cpuInfo, tracesFile, null);
4421
4422        if (mController != null) {
4423            try {
4424                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4425                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4426                if (res != 0) {
4427                    if (res < 0 && app.pid != MY_PID) {
4428                        Process.killProcess(app.pid);
4429                    } else {
4430                        synchronized (this) {
4431                            mServices.scheduleServiceTimeoutLocked(app);
4432                        }
4433                    }
4434                    return;
4435                }
4436            } catch (RemoteException e) {
4437                mController = null;
4438                Watchdog.getInstance().setActivityController(null);
4439            }
4440        }
4441
4442        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4443        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4444                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4445
4446        synchronized (this) {
4447            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4448                killUnneededProcessLocked(app, "background ANR");
4449                return;
4450            }
4451
4452            // Set the app's notResponding state, and look up the errorReportReceiver
4453            makeAppNotRespondingLocked(app,
4454                    activity != null ? activity.shortComponentName : null,
4455                    annotation != null ? "ANR " + annotation : "ANR",
4456                    info.toString());
4457
4458            // Bring up the infamous App Not Responding dialog
4459            Message msg = Message.obtain();
4460            HashMap<String, Object> map = new HashMap<String, Object>();
4461            msg.what = SHOW_NOT_RESPONDING_MSG;
4462            msg.obj = map;
4463            msg.arg1 = aboveSystem ? 1 : 0;
4464            map.put("app", app);
4465            if (activity != null) {
4466                map.put("activity", activity);
4467            }
4468
4469            mHandler.sendMessage(msg);
4470        }
4471    }
4472
4473    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4474        if (!mLaunchWarningShown) {
4475            mLaunchWarningShown = true;
4476            mHandler.post(new Runnable() {
4477                @Override
4478                public void run() {
4479                    synchronized (ActivityManagerService.this) {
4480                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4481                        d.show();
4482                        mHandler.postDelayed(new Runnable() {
4483                            @Override
4484                            public void run() {
4485                                synchronized (ActivityManagerService.this) {
4486                                    d.dismiss();
4487                                    mLaunchWarningShown = false;
4488                                }
4489                            }
4490                        }, 4000);
4491                    }
4492                }
4493            });
4494        }
4495    }
4496
4497    @Override
4498    public boolean clearApplicationUserData(final String packageName,
4499            final IPackageDataObserver observer, int userId) {
4500        enforceNotIsolatedCaller("clearApplicationUserData");
4501        int uid = Binder.getCallingUid();
4502        int pid = Binder.getCallingPid();
4503        userId = handleIncomingUser(pid, uid,
4504                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4505        long callingId = Binder.clearCallingIdentity();
4506        try {
4507            IPackageManager pm = AppGlobals.getPackageManager();
4508            int pkgUid = -1;
4509            synchronized(this) {
4510                try {
4511                    pkgUid = pm.getPackageUid(packageName, userId);
4512                } catch (RemoteException e) {
4513                }
4514                if (pkgUid == -1) {
4515                    Slog.w(TAG, "Invalid packageName: " + packageName);
4516                    if (observer != null) {
4517                        try {
4518                            observer.onRemoveCompleted(packageName, false);
4519                        } catch (RemoteException e) {
4520                            Slog.i(TAG, "Observer no longer exists.");
4521                        }
4522                    }
4523                    return false;
4524                }
4525                if (uid == pkgUid || checkComponentPermission(
4526                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4527                        pid, uid, -1, true)
4528                        == PackageManager.PERMISSION_GRANTED) {
4529                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4530                } else {
4531                    throw new SecurityException("PID " + pid + " does not have permission "
4532                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4533                                    + " of package " + packageName);
4534                }
4535            }
4536
4537            try {
4538                // Clear application user data
4539                pm.clearApplicationUserData(packageName, observer, userId);
4540
4541                // Remove all permissions granted from/to this package
4542                removeUriPermissionsForPackageLocked(packageName, userId, true);
4543
4544                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4545                        Uri.fromParts("package", packageName, null));
4546                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4547                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4548                        null, null, 0, null, null, null, false, false, userId);
4549            } catch (RemoteException e) {
4550            }
4551        } finally {
4552            Binder.restoreCallingIdentity(callingId);
4553        }
4554        return true;
4555    }
4556
4557    @Override
4558    public void killBackgroundProcesses(final String packageName, int userId) {
4559        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4560                != PackageManager.PERMISSION_GRANTED &&
4561                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4562                        != PackageManager.PERMISSION_GRANTED) {
4563            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4564                    + Binder.getCallingPid()
4565                    + ", uid=" + Binder.getCallingUid()
4566                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4567            Slog.w(TAG, msg);
4568            throw new SecurityException(msg);
4569        }
4570
4571        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4572                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4573        long callingId = Binder.clearCallingIdentity();
4574        try {
4575            IPackageManager pm = AppGlobals.getPackageManager();
4576            synchronized(this) {
4577                int appId = -1;
4578                try {
4579                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4580                } catch (RemoteException e) {
4581                }
4582                if (appId == -1) {
4583                    Slog.w(TAG, "Invalid packageName: " + packageName);
4584                    return;
4585                }
4586                killPackageProcessesLocked(packageName, appId, userId,
4587                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4588            }
4589        } finally {
4590            Binder.restoreCallingIdentity(callingId);
4591        }
4592    }
4593
4594    @Override
4595    public void killAllBackgroundProcesses() {
4596        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4597                != PackageManager.PERMISSION_GRANTED) {
4598            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4599                    + Binder.getCallingPid()
4600                    + ", uid=" + Binder.getCallingUid()
4601                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4602            Slog.w(TAG, msg);
4603            throw new SecurityException(msg);
4604        }
4605
4606        long callingId = Binder.clearCallingIdentity();
4607        try {
4608            synchronized(this) {
4609                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4610                final int NP = mProcessNames.getMap().size();
4611                for (int ip=0; ip<NP; ip++) {
4612                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4613                    final int NA = apps.size();
4614                    for (int ia=0; ia<NA; ia++) {
4615                        ProcessRecord app = apps.valueAt(ia);
4616                        if (app.persistent) {
4617                            // we don't kill persistent processes
4618                            continue;
4619                        }
4620                        if (app.removed) {
4621                            procs.add(app);
4622                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4623                            app.removed = true;
4624                            procs.add(app);
4625                        }
4626                    }
4627                }
4628
4629                int N = procs.size();
4630                for (int i=0; i<N; i++) {
4631                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4632                }
4633                mAllowLowerMemLevel = true;
4634                updateOomAdjLocked();
4635                doLowMemReportIfNeededLocked(null);
4636            }
4637        } finally {
4638            Binder.restoreCallingIdentity(callingId);
4639        }
4640    }
4641
4642    @Override
4643    public void forceStopPackage(final String packageName, int userId) {
4644        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4645                != PackageManager.PERMISSION_GRANTED) {
4646            String msg = "Permission Denial: forceStopPackage() from pid="
4647                    + Binder.getCallingPid()
4648                    + ", uid=" + Binder.getCallingUid()
4649                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4650            Slog.w(TAG, msg);
4651            throw new SecurityException(msg);
4652        }
4653        final int callingPid = Binder.getCallingPid();
4654        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4655                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4656        long callingId = Binder.clearCallingIdentity();
4657        try {
4658            IPackageManager pm = AppGlobals.getPackageManager();
4659            synchronized(this) {
4660                int[] users = userId == UserHandle.USER_ALL
4661                        ? getUsersLocked() : new int[] { userId };
4662                for (int user : users) {
4663                    int pkgUid = -1;
4664                    try {
4665                        pkgUid = pm.getPackageUid(packageName, user);
4666                    } catch (RemoteException e) {
4667                    }
4668                    if (pkgUid == -1) {
4669                        Slog.w(TAG, "Invalid packageName: " + packageName);
4670                        continue;
4671                    }
4672                    try {
4673                        pm.setPackageStoppedState(packageName, true, user);
4674                    } catch (RemoteException e) {
4675                    } catch (IllegalArgumentException e) {
4676                        Slog.w(TAG, "Failed trying to unstop package "
4677                                + packageName + ": " + e);
4678                    }
4679                    if (isUserRunningLocked(user, false)) {
4680                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4681                    }
4682                }
4683            }
4684        } finally {
4685            Binder.restoreCallingIdentity(callingId);
4686        }
4687    }
4688
4689    /*
4690     * The pkg name and app id have to be specified.
4691     */
4692    @Override
4693    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4694        if (pkg == null) {
4695            return;
4696        }
4697        // Make sure the uid is valid.
4698        if (appid < 0) {
4699            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4700            return;
4701        }
4702        int callerUid = Binder.getCallingUid();
4703        // Only the system server can kill an application
4704        if (callerUid == Process.SYSTEM_UID) {
4705            // Post an aysnc message to kill the application
4706            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4707            msg.arg1 = appid;
4708            msg.arg2 = 0;
4709            Bundle bundle = new Bundle();
4710            bundle.putString("pkg", pkg);
4711            bundle.putString("reason", reason);
4712            msg.obj = bundle;
4713            mHandler.sendMessage(msg);
4714        } else {
4715            throw new SecurityException(callerUid + " cannot kill pkg: " +
4716                    pkg);
4717        }
4718    }
4719
4720    @Override
4721    public void closeSystemDialogs(String reason) {
4722        enforceNotIsolatedCaller("closeSystemDialogs");
4723
4724        final int pid = Binder.getCallingPid();
4725        final int uid = Binder.getCallingUid();
4726        final long origId = Binder.clearCallingIdentity();
4727        try {
4728            synchronized (this) {
4729                // Only allow this from foreground processes, so that background
4730                // applications can't abuse it to prevent system UI from being shown.
4731                if (uid >= Process.FIRST_APPLICATION_UID) {
4732                    ProcessRecord proc;
4733                    synchronized (mPidsSelfLocked) {
4734                        proc = mPidsSelfLocked.get(pid);
4735                    }
4736                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4737                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4738                                + " from background process " + proc);
4739                        return;
4740                    }
4741                }
4742                closeSystemDialogsLocked(reason);
4743            }
4744        } finally {
4745            Binder.restoreCallingIdentity(origId);
4746        }
4747    }
4748
4749    void closeSystemDialogsLocked(String reason) {
4750        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4751        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4752                | Intent.FLAG_RECEIVER_FOREGROUND);
4753        if (reason != null) {
4754            intent.putExtra("reason", reason);
4755        }
4756        mWindowManager.closeSystemDialogs(reason);
4757
4758        mStackSupervisor.closeSystemDialogsLocked();
4759
4760        broadcastIntentLocked(null, null, intent, null,
4761                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4762                Process.SYSTEM_UID, UserHandle.USER_ALL);
4763    }
4764
4765    @Override
4766    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4767        enforceNotIsolatedCaller("getProcessMemoryInfo");
4768        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4769        for (int i=pids.length-1; i>=0; i--) {
4770            ProcessRecord proc;
4771            int oomAdj;
4772            synchronized (this) {
4773                synchronized (mPidsSelfLocked) {
4774                    proc = mPidsSelfLocked.get(pids[i]);
4775                    oomAdj = proc != null ? proc.setAdj : 0;
4776                }
4777            }
4778            infos[i] = new Debug.MemoryInfo();
4779            Debug.getMemoryInfo(pids[i], infos[i]);
4780            if (proc != null) {
4781                synchronized (this) {
4782                    if (proc.thread != null && proc.setAdj == oomAdj) {
4783                        // Record this for posterity if the process has been stable.
4784                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4785                                infos[i].getTotalUss(), false, proc.pkgList);
4786                    }
4787                }
4788            }
4789        }
4790        return infos;
4791    }
4792
4793    @Override
4794    public long[] getProcessPss(int[] pids) {
4795        enforceNotIsolatedCaller("getProcessPss");
4796        long[] pss = new long[pids.length];
4797        for (int i=pids.length-1; i>=0; i--) {
4798            ProcessRecord proc;
4799            int oomAdj;
4800            synchronized (this) {
4801                synchronized (mPidsSelfLocked) {
4802                    proc = mPidsSelfLocked.get(pids[i]);
4803                    oomAdj = proc != null ? proc.setAdj : 0;
4804                }
4805            }
4806            long[] tmpUss = new long[1];
4807            pss[i] = Debug.getPss(pids[i], tmpUss);
4808            if (proc != null) {
4809                synchronized (this) {
4810                    if (proc.thread != null && proc.setAdj == oomAdj) {
4811                        // Record this for posterity if the process has been stable.
4812                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4813                    }
4814                }
4815            }
4816        }
4817        return pss;
4818    }
4819
4820    @Override
4821    public void killApplicationProcess(String processName, int uid) {
4822        if (processName == null) {
4823            return;
4824        }
4825
4826        int callerUid = Binder.getCallingUid();
4827        // Only the system server can kill an application
4828        if (callerUid == Process.SYSTEM_UID) {
4829            synchronized (this) {
4830                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4831                if (app != null && app.thread != null) {
4832                    try {
4833                        app.thread.scheduleSuicide();
4834                    } catch (RemoteException e) {
4835                        // If the other end already died, then our work here is done.
4836                    }
4837                } else {
4838                    Slog.w(TAG, "Process/uid not found attempting kill of "
4839                            + processName + " / " + uid);
4840                }
4841            }
4842        } else {
4843            throw new SecurityException(callerUid + " cannot kill app process: " +
4844                    processName);
4845        }
4846    }
4847
4848    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4849        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4850                false, true, false, false, UserHandle.getUserId(uid), reason);
4851        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4852                Uri.fromParts("package", packageName, null));
4853        if (!mProcessesReady) {
4854            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4855                    | Intent.FLAG_RECEIVER_FOREGROUND);
4856        }
4857        intent.putExtra(Intent.EXTRA_UID, uid);
4858        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4859        broadcastIntentLocked(null, null, intent,
4860                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4861                false, false,
4862                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4863    }
4864
4865    private void forceStopUserLocked(int userId, String reason) {
4866        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4867        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4868        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4869                | Intent.FLAG_RECEIVER_FOREGROUND);
4870        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4871        broadcastIntentLocked(null, null, intent,
4872                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4873                false, false,
4874                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4875    }
4876
4877    private final boolean killPackageProcessesLocked(String packageName, int appId,
4878            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4879            boolean doit, boolean evenPersistent, String reason) {
4880        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4881
4882        // Remove all processes this package may have touched: all with the
4883        // same UID (except for the system or root user), and all whose name
4884        // matches the package name.
4885        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4886        final int NP = mProcessNames.getMap().size();
4887        for (int ip=0; ip<NP; ip++) {
4888            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4889            final int NA = apps.size();
4890            for (int ia=0; ia<NA; ia++) {
4891                ProcessRecord app = apps.valueAt(ia);
4892                if (app.persistent && !evenPersistent) {
4893                    // we don't kill persistent processes
4894                    continue;
4895                }
4896                if (app.removed) {
4897                    if (doit) {
4898                        procs.add(app);
4899                    }
4900                    continue;
4901                }
4902
4903                // Skip process if it doesn't meet our oom adj requirement.
4904                if (app.setAdj < minOomAdj) {
4905                    continue;
4906                }
4907
4908                // If no package is specified, we call all processes under the
4909                // give user id.
4910                if (packageName == null) {
4911                    if (app.userId != userId) {
4912                        continue;
4913                    }
4914                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4915                        continue;
4916                    }
4917                // Package has been specified, we want to hit all processes
4918                // that match it.  We need to qualify this by the processes
4919                // that are running under the specified app and user ID.
4920                } else {
4921                    if (UserHandle.getAppId(app.uid) != appId) {
4922                        continue;
4923                    }
4924                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4925                        continue;
4926                    }
4927                    if (!app.pkgList.containsKey(packageName)) {
4928                        continue;
4929                    }
4930                }
4931
4932                // Process has passed all conditions, kill it!
4933                if (!doit) {
4934                    return true;
4935                }
4936                app.removed = true;
4937                procs.add(app);
4938            }
4939        }
4940
4941        int N = procs.size();
4942        for (int i=0; i<N; i++) {
4943            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4944        }
4945        updateOomAdjLocked();
4946        return N > 0;
4947    }
4948
4949    private final boolean forceStopPackageLocked(String name, int appId,
4950            boolean callerWillRestart, boolean purgeCache, boolean doit,
4951            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4952        int i;
4953        int N;
4954
4955        if (userId == UserHandle.USER_ALL && name == null) {
4956            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4957        }
4958
4959        if (appId < 0 && name != null) {
4960            try {
4961                appId = UserHandle.getAppId(
4962                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4963            } catch (RemoteException e) {
4964            }
4965        }
4966
4967        if (doit) {
4968            if (name != null) {
4969                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4970                        + " user=" + userId + ": " + reason);
4971            } else {
4972                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4973            }
4974
4975            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4976            for (int ip=pmap.size()-1; ip>=0; ip--) {
4977                SparseArray<Long> ba = pmap.valueAt(ip);
4978                for (i=ba.size()-1; i>=0; i--) {
4979                    boolean remove = false;
4980                    final int entUid = ba.keyAt(i);
4981                    if (name != null) {
4982                        if (userId == UserHandle.USER_ALL) {
4983                            if (UserHandle.getAppId(entUid) == appId) {
4984                                remove = true;
4985                            }
4986                        } else {
4987                            if (entUid == UserHandle.getUid(userId, appId)) {
4988                                remove = true;
4989                            }
4990                        }
4991                    } else if (UserHandle.getUserId(entUid) == userId) {
4992                        remove = true;
4993                    }
4994                    if (remove) {
4995                        ba.removeAt(i);
4996                    }
4997                }
4998                if (ba.size() == 0) {
4999                    pmap.removeAt(ip);
5000                }
5001            }
5002        }
5003
5004        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5005                -100, callerWillRestart, true, doit, evenPersistent,
5006                name == null ? ("stop user " + userId) : ("stop " + name));
5007
5008        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5009            if (!doit) {
5010                return true;
5011            }
5012            didSomething = true;
5013        }
5014
5015        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5016            if (!doit) {
5017                return true;
5018            }
5019            didSomething = true;
5020        }
5021
5022        if (name == null) {
5023            // Remove all sticky broadcasts from this user.
5024            mStickyBroadcasts.remove(userId);
5025        }
5026
5027        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5028        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5029                userId, providers)) {
5030            if (!doit) {
5031                return true;
5032            }
5033            didSomething = true;
5034        }
5035        N = providers.size();
5036        for (i=0; i<N; i++) {
5037            removeDyingProviderLocked(null, providers.get(i), true);
5038        }
5039
5040        // Remove transient permissions granted from/to this package/user
5041        removeUriPermissionsForPackageLocked(name, userId, false);
5042
5043        if (name == null || uninstalling) {
5044            // Remove pending intents.  For now we only do this when force
5045            // stopping users, because we have some problems when doing this
5046            // for packages -- app widgets are not currently cleaned up for
5047            // such packages, so they can be left with bad pending intents.
5048            if (mIntentSenderRecords.size() > 0) {
5049                Iterator<WeakReference<PendingIntentRecord>> it
5050                        = mIntentSenderRecords.values().iterator();
5051                while (it.hasNext()) {
5052                    WeakReference<PendingIntentRecord> wpir = it.next();
5053                    if (wpir == null) {
5054                        it.remove();
5055                        continue;
5056                    }
5057                    PendingIntentRecord pir = wpir.get();
5058                    if (pir == null) {
5059                        it.remove();
5060                        continue;
5061                    }
5062                    if (name == null) {
5063                        // Stopping user, remove all objects for the user.
5064                        if (pir.key.userId != userId) {
5065                            // Not the same user, skip it.
5066                            continue;
5067                        }
5068                    } else {
5069                        if (UserHandle.getAppId(pir.uid) != appId) {
5070                            // Different app id, skip it.
5071                            continue;
5072                        }
5073                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5074                            // Different user, skip it.
5075                            continue;
5076                        }
5077                        if (!pir.key.packageName.equals(name)) {
5078                            // Different package, skip it.
5079                            continue;
5080                        }
5081                    }
5082                    if (!doit) {
5083                        return true;
5084                    }
5085                    didSomething = true;
5086                    it.remove();
5087                    pir.canceled = true;
5088                    if (pir.key.activity != null) {
5089                        pir.key.activity.pendingResults.remove(pir.ref);
5090                    }
5091                }
5092            }
5093        }
5094
5095        if (doit) {
5096            if (purgeCache && name != null) {
5097                AttributeCache ac = AttributeCache.instance();
5098                if (ac != null) {
5099                    ac.removePackage(name);
5100                }
5101            }
5102            if (mBooted) {
5103                mStackSupervisor.resumeTopActivitiesLocked();
5104                mStackSupervisor.scheduleIdleLocked();
5105            }
5106        }
5107
5108        return didSomething;
5109    }
5110
5111    private final boolean removeProcessLocked(ProcessRecord app,
5112            boolean callerWillRestart, boolean allowRestart, String reason) {
5113        final String name = app.processName;
5114        final int uid = app.uid;
5115        if (DEBUG_PROCESSES) Slog.d(
5116            TAG, "Force removing proc " + app.toShortString() + " (" + name
5117            + "/" + uid + ")");
5118
5119        mProcessNames.remove(name, uid);
5120        mIsolatedProcesses.remove(app.uid);
5121        if (mHeavyWeightProcess == app) {
5122            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5123                    mHeavyWeightProcess.userId, 0));
5124            mHeavyWeightProcess = null;
5125        }
5126        boolean needRestart = false;
5127        if (app.pid > 0 && app.pid != MY_PID) {
5128            int pid = app.pid;
5129            synchronized (mPidsSelfLocked) {
5130                mPidsSelfLocked.remove(pid);
5131                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5132            }
5133            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5134            if (app.isolated) {
5135                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5136            }
5137            killUnneededProcessLocked(app, reason);
5138            handleAppDiedLocked(app, true, allowRestart);
5139            removeLruProcessLocked(app);
5140
5141            if (app.persistent && !app.isolated) {
5142                if (!callerWillRestart) {
5143                    addAppLocked(app.info, false, null /* ABI override */);
5144                } else {
5145                    needRestart = true;
5146                }
5147            }
5148        } else {
5149            mRemovedProcesses.add(app);
5150        }
5151
5152        return needRestart;
5153    }
5154
5155    private final void processStartTimedOutLocked(ProcessRecord app) {
5156        final int pid = app.pid;
5157        boolean gone = false;
5158        synchronized (mPidsSelfLocked) {
5159            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5160            if (knownApp != null && knownApp.thread == null) {
5161                mPidsSelfLocked.remove(pid);
5162                gone = true;
5163            }
5164        }
5165
5166        if (gone) {
5167            Slog.w(TAG, "Process " + app + " failed to attach");
5168            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5169                    pid, app.uid, app.processName);
5170            mProcessNames.remove(app.processName, app.uid);
5171            mIsolatedProcesses.remove(app.uid);
5172            if (mHeavyWeightProcess == app) {
5173                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5174                        mHeavyWeightProcess.userId, 0));
5175                mHeavyWeightProcess = null;
5176            }
5177            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5178            if (app.isolated) {
5179                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5180            }
5181            // Take care of any launching providers waiting for this process.
5182            checkAppInLaunchingProvidersLocked(app, true);
5183            // Take care of any services that are waiting for the process.
5184            mServices.processStartTimedOutLocked(app);
5185            killUnneededProcessLocked(app, "start timeout");
5186            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5187                Slog.w(TAG, "Unattached app died before backup, skipping");
5188                try {
5189                    IBackupManager bm = IBackupManager.Stub.asInterface(
5190                            ServiceManager.getService(Context.BACKUP_SERVICE));
5191                    bm.agentDisconnected(app.info.packageName);
5192                } catch (RemoteException e) {
5193                    // Can't happen; the backup manager is local
5194                }
5195            }
5196            if (isPendingBroadcastProcessLocked(pid)) {
5197                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5198                skipPendingBroadcastLocked(pid);
5199            }
5200        } else {
5201            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5202        }
5203    }
5204
5205    private final boolean attachApplicationLocked(IApplicationThread thread,
5206            int pid) {
5207
5208        // Find the application record that is being attached...  either via
5209        // the pid if we are running in multiple processes, or just pull the
5210        // next app record if we are emulating process with anonymous threads.
5211        ProcessRecord app;
5212        if (pid != MY_PID && pid >= 0) {
5213            synchronized (mPidsSelfLocked) {
5214                app = mPidsSelfLocked.get(pid);
5215            }
5216        } else {
5217            app = null;
5218        }
5219
5220        if (app == null) {
5221            Slog.w(TAG, "No pending application record for pid " + pid
5222                    + " (IApplicationThread " + thread + "); dropping process");
5223            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5224            if (pid > 0 && pid != MY_PID) {
5225                Process.killProcessQuiet(pid);
5226            } else {
5227                try {
5228                    thread.scheduleExit();
5229                } catch (Exception e) {
5230                    // Ignore exceptions.
5231                }
5232            }
5233            return false;
5234        }
5235
5236        // If this application record is still attached to a previous
5237        // process, clean it up now.
5238        if (app.thread != null) {
5239            handleAppDiedLocked(app, true, true);
5240        }
5241
5242        // Tell the process all about itself.
5243
5244        if (localLOGV) Slog.v(
5245                TAG, "Binding process pid " + pid + " to record " + app);
5246
5247        final String processName = app.processName;
5248        try {
5249            AppDeathRecipient adr = new AppDeathRecipient(
5250                    app, pid, thread);
5251            thread.asBinder().linkToDeath(adr, 0);
5252            app.deathRecipient = adr;
5253        } catch (RemoteException e) {
5254            app.resetPackageList(mProcessStats);
5255            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5256            return false;
5257        }
5258
5259        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5260
5261        app.makeActive(thread, mProcessStats);
5262        app.curAdj = app.setAdj = -100;
5263        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5264        app.forcingToForeground = null;
5265        updateProcessForegroundLocked(app, false, false);
5266        app.hasShownUi = false;
5267        app.debugging = false;
5268        app.cached = false;
5269
5270        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5271
5272        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5273        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5274
5275        if (!normalMode) {
5276            Slog.i(TAG, "Launching preboot mode app: " + app);
5277        }
5278
5279        if (localLOGV) Slog.v(
5280            TAG, "New app record " + app
5281            + " thread=" + thread.asBinder() + " pid=" + pid);
5282        try {
5283            int testMode = IApplicationThread.DEBUG_OFF;
5284            if (mDebugApp != null && mDebugApp.equals(processName)) {
5285                testMode = mWaitForDebugger
5286                    ? IApplicationThread.DEBUG_WAIT
5287                    : IApplicationThread.DEBUG_ON;
5288                app.debugging = true;
5289                if (mDebugTransient) {
5290                    mDebugApp = mOrigDebugApp;
5291                    mWaitForDebugger = mOrigWaitForDebugger;
5292                }
5293            }
5294            String profileFile = app.instrumentationProfileFile;
5295            ParcelFileDescriptor profileFd = null;
5296            boolean profileAutoStop = false;
5297            if (mProfileApp != null && mProfileApp.equals(processName)) {
5298                mProfileProc = app;
5299                profileFile = mProfileFile;
5300                profileFd = mProfileFd;
5301                profileAutoStop = mAutoStopProfiler;
5302            }
5303            boolean enableOpenGlTrace = false;
5304            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5305                enableOpenGlTrace = true;
5306                mOpenGlTraceApp = null;
5307            }
5308
5309            // If the app is being launched for restore or full backup, set it up specially
5310            boolean isRestrictedBackupMode = false;
5311            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5312                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5313                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5314                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5315            }
5316
5317            ensurePackageDexOpt(app.instrumentationInfo != null
5318                    ? app.instrumentationInfo.packageName
5319                    : app.info.packageName);
5320            if (app.instrumentationClass != null) {
5321                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5322            }
5323            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5324                    + processName + " with config " + mConfiguration);
5325            ApplicationInfo appInfo = app.instrumentationInfo != null
5326                    ? app.instrumentationInfo : app.info;
5327            app.compat = compatibilityInfoForPackageLocked(appInfo);
5328            if (profileFd != null) {
5329                profileFd = profileFd.dup();
5330            }
5331            thread.bindApplication(processName, appInfo, providers,
5332                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5333                    app.instrumentationArguments, app.instrumentationWatcher,
5334                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5335                    isRestrictedBackupMode || !normalMode, app.persistent,
5336                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5337                    mCoreSettingsObserver.getCoreSettingsLocked());
5338            updateLruProcessLocked(app, false, null);
5339            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5340        } catch (Exception e) {
5341            // todo: Yikes!  What should we do?  For now we will try to
5342            // start another process, but that could easily get us in
5343            // an infinite loop of restarting processes...
5344            Slog.w(TAG, "Exception thrown during bind!", e);
5345
5346            app.resetPackageList(mProcessStats);
5347            app.unlinkDeathRecipient();
5348            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5349            return false;
5350        }
5351
5352        // Remove this record from the list of starting applications.
5353        mPersistentStartingProcesses.remove(app);
5354        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5355                "Attach application locked removing on hold: " + app);
5356        mProcessesOnHold.remove(app);
5357
5358        boolean badApp = false;
5359        boolean didSomething = false;
5360
5361        // See if the top visible activity is waiting to run in this process...
5362        if (normalMode) {
5363            try {
5364                if (mStackSupervisor.attachApplicationLocked(app)) {
5365                    didSomething = true;
5366                }
5367            } catch (Exception e) {
5368                badApp = true;
5369            }
5370        }
5371
5372        // Find any services that should be running in this process...
5373        if (!badApp) {
5374            try {
5375                didSomething |= mServices.attachApplicationLocked(app, processName);
5376            } catch (Exception e) {
5377                badApp = true;
5378            }
5379        }
5380
5381        // Check if a next-broadcast receiver is in this process...
5382        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5383            try {
5384                didSomething |= sendPendingBroadcastsLocked(app);
5385            } catch (Exception e) {
5386                // If the app died trying to launch the receiver we declare it 'bad'
5387                badApp = true;
5388            }
5389        }
5390
5391        // Check whether the next backup agent is in this process...
5392        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5393            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5394            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5395            try {
5396                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5397                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5398                        mBackupTarget.backupMode);
5399            } catch (Exception e) {
5400                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5401                e.printStackTrace();
5402            }
5403        }
5404
5405        if (badApp) {
5406            // todo: Also need to kill application to deal with all
5407            // kinds of exceptions.
5408            handleAppDiedLocked(app, false, true);
5409            return false;
5410        }
5411
5412        if (!didSomething) {
5413            updateOomAdjLocked();
5414        }
5415
5416        return true;
5417    }
5418
5419    @Override
5420    public final void attachApplication(IApplicationThread thread) {
5421        synchronized (this) {
5422            int callingPid = Binder.getCallingPid();
5423            final long origId = Binder.clearCallingIdentity();
5424            attachApplicationLocked(thread, callingPid);
5425            Binder.restoreCallingIdentity(origId);
5426        }
5427    }
5428
5429    @Override
5430    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5431        final long origId = Binder.clearCallingIdentity();
5432        synchronized (this) {
5433            ActivityStack stack = ActivityRecord.getStackLocked(token);
5434            if (stack != null) {
5435                ActivityRecord r =
5436                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5437                if (stopProfiling) {
5438                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5439                        try {
5440                            mProfileFd.close();
5441                        } catch (IOException e) {
5442                        }
5443                        clearProfilerLocked();
5444                    }
5445                }
5446            }
5447        }
5448        Binder.restoreCallingIdentity(origId);
5449    }
5450
5451    void enableScreenAfterBoot() {
5452        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5453                SystemClock.uptimeMillis());
5454        mWindowManager.enableScreenAfterBoot();
5455
5456        synchronized (this) {
5457            updateEventDispatchingLocked();
5458        }
5459    }
5460
5461    @Override
5462    public void showBootMessage(final CharSequence msg, final boolean always) {
5463        enforceNotIsolatedCaller("showBootMessage");
5464        mWindowManager.showBootMessage(msg, always);
5465    }
5466
5467    @Override
5468    public void dismissKeyguardOnNextActivity() {
5469        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5470        final long token = Binder.clearCallingIdentity();
5471        try {
5472            synchronized (this) {
5473                if (DEBUG_LOCKSCREEN) logLockScreen("");
5474                if (mLockScreenShown) {
5475                    mLockScreenShown = false;
5476                    comeOutOfSleepIfNeededLocked();
5477                }
5478                mStackSupervisor.setDismissKeyguard(true);
5479            }
5480        } finally {
5481            Binder.restoreCallingIdentity(token);
5482        }
5483    }
5484
5485    final void finishBooting() {
5486        // Register receivers to handle package update events
5487        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5488
5489        synchronized (this) {
5490            // Ensure that any processes we had put on hold are now started
5491            // up.
5492            final int NP = mProcessesOnHold.size();
5493            if (NP > 0) {
5494                ArrayList<ProcessRecord> procs =
5495                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5496                for (int ip=0; ip<NP; ip++) {
5497                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5498                            + procs.get(ip));
5499                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5500                }
5501            }
5502
5503            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5504                // Start looking for apps that are abusing wake locks.
5505                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5506                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5507                // Tell anyone interested that we are done booting!
5508                SystemProperties.set("sys.boot_completed", "1");
5509                SystemProperties.set("dev.bootcomplete", "1");
5510                for (int i=0; i<mStartedUsers.size(); i++) {
5511                    UserStartedState uss = mStartedUsers.valueAt(i);
5512                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5513                        uss.mState = UserStartedState.STATE_RUNNING;
5514                        final int userId = mStartedUsers.keyAt(i);
5515                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5516                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5517                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5518                        broadcastIntentLocked(null, null, intent, null,
5519                                new IIntentReceiver.Stub() {
5520                                    @Override
5521                                    public void performReceive(Intent intent, int resultCode,
5522                                            String data, Bundle extras, boolean ordered,
5523                                            boolean sticky, int sendingUser) {
5524                                        synchronized (ActivityManagerService.this) {
5525                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5526                                                    true, false);
5527                                        }
5528                                    }
5529                                },
5530                                0, null, null,
5531                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5532                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5533                                userId);
5534                    }
5535                }
5536                scheduleStartProfilesLocked();
5537            }
5538        }
5539    }
5540
5541    final void ensureBootCompleted() {
5542        boolean booting;
5543        boolean enableScreen;
5544        synchronized (this) {
5545            booting = mBooting;
5546            mBooting = false;
5547            enableScreen = !mBooted;
5548            mBooted = true;
5549        }
5550
5551        if (booting) {
5552            finishBooting();
5553        }
5554
5555        if (enableScreen) {
5556            enableScreenAfterBoot();
5557        }
5558    }
5559
5560    @Override
5561    public final void activityResumed(IBinder token) {
5562        final long origId = Binder.clearCallingIdentity();
5563        synchronized(this) {
5564            ActivityStack stack = ActivityRecord.getStackLocked(token);
5565            if (stack != null) {
5566                ActivityRecord.activityResumedLocked(token);
5567            }
5568        }
5569        Binder.restoreCallingIdentity(origId);
5570    }
5571
5572    @Override
5573    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5574        final long origId = Binder.clearCallingIdentity();
5575        synchronized(this) {
5576            ActivityStack stack = ActivityRecord.getStackLocked(token);
5577            if (stack != null) {
5578                stack.activityPausedLocked(token, false, persistentState);
5579            }
5580        }
5581        Binder.restoreCallingIdentity(origId);
5582    }
5583
5584    @Override
5585    public final void activityStopped(IBinder token, Bundle icicle,
5586            PersistableBundle persistentState, CharSequence description) {
5587        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5588
5589        // Refuse possible leaked file descriptors
5590        if (icicle != null && icicle.hasFileDescriptors()) {
5591            throw new IllegalArgumentException("File descriptors passed in Bundle");
5592        }
5593
5594        final long origId = Binder.clearCallingIdentity();
5595
5596        synchronized (this) {
5597            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5598            if (r != null) {
5599                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5600            }
5601        }
5602
5603        trimApplications();
5604
5605        Binder.restoreCallingIdentity(origId);
5606    }
5607
5608    @Override
5609    public final void activityDestroyed(IBinder token) {
5610        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5611        synchronized (this) {
5612            ActivityStack stack = ActivityRecord.getStackLocked(token);
5613            if (stack != null) {
5614                stack.activityDestroyedLocked(token);
5615            }
5616        }
5617    }
5618
5619    @Override
5620    public final void mediaResourcesReleased(IBinder token) {
5621        final long origId = Binder.clearCallingIdentity();
5622        try {
5623            synchronized (this) {
5624                ActivityStack stack = ActivityRecord.getStackLocked(token);
5625                if (stack != null) {
5626                    stack.mediaResourcesReleased(token);
5627                }
5628            }
5629        } finally {
5630            Binder.restoreCallingIdentity(origId);
5631        }
5632    }
5633
5634    @Override
5635    public String getCallingPackage(IBinder token) {
5636        synchronized (this) {
5637            ActivityRecord r = getCallingRecordLocked(token);
5638            return r != null ? r.info.packageName : null;
5639        }
5640    }
5641
5642    @Override
5643    public ComponentName getCallingActivity(IBinder token) {
5644        synchronized (this) {
5645            ActivityRecord r = getCallingRecordLocked(token);
5646            return r != null ? r.intent.getComponent() : null;
5647        }
5648    }
5649
5650    private ActivityRecord getCallingRecordLocked(IBinder token) {
5651        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5652        if (r == null) {
5653            return null;
5654        }
5655        return r.resultTo;
5656    }
5657
5658    @Override
5659    public ComponentName getActivityClassForToken(IBinder token) {
5660        synchronized(this) {
5661            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5662            if (r == null) {
5663                return null;
5664            }
5665            return r.intent.getComponent();
5666        }
5667    }
5668
5669    @Override
5670    public String getPackageForToken(IBinder token) {
5671        synchronized(this) {
5672            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5673            if (r == null) {
5674                return null;
5675            }
5676            return r.packageName;
5677        }
5678    }
5679
5680    @Override
5681    public IIntentSender getIntentSender(int type,
5682            String packageName, IBinder token, String resultWho,
5683            int requestCode, Intent[] intents, String[] resolvedTypes,
5684            int flags, Bundle options, int userId) {
5685        enforceNotIsolatedCaller("getIntentSender");
5686        // Refuse possible leaked file descriptors
5687        if (intents != null) {
5688            if (intents.length < 1) {
5689                throw new IllegalArgumentException("Intents array length must be >= 1");
5690            }
5691            for (int i=0; i<intents.length; i++) {
5692                Intent intent = intents[i];
5693                if (intent != null) {
5694                    if (intent.hasFileDescriptors()) {
5695                        throw new IllegalArgumentException("File descriptors passed in Intent");
5696                    }
5697                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5698                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5699                        throw new IllegalArgumentException(
5700                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5701                    }
5702                    intents[i] = new Intent(intent);
5703                }
5704            }
5705            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5706                throw new IllegalArgumentException(
5707                        "Intent array length does not match resolvedTypes length");
5708            }
5709        }
5710        if (options != null) {
5711            if (options.hasFileDescriptors()) {
5712                throw new IllegalArgumentException("File descriptors passed in options");
5713            }
5714        }
5715
5716        synchronized(this) {
5717            int callingUid = Binder.getCallingUid();
5718            int origUserId = userId;
5719            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5720                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5721                    ALLOW_NON_FULL, "getIntentSender", null);
5722            if (origUserId == UserHandle.USER_CURRENT) {
5723                // We don't want to evaluate this until the pending intent is
5724                // actually executed.  However, we do want to always do the
5725                // security checking for it above.
5726                userId = UserHandle.USER_CURRENT;
5727            }
5728            try {
5729                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5730                    int uid = AppGlobals.getPackageManager()
5731                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5732                    if (!UserHandle.isSameApp(callingUid, uid)) {
5733                        String msg = "Permission Denial: getIntentSender() from pid="
5734                            + Binder.getCallingPid()
5735                            + ", uid=" + Binder.getCallingUid()
5736                            + ", (need uid=" + uid + ")"
5737                            + " is not allowed to send as package " + packageName;
5738                        Slog.w(TAG, msg);
5739                        throw new SecurityException(msg);
5740                    }
5741                }
5742
5743                return getIntentSenderLocked(type, packageName, callingUid, userId,
5744                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5745
5746            } catch (RemoteException e) {
5747                throw new SecurityException(e);
5748            }
5749        }
5750    }
5751
5752    IIntentSender getIntentSenderLocked(int type, String packageName,
5753            int callingUid, int userId, IBinder token, String resultWho,
5754            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5755            Bundle options) {
5756        if (DEBUG_MU)
5757            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5758        ActivityRecord activity = null;
5759        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5760            activity = ActivityRecord.isInStackLocked(token);
5761            if (activity == null) {
5762                return null;
5763            }
5764            if (activity.finishing) {
5765                return null;
5766            }
5767        }
5768
5769        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5770        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5771        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5772        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5773                |PendingIntent.FLAG_UPDATE_CURRENT);
5774
5775        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5776                type, packageName, activity, resultWho,
5777                requestCode, intents, resolvedTypes, flags, options, userId);
5778        WeakReference<PendingIntentRecord> ref;
5779        ref = mIntentSenderRecords.get(key);
5780        PendingIntentRecord rec = ref != null ? ref.get() : null;
5781        if (rec != null) {
5782            if (!cancelCurrent) {
5783                if (updateCurrent) {
5784                    if (rec.key.requestIntent != null) {
5785                        rec.key.requestIntent.replaceExtras(intents != null ?
5786                                intents[intents.length - 1] : null);
5787                    }
5788                    if (intents != null) {
5789                        intents[intents.length-1] = rec.key.requestIntent;
5790                        rec.key.allIntents = intents;
5791                        rec.key.allResolvedTypes = resolvedTypes;
5792                    } else {
5793                        rec.key.allIntents = null;
5794                        rec.key.allResolvedTypes = null;
5795                    }
5796                }
5797                return rec;
5798            }
5799            rec.canceled = true;
5800            mIntentSenderRecords.remove(key);
5801        }
5802        if (noCreate) {
5803            return rec;
5804        }
5805        rec = new PendingIntentRecord(this, key, callingUid);
5806        mIntentSenderRecords.put(key, rec.ref);
5807        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5808            if (activity.pendingResults == null) {
5809                activity.pendingResults
5810                        = new HashSet<WeakReference<PendingIntentRecord>>();
5811            }
5812            activity.pendingResults.add(rec.ref);
5813        }
5814        return rec;
5815    }
5816
5817    @Override
5818    public void cancelIntentSender(IIntentSender sender) {
5819        if (!(sender instanceof PendingIntentRecord)) {
5820            return;
5821        }
5822        synchronized(this) {
5823            PendingIntentRecord rec = (PendingIntentRecord)sender;
5824            try {
5825                int uid = AppGlobals.getPackageManager()
5826                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5827                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5828                    String msg = "Permission Denial: cancelIntentSender() from pid="
5829                        + Binder.getCallingPid()
5830                        + ", uid=" + Binder.getCallingUid()
5831                        + " is not allowed to cancel packges "
5832                        + rec.key.packageName;
5833                    Slog.w(TAG, msg);
5834                    throw new SecurityException(msg);
5835                }
5836            } catch (RemoteException e) {
5837                throw new SecurityException(e);
5838            }
5839            cancelIntentSenderLocked(rec, true);
5840        }
5841    }
5842
5843    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5844        rec.canceled = true;
5845        mIntentSenderRecords.remove(rec.key);
5846        if (cleanActivity && rec.key.activity != null) {
5847            rec.key.activity.pendingResults.remove(rec.ref);
5848        }
5849    }
5850
5851    @Override
5852    public String getPackageForIntentSender(IIntentSender pendingResult) {
5853        if (!(pendingResult instanceof PendingIntentRecord)) {
5854            return null;
5855        }
5856        try {
5857            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5858            return res.key.packageName;
5859        } catch (ClassCastException e) {
5860        }
5861        return null;
5862    }
5863
5864    @Override
5865    public int getUidForIntentSender(IIntentSender sender) {
5866        if (sender instanceof PendingIntentRecord) {
5867            try {
5868                PendingIntentRecord res = (PendingIntentRecord)sender;
5869                return res.uid;
5870            } catch (ClassCastException e) {
5871            }
5872        }
5873        return -1;
5874    }
5875
5876    @Override
5877    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5878        if (!(pendingResult instanceof PendingIntentRecord)) {
5879            return false;
5880        }
5881        try {
5882            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5883            if (res.key.allIntents == null) {
5884                return false;
5885            }
5886            for (int i=0; i<res.key.allIntents.length; i++) {
5887                Intent intent = res.key.allIntents[i];
5888                if (intent.getPackage() != null && intent.getComponent() != null) {
5889                    return false;
5890                }
5891            }
5892            return true;
5893        } catch (ClassCastException e) {
5894        }
5895        return false;
5896    }
5897
5898    @Override
5899    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5900        if (!(pendingResult instanceof PendingIntentRecord)) {
5901            return false;
5902        }
5903        try {
5904            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5905            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5906                return true;
5907            }
5908            return false;
5909        } catch (ClassCastException e) {
5910        }
5911        return false;
5912    }
5913
5914    @Override
5915    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5916        if (!(pendingResult instanceof PendingIntentRecord)) {
5917            return null;
5918        }
5919        try {
5920            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5921            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5922        } catch (ClassCastException e) {
5923        }
5924        return null;
5925    }
5926
5927    @Override
5928    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5929        if (!(pendingResult instanceof PendingIntentRecord)) {
5930            return null;
5931        }
5932        try {
5933            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5934            Intent intent = res.key.requestIntent;
5935            if (intent != null) {
5936                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5937                        || res.lastTagPrefix.equals(prefix))) {
5938                    return res.lastTag;
5939                }
5940                res.lastTagPrefix = prefix;
5941                StringBuilder sb = new StringBuilder(128);
5942                if (prefix != null) {
5943                    sb.append(prefix);
5944                }
5945                if (intent.getAction() != null) {
5946                    sb.append(intent.getAction());
5947                } else if (intent.getComponent() != null) {
5948                    intent.getComponent().appendShortString(sb);
5949                } else {
5950                    sb.append("?");
5951                }
5952                return res.lastTag = sb.toString();
5953            }
5954        } catch (ClassCastException e) {
5955        }
5956        return null;
5957    }
5958
5959    @Override
5960    public void setProcessLimit(int max) {
5961        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5962                "setProcessLimit()");
5963        synchronized (this) {
5964            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5965            mProcessLimitOverride = max;
5966        }
5967        trimApplications();
5968    }
5969
5970    @Override
5971    public int getProcessLimit() {
5972        synchronized (this) {
5973            return mProcessLimitOverride;
5974        }
5975    }
5976
5977    void foregroundTokenDied(ForegroundToken token) {
5978        synchronized (ActivityManagerService.this) {
5979            synchronized (mPidsSelfLocked) {
5980                ForegroundToken cur
5981                    = mForegroundProcesses.get(token.pid);
5982                if (cur != token) {
5983                    return;
5984                }
5985                mForegroundProcesses.remove(token.pid);
5986                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5987                if (pr == null) {
5988                    return;
5989                }
5990                pr.forcingToForeground = null;
5991                updateProcessForegroundLocked(pr, false, false);
5992            }
5993            updateOomAdjLocked();
5994        }
5995    }
5996
5997    @Override
5998    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5999        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6000                "setProcessForeground()");
6001        synchronized(this) {
6002            boolean changed = false;
6003
6004            synchronized (mPidsSelfLocked) {
6005                ProcessRecord pr = mPidsSelfLocked.get(pid);
6006                if (pr == null && isForeground) {
6007                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6008                    return;
6009                }
6010                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6011                if (oldToken != null) {
6012                    oldToken.token.unlinkToDeath(oldToken, 0);
6013                    mForegroundProcesses.remove(pid);
6014                    if (pr != null) {
6015                        pr.forcingToForeground = null;
6016                    }
6017                    changed = true;
6018                }
6019                if (isForeground && token != null) {
6020                    ForegroundToken newToken = new ForegroundToken() {
6021                        @Override
6022                        public void binderDied() {
6023                            foregroundTokenDied(this);
6024                        }
6025                    };
6026                    newToken.pid = pid;
6027                    newToken.token = token;
6028                    try {
6029                        token.linkToDeath(newToken, 0);
6030                        mForegroundProcesses.put(pid, newToken);
6031                        pr.forcingToForeground = token;
6032                        changed = true;
6033                    } catch (RemoteException e) {
6034                        // If the process died while doing this, we will later
6035                        // do the cleanup with the process death link.
6036                    }
6037                }
6038            }
6039
6040            if (changed) {
6041                updateOomAdjLocked();
6042            }
6043        }
6044    }
6045
6046    // =========================================================
6047    // PERMISSIONS
6048    // =========================================================
6049
6050    static class PermissionController extends IPermissionController.Stub {
6051        ActivityManagerService mActivityManagerService;
6052        PermissionController(ActivityManagerService activityManagerService) {
6053            mActivityManagerService = activityManagerService;
6054        }
6055
6056        @Override
6057        public boolean checkPermission(String permission, int pid, int uid) {
6058            return mActivityManagerService.checkPermission(permission, pid,
6059                    uid) == PackageManager.PERMISSION_GRANTED;
6060        }
6061    }
6062
6063    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6064        @Override
6065        public int checkComponentPermission(String permission, int pid, int uid,
6066                int owningUid, boolean exported) {
6067            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6068                    owningUid, exported);
6069        }
6070
6071        @Override
6072        public Object getAMSLock() {
6073            return ActivityManagerService.this;
6074        }
6075    }
6076
6077    /**
6078     * This can be called with or without the global lock held.
6079     */
6080    int checkComponentPermission(String permission, int pid, int uid,
6081            int owningUid, boolean exported) {
6082        // We might be performing an operation on behalf of an indirect binder
6083        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6084        // client identity accordingly before proceeding.
6085        Identity tlsIdentity = sCallerIdentity.get();
6086        if (tlsIdentity != null) {
6087            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6088                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6089            uid = tlsIdentity.uid;
6090            pid = tlsIdentity.pid;
6091        }
6092
6093        if (pid == MY_PID) {
6094            return PackageManager.PERMISSION_GRANTED;
6095        }
6096
6097        return ActivityManager.checkComponentPermission(permission, uid,
6098                owningUid, exported);
6099    }
6100
6101    /**
6102     * As the only public entry point for permissions checking, this method
6103     * can enforce the semantic that requesting a check on a null global
6104     * permission is automatically denied.  (Internally a null permission
6105     * string is used when calling {@link #checkComponentPermission} in cases
6106     * when only uid-based security is needed.)
6107     *
6108     * This can be called with or without the global lock held.
6109     */
6110    @Override
6111    public int checkPermission(String permission, int pid, int uid) {
6112        if (permission == null) {
6113            return PackageManager.PERMISSION_DENIED;
6114        }
6115        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6116    }
6117
6118    /**
6119     * Binder IPC calls go through the public entry point.
6120     * This can be called with or without the global lock held.
6121     */
6122    int checkCallingPermission(String permission) {
6123        return checkPermission(permission,
6124                Binder.getCallingPid(),
6125                UserHandle.getAppId(Binder.getCallingUid()));
6126    }
6127
6128    /**
6129     * This can be called with or without the global lock held.
6130     */
6131    void enforceCallingPermission(String permission, String func) {
6132        if (checkCallingPermission(permission)
6133                == PackageManager.PERMISSION_GRANTED) {
6134            return;
6135        }
6136
6137        String msg = "Permission Denial: " + func + " from pid="
6138                + Binder.getCallingPid()
6139                + ", uid=" + Binder.getCallingUid()
6140                + " requires " + permission;
6141        Slog.w(TAG, msg);
6142        throw new SecurityException(msg);
6143    }
6144
6145    /**
6146     * Determine if UID is holding permissions required to access {@link Uri} in
6147     * the given {@link ProviderInfo}. Final permission checking is always done
6148     * in {@link ContentProvider}.
6149     */
6150    private final boolean checkHoldingPermissionsLocked(
6151            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6152        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6153                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6154        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6155            return false;
6156        }
6157        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6158    }
6159
6160    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6161            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6162        if (pi.applicationInfo.uid == uid) {
6163            return true;
6164        } else if (!pi.exported) {
6165            return false;
6166        }
6167
6168        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6169        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6170        try {
6171            // check if target holds top-level <provider> permissions
6172            if (!readMet && pi.readPermission != null && considerUidPermissions
6173                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6174                readMet = true;
6175            }
6176            if (!writeMet && pi.writePermission != null && considerUidPermissions
6177                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6178                writeMet = true;
6179            }
6180
6181            // track if unprotected read/write is allowed; any denied
6182            // <path-permission> below removes this ability
6183            boolean allowDefaultRead = pi.readPermission == null;
6184            boolean allowDefaultWrite = pi.writePermission == null;
6185
6186            // check if target holds any <path-permission> that match uri
6187            final PathPermission[] pps = pi.pathPermissions;
6188            if (pps != null) {
6189                final String path = grantUri.uri.getPath();
6190                int i = pps.length;
6191                while (i > 0 && (!readMet || !writeMet)) {
6192                    i--;
6193                    PathPermission pp = pps[i];
6194                    if (pp.match(path)) {
6195                        if (!readMet) {
6196                            final String pprperm = pp.getReadPermission();
6197                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6198                                    + pprperm + " for " + pp.getPath()
6199                                    + ": match=" + pp.match(path)
6200                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6201                            if (pprperm != null) {
6202                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6203                                        == PERMISSION_GRANTED) {
6204                                    readMet = true;
6205                                } else {
6206                                    allowDefaultRead = false;
6207                                }
6208                            }
6209                        }
6210                        if (!writeMet) {
6211                            final String ppwperm = pp.getWritePermission();
6212                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6213                                    + ppwperm + " for " + pp.getPath()
6214                                    + ": match=" + pp.match(path)
6215                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6216                            if (ppwperm != null) {
6217                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6218                                        == PERMISSION_GRANTED) {
6219                                    writeMet = true;
6220                                } else {
6221                                    allowDefaultWrite = false;
6222                                }
6223                            }
6224                        }
6225                    }
6226                }
6227            }
6228
6229            // grant unprotected <provider> read/write, if not blocked by
6230            // <path-permission> above
6231            if (allowDefaultRead) readMet = true;
6232            if (allowDefaultWrite) writeMet = true;
6233
6234        } catch (RemoteException e) {
6235            return false;
6236        }
6237
6238        return readMet && writeMet;
6239    }
6240
6241    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6242        ProviderInfo pi = null;
6243        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6244        if (cpr != null) {
6245            pi = cpr.info;
6246        } else {
6247            try {
6248                pi = AppGlobals.getPackageManager().resolveContentProvider(
6249                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6250            } catch (RemoteException ex) {
6251            }
6252        }
6253        return pi;
6254    }
6255
6256    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6257        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6258        if (targetUris != null) {
6259            return targetUris.get(grantUri);
6260        }
6261        return null;
6262    }
6263
6264    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6265            String targetPkg, int targetUid, GrantUri grantUri) {
6266        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6267        if (targetUris == null) {
6268            targetUris = Maps.newArrayMap();
6269            mGrantedUriPermissions.put(targetUid, targetUris);
6270        }
6271
6272        UriPermission perm = targetUris.get(grantUri);
6273        if (perm == null) {
6274            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6275            targetUris.put(grantUri, perm);
6276        }
6277
6278        return perm;
6279    }
6280
6281    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6282            final int modeFlags) {
6283        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6284        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6285                : UriPermission.STRENGTH_OWNED;
6286
6287        // Root gets to do everything.
6288        if (uid == 0) {
6289            return true;
6290        }
6291
6292        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6293        if (perms == null) return false;
6294
6295        // First look for exact match
6296        final UriPermission exactPerm = perms.get(grantUri);
6297        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6298            return true;
6299        }
6300
6301        // No exact match, look for prefixes
6302        final int N = perms.size();
6303        for (int i = 0; i < N; i++) {
6304            final UriPermission perm = perms.valueAt(i);
6305            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6306                    && perm.getStrength(modeFlags) >= minStrength) {
6307                return true;
6308            }
6309        }
6310
6311        return false;
6312    }
6313
6314    @Override
6315    public int checkUriPermission(Uri uri, int pid, int uid,
6316            final int modeFlags, int userId) {
6317        enforceNotIsolatedCaller("checkUriPermission");
6318
6319        // Another redirected-binder-call permissions check as in
6320        // {@link checkComponentPermission}.
6321        Identity tlsIdentity = sCallerIdentity.get();
6322        if (tlsIdentity != null) {
6323            uid = tlsIdentity.uid;
6324            pid = tlsIdentity.pid;
6325        }
6326
6327        // Our own process gets to do everything.
6328        if (pid == MY_PID) {
6329            return PackageManager.PERMISSION_GRANTED;
6330        }
6331        synchronized (this) {
6332            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6333                    ? PackageManager.PERMISSION_GRANTED
6334                    : PackageManager.PERMISSION_DENIED;
6335        }
6336    }
6337
6338    /**
6339     * Check if the targetPkg can be granted permission to access uri by
6340     * the callingUid using the given modeFlags.  Throws a security exception
6341     * if callingUid is not allowed to do this.  Returns the uid of the target
6342     * if the URI permission grant should be performed; returns -1 if it is not
6343     * needed (for example targetPkg already has permission to access the URI).
6344     * If you already know the uid of the target, you can supply it in
6345     * lastTargetUid else set that to -1.
6346     */
6347    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6348            final int modeFlags, int lastTargetUid) {
6349        if (!Intent.isAccessUriMode(modeFlags)) {
6350            return -1;
6351        }
6352
6353        if (targetPkg != null) {
6354            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6355                    "Checking grant " + targetPkg + " permission to " + grantUri);
6356        }
6357
6358        final IPackageManager pm = AppGlobals.getPackageManager();
6359
6360        // If this is not a content: uri, we can't do anything with it.
6361        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6362            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6363                    "Can't grant URI permission for non-content URI: " + grantUri);
6364            return -1;
6365        }
6366
6367        final String authority = grantUri.uri.getAuthority();
6368        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6369        if (pi == null) {
6370            Slog.w(TAG, "No content provider found for permission check: " +
6371                    grantUri.uri.toSafeString());
6372            return -1;
6373        }
6374
6375        int targetUid = lastTargetUid;
6376        if (targetUid < 0 && targetPkg != null) {
6377            try {
6378                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6379                if (targetUid < 0) {
6380                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6381                            "Can't grant URI permission no uid for: " + targetPkg);
6382                    return -1;
6383                }
6384            } catch (RemoteException ex) {
6385                return -1;
6386            }
6387        }
6388
6389        if (targetUid >= 0) {
6390            // First...  does the target actually need this permission?
6391            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6392                // No need to grant the target this permission.
6393                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6394                        "Target " + targetPkg + " already has full permission to " + grantUri);
6395                return -1;
6396            }
6397        } else {
6398            // First...  there is no target package, so can anyone access it?
6399            boolean allowed = pi.exported;
6400            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6401                if (pi.readPermission != null) {
6402                    allowed = false;
6403                }
6404            }
6405            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6406                if (pi.writePermission != null) {
6407                    allowed = false;
6408                }
6409            }
6410            if (allowed) {
6411                return -1;
6412            }
6413        }
6414
6415        /* There is a special cross user grant if:
6416         * - The target is on another user.
6417         * - Apps on the current user can access the uri without any uid permissions.
6418         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6419         * grant uri permissions.
6420         */
6421        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6422                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6423                modeFlags, false /*without considering the uid permissions*/);
6424
6425        // Second...  is the provider allowing granting of URI permissions?
6426        if (!specialCrossUserGrant) {
6427            if (!pi.grantUriPermissions) {
6428                throw new SecurityException("Provider " + pi.packageName
6429                        + "/" + pi.name
6430                        + " does not allow granting of Uri permissions (uri "
6431                        + grantUri + ")");
6432            }
6433            if (pi.uriPermissionPatterns != null) {
6434                final int N = pi.uriPermissionPatterns.length;
6435                boolean allowed = false;
6436                for (int i=0; i<N; i++) {
6437                    if (pi.uriPermissionPatterns[i] != null
6438                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6439                        allowed = true;
6440                        break;
6441                    }
6442                }
6443                if (!allowed) {
6444                    throw new SecurityException("Provider " + pi.packageName
6445                            + "/" + pi.name
6446                            + " does not allow granting of permission to path of Uri "
6447                            + grantUri);
6448                }
6449            }
6450        }
6451
6452        // Third...  does the caller itself have permission to access
6453        // this uri?
6454        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6455            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6456                // Require they hold a strong enough Uri permission
6457                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6458                    throw new SecurityException("Uid " + callingUid
6459                            + " does not have permission to uri " + grantUri);
6460                }
6461            }
6462        }
6463        return targetUid;
6464    }
6465
6466    @Override
6467    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6468            final int modeFlags, int userId) {
6469        enforceNotIsolatedCaller("checkGrantUriPermission");
6470        synchronized(this) {
6471            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6472                    new GrantUri(userId, uri, false), modeFlags, -1);
6473        }
6474    }
6475
6476    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6477            final int modeFlags, UriPermissionOwner owner) {
6478        if (!Intent.isAccessUriMode(modeFlags)) {
6479            return;
6480        }
6481
6482        // So here we are: the caller has the assumed permission
6483        // to the uri, and the target doesn't.  Let's now give this to
6484        // the target.
6485
6486        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6487                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6488
6489        final String authority = grantUri.uri.getAuthority();
6490        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6491        if (pi == null) {
6492            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6493            return;
6494        }
6495
6496        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6497            grantUri.prefix = true;
6498        }
6499        final UriPermission perm = findOrCreateUriPermissionLocked(
6500                pi.packageName, targetPkg, targetUid, grantUri);
6501        perm.grantModes(modeFlags, owner);
6502    }
6503
6504    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6505            final int modeFlags, UriPermissionOwner owner) {
6506        if (targetPkg == null) {
6507            throw new NullPointerException("targetPkg");
6508        }
6509
6510        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6511                -1);
6512        if (targetUid < 0) {
6513            return;
6514        }
6515
6516        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6517                owner);
6518    }
6519
6520    static class NeededUriGrants extends ArrayList<GrantUri> {
6521        final String targetPkg;
6522        final int targetUid;
6523        final int flags;
6524
6525        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6526            this.targetPkg = targetPkg;
6527            this.targetUid = targetUid;
6528            this.flags = flags;
6529        }
6530    }
6531
6532    /**
6533     * Like checkGrantUriPermissionLocked, but takes an Intent.
6534     */
6535    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6536            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6537        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6538                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6539                + " clip=" + (intent != null ? intent.getClipData() : null)
6540                + " from " + intent + "; flags=0x"
6541                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6542
6543        if (targetPkg == null) {
6544            throw new NullPointerException("targetPkg");
6545        }
6546
6547        if (intent == null) {
6548            return null;
6549        }
6550        Uri data = intent.getData();
6551        ClipData clip = intent.getClipData();
6552        if (data == null && clip == null) {
6553            return null;
6554        }
6555        final IPackageManager pm = AppGlobals.getPackageManager();
6556        int targetUid;
6557        if (needed != null) {
6558            targetUid = needed.targetUid;
6559        } else {
6560            try {
6561                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6562            } catch (RemoteException ex) {
6563                return null;
6564            }
6565            if (targetUid < 0) {
6566                if (DEBUG_URI_PERMISSION) {
6567                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6568                            + " on user " + targetUserId);
6569                }
6570                return null;
6571            }
6572        }
6573        if (data != null) {
6574            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6575            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6576                    targetUid);
6577            if (targetUid > 0) {
6578                if (needed == null) {
6579                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6580                }
6581                needed.add(grantUri);
6582            }
6583        }
6584        if (clip != null) {
6585            for (int i=0; i<clip.getItemCount(); i++) {
6586                Uri uri = clip.getItemAt(i).getUri();
6587                if (uri != null) {
6588                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6589                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6590                            targetUid);
6591                    if (targetUid > 0) {
6592                        if (needed == null) {
6593                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6594                        }
6595                        needed.add(grantUri);
6596                    }
6597                } else {
6598                    Intent clipIntent = clip.getItemAt(i).getIntent();
6599                    if (clipIntent != null) {
6600                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6601                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6602                        if (newNeeded != null) {
6603                            needed = newNeeded;
6604                        }
6605                    }
6606                }
6607            }
6608        }
6609
6610        return needed;
6611    }
6612
6613    /**
6614     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6615     */
6616    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6617            UriPermissionOwner owner) {
6618        if (needed != null) {
6619            for (int i=0; i<needed.size(); i++) {
6620                GrantUri grantUri = needed.get(i);
6621                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6622                        grantUri, needed.flags, owner);
6623            }
6624        }
6625    }
6626
6627    void grantUriPermissionFromIntentLocked(int callingUid,
6628            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6629        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6630                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6631        if (needed == null) {
6632            return;
6633        }
6634
6635        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6636    }
6637
6638    @Override
6639    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6640            final int modeFlags, int userId) {
6641        enforceNotIsolatedCaller("grantUriPermission");
6642        GrantUri grantUri = new GrantUri(userId, uri, false);
6643        synchronized(this) {
6644            final ProcessRecord r = getRecordForAppLocked(caller);
6645            if (r == null) {
6646                throw new SecurityException("Unable to find app for caller "
6647                        + caller
6648                        + " when granting permission to uri " + grantUri);
6649            }
6650            if (targetPkg == null) {
6651                throw new IllegalArgumentException("null target");
6652            }
6653            if (grantUri == null) {
6654                throw new IllegalArgumentException("null uri");
6655            }
6656
6657            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6658                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6659                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6660                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6661
6662            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6663        }
6664    }
6665
6666    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6667        if (perm.modeFlags == 0) {
6668            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6669                    perm.targetUid);
6670            if (perms != null) {
6671                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6672                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6673
6674                perms.remove(perm.uri);
6675                if (perms.isEmpty()) {
6676                    mGrantedUriPermissions.remove(perm.targetUid);
6677                }
6678            }
6679        }
6680    }
6681
6682    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6683        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6684
6685        final IPackageManager pm = AppGlobals.getPackageManager();
6686        final String authority = grantUri.uri.getAuthority();
6687        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6688        if (pi == null) {
6689            Slog.w(TAG, "No content provider found for permission revoke: "
6690                    + grantUri.toSafeString());
6691            return;
6692        }
6693
6694        // Does the caller have this permission on the URI?
6695        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6696            // Right now, if you are not the original owner of the permission,
6697            // you are not allowed to revoke it.
6698            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6699                throw new SecurityException("Uid " + callingUid
6700                        + " does not have permission to uri " + grantUri);
6701            //}
6702        }
6703
6704        boolean persistChanged = false;
6705
6706        // Go through all of the permissions and remove any that match.
6707        int N = mGrantedUriPermissions.size();
6708        for (int i = 0; i < N; i++) {
6709            final int targetUid = mGrantedUriPermissions.keyAt(i);
6710            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6711
6712            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6713                final UriPermission perm = it.next();
6714                if (perm.uri.sourceUserId == grantUri.sourceUserId
6715                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6716                    if (DEBUG_URI_PERMISSION)
6717                        Slog.v(TAG,
6718                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6719                    persistChanged |= perm.revokeModes(
6720                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6721                    if (perm.modeFlags == 0) {
6722                        it.remove();
6723                    }
6724                }
6725            }
6726
6727            if (perms.isEmpty()) {
6728                mGrantedUriPermissions.remove(targetUid);
6729                N--;
6730                i--;
6731            }
6732        }
6733
6734        if (persistChanged) {
6735            schedulePersistUriGrants();
6736        }
6737    }
6738
6739    @Override
6740    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6741            int userId) {
6742        enforceNotIsolatedCaller("revokeUriPermission");
6743        synchronized(this) {
6744            final ProcessRecord r = getRecordForAppLocked(caller);
6745            if (r == null) {
6746                throw new SecurityException("Unable to find app for caller "
6747                        + caller
6748                        + " when revoking permission to uri " + uri);
6749            }
6750            if (uri == null) {
6751                Slog.w(TAG, "revokeUriPermission: null uri");
6752                return;
6753            }
6754
6755            if (!Intent.isAccessUriMode(modeFlags)) {
6756                return;
6757            }
6758
6759            final IPackageManager pm = AppGlobals.getPackageManager();
6760            final String authority = uri.getAuthority();
6761            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6762            if (pi == null) {
6763                Slog.w(TAG, "No content provider found for permission revoke: "
6764                        + uri.toSafeString());
6765                return;
6766            }
6767
6768            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6769        }
6770    }
6771
6772    /**
6773     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6774     * given package.
6775     *
6776     * @param packageName Package name to match, or {@code null} to apply to all
6777     *            packages.
6778     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6779     *            to all users.
6780     * @param persistable If persistable grants should be removed.
6781     */
6782    private void removeUriPermissionsForPackageLocked(
6783            String packageName, int userHandle, boolean persistable) {
6784        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6785            throw new IllegalArgumentException("Must narrow by either package or user");
6786        }
6787
6788        boolean persistChanged = false;
6789
6790        int N = mGrantedUriPermissions.size();
6791        for (int i = 0; i < N; i++) {
6792            final int targetUid = mGrantedUriPermissions.keyAt(i);
6793            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6794
6795            // Only inspect grants matching user
6796            if (userHandle == UserHandle.USER_ALL
6797                    || userHandle == UserHandle.getUserId(targetUid)) {
6798                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6799                    final UriPermission perm = it.next();
6800
6801                    // Only inspect grants matching package
6802                    if (packageName == null || perm.sourcePkg.equals(packageName)
6803                            || perm.targetPkg.equals(packageName)) {
6804                        persistChanged |= perm.revokeModes(
6805                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6806
6807                        // Only remove when no modes remain; any persisted grants
6808                        // will keep this alive.
6809                        if (perm.modeFlags == 0) {
6810                            it.remove();
6811                        }
6812                    }
6813                }
6814
6815                if (perms.isEmpty()) {
6816                    mGrantedUriPermissions.remove(targetUid);
6817                    N--;
6818                    i--;
6819                }
6820            }
6821        }
6822
6823        if (persistChanged) {
6824            schedulePersistUriGrants();
6825        }
6826    }
6827
6828    @Override
6829    public IBinder newUriPermissionOwner(String name) {
6830        enforceNotIsolatedCaller("newUriPermissionOwner");
6831        synchronized(this) {
6832            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6833            return owner.getExternalTokenLocked();
6834        }
6835    }
6836
6837    @Override
6838    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6839            final int modeFlags, int userId) {
6840        synchronized(this) {
6841            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6842            if (owner == null) {
6843                throw new IllegalArgumentException("Unknown owner: " + token);
6844            }
6845            if (fromUid != Binder.getCallingUid()) {
6846                if (Binder.getCallingUid() != Process.myUid()) {
6847                    // Only system code can grant URI permissions on behalf
6848                    // of other users.
6849                    throw new SecurityException("nice try");
6850                }
6851            }
6852            if (targetPkg == null) {
6853                throw new IllegalArgumentException("null target");
6854            }
6855            if (uri == null) {
6856                throw new IllegalArgumentException("null uri");
6857            }
6858
6859            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6860                    modeFlags, owner);
6861        }
6862    }
6863
6864    @Override
6865    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6866        synchronized(this) {
6867            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6868            if (owner == null) {
6869                throw new IllegalArgumentException("Unknown owner: " + token);
6870            }
6871
6872            if (uri == null) {
6873                owner.removeUriPermissionsLocked(mode);
6874            } else {
6875                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6876            }
6877        }
6878    }
6879
6880    private void schedulePersistUriGrants() {
6881        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6882            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6883                    10 * DateUtils.SECOND_IN_MILLIS);
6884        }
6885    }
6886
6887    private void writeGrantedUriPermissions() {
6888        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6889
6890        // Snapshot permissions so we can persist without lock
6891        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6892        synchronized (this) {
6893            final int size = mGrantedUriPermissions.size();
6894            for (int i = 0; i < size; i++) {
6895                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6896                for (UriPermission perm : perms.values()) {
6897                    if (perm.persistedModeFlags != 0) {
6898                        persist.add(perm.snapshot());
6899                    }
6900                }
6901            }
6902        }
6903
6904        FileOutputStream fos = null;
6905        try {
6906            fos = mGrantFile.startWrite();
6907
6908            XmlSerializer out = new FastXmlSerializer();
6909            out.setOutput(fos, "utf-8");
6910            out.startDocument(null, true);
6911            out.startTag(null, TAG_URI_GRANTS);
6912            for (UriPermission.Snapshot perm : persist) {
6913                out.startTag(null, TAG_URI_GRANT);
6914                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6915                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6916                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6917                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6918                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6919                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6920                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6921                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6922                out.endTag(null, TAG_URI_GRANT);
6923            }
6924            out.endTag(null, TAG_URI_GRANTS);
6925            out.endDocument();
6926
6927            mGrantFile.finishWrite(fos);
6928        } catch (IOException e) {
6929            if (fos != null) {
6930                mGrantFile.failWrite(fos);
6931            }
6932        }
6933    }
6934
6935    private void readGrantedUriPermissionsLocked() {
6936        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6937
6938        final long now = System.currentTimeMillis();
6939
6940        FileInputStream fis = null;
6941        try {
6942            fis = mGrantFile.openRead();
6943            final XmlPullParser in = Xml.newPullParser();
6944            in.setInput(fis, null);
6945
6946            int type;
6947            while ((type = in.next()) != END_DOCUMENT) {
6948                final String tag = in.getName();
6949                if (type == START_TAG) {
6950                    if (TAG_URI_GRANT.equals(tag)) {
6951                        final int sourceUserId;
6952                        final int targetUserId;
6953                        final int userHandle = readIntAttribute(in,
6954                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6955                        if (userHandle != UserHandle.USER_NULL) {
6956                            // For backwards compatibility.
6957                            sourceUserId = userHandle;
6958                            targetUserId = userHandle;
6959                        } else {
6960                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6961                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6962                        }
6963                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6964                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6965                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6966                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6967                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6968                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6969
6970                        // Sanity check that provider still belongs to source package
6971                        final ProviderInfo pi = getProviderInfoLocked(
6972                                uri.getAuthority(), sourceUserId);
6973                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6974                            int targetUid = -1;
6975                            try {
6976                                targetUid = AppGlobals.getPackageManager()
6977                                        .getPackageUid(targetPkg, targetUserId);
6978                            } catch (RemoteException e) {
6979                            }
6980                            if (targetUid != -1) {
6981                                final UriPermission perm = findOrCreateUriPermissionLocked(
6982                                        sourcePkg, targetPkg, targetUid,
6983                                        new GrantUri(sourceUserId, uri, prefix));
6984                                perm.initPersistedModes(modeFlags, createdTime);
6985                            }
6986                        } else {
6987                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6988                                    + " but instead found " + pi);
6989                        }
6990                    }
6991                }
6992            }
6993        } catch (FileNotFoundException e) {
6994            // Missing grants is okay
6995        } catch (IOException e) {
6996            Log.wtf(TAG, "Failed reading Uri grants", e);
6997        } catch (XmlPullParserException e) {
6998            Log.wtf(TAG, "Failed reading Uri grants", e);
6999        } finally {
7000            IoUtils.closeQuietly(fis);
7001        }
7002    }
7003
7004    @Override
7005    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7006        enforceNotIsolatedCaller("takePersistableUriPermission");
7007
7008        Preconditions.checkFlagsArgument(modeFlags,
7009                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7010
7011        synchronized (this) {
7012            final int callingUid = Binder.getCallingUid();
7013            boolean persistChanged = false;
7014            GrantUri grantUri = new GrantUri(userId, uri, false);
7015
7016            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7017                    new GrantUri(userId, uri, false));
7018            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7019                    new GrantUri(userId, uri, true));
7020
7021            final boolean exactValid = (exactPerm != null)
7022                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7023            final boolean prefixValid = (prefixPerm != null)
7024                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7025
7026            if (!(exactValid || prefixValid)) {
7027                throw new SecurityException("No persistable permission grants found for UID "
7028                        + callingUid + " and Uri " + grantUri.toSafeString());
7029            }
7030
7031            if (exactValid) {
7032                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7033            }
7034            if (prefixValid) {
7035                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7036            }
7037
7038            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7039
7040            if (persistChanged) {
7041                schedulePersistUriGrants();
7042            }
7043        }
7044    }
7045
7046    @Override
7047    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7048        enforceNotIsolatedCaller("releasePersistableUriPermission");
7049
7050        Preconditions.checkFlagsArgument(modeFlags,
7051                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7052
7053        synchronized (this) {
7054            final int callingUid = Binder.getCallingUid();
7055            boolean persistChanged = false;
7056
7057            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7058                    new GrantUri(userId, uri, false));
7059            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7060                    new GrantUri(userId, uri, true));
7061            if (exactPerm == null && prefixPerm == null) {
7062                throw new SecurityException("No permission grants found for UID " + callingUid
7063                        + " and Uri " + uri.toSafeString());
7064            }
7065
7066            if (exactPerm != null) {
7067                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7068                removeUriPermissionIfNeededLocked(exactPerm);
7069            }
7070            if (prefixPerm != null) {
7071                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7072                removeUriPermissionIfNeededLocked(prefixPerm);
7073            }
7074
7075            if (persistChanged) {
7076                schedulePersistUriGrants();
7077            }
7078        }
7079    }
7080
7081    /**
7082     * Prune any older {@link UriPermission} for the given UID until outstanding
7083     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7084     *
7085     * @return if any mutations occured that require persisting.
7086     */
7087    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7088        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7089        if (perms == null) return false;
7090        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7091
7092        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7093        for (UriPermission perm : perms.values()) {
7094            if (perm.persistedModeFlags != 0) {
7095                persisted.add(perm);
7096            }
7097        }
7098
7099        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7100        if (trimCount <= 0) return false;
7101
7102        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7103        for (int i = 0; i < trimCount; i++) {
7104            final UriPermission perm = persisted.get(i);
7105
7106            if (DEBUG_URI_PERMISSION) {
7107                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7108            }
7109
7110            perm.releasePersistableModes(~0);
7111            removeUriPermissionIfNeededLocked(perm);
7112        }
7113
7114        return true;
7115    }
7116
7117    @Override
7118    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7119            String packageName, boolean incoming) {
7120        enforceNotIsolatedCaller("getPersistedUriPermissions");
7121        Preconditions.checkNotNull(packageName, "packageName");
7122
7123        final int callingUid = Binder.getCallingUid();
7124        final IPackageManager pm = AppGlobals.getPackageManager();
7125        try {
7126            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7127            if (packageUid != callingUid) {
7128                throw new SecurityException(
7129                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7130            }
7131        } catch (RemoteException e) {
7132            throw new SecurityException("Failed to verify package name ownership");
7133        }
7134
7135        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7136        synchronized (this) {
7137            if (incoming) {
7138                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7139                        callingUid);
7140                if (perms == null) {
7141                    Slog.w(TAG, "No permission grants found for " + packageName);
7142                } else {
7143                    for (UriPermission perm : perms.values()) {
7144                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7145                            result.add(perm.buildPersistedPublicApiObject());
7146                        }
7147                    }
7148                }
7149            } else {
7150                final int size = mGrantedUriPermissions.size();
7151                for (int i = 0; i < size; i++) {
7152                    final ArrayMap<GrantUri, UriPermission> perms =
7153                            mGrantedUriPermissions.valueAt(i);
7154                    for (UriPermission perm : perms.values()) {
7155                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7156                            result.add(perm.buildPersistedPublicApiObject());
7157                        }
7158                    }
7159                }
7160            }
7161        }
7162        return new ParceledListSlice<android.content.UriPermission>(result);
7163    }
7164
7165    @Override
7166    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7167        synchronized (this) {
7168            ProcessRecord app =
7169                who != null ? getRecordForAppLocked(who) : null;
7170            if (app == null) return;
7171
7172            Message msg = Message.obtain();
7173            msg.what = WAIT_FOR_DEBUGGER_MSG;
7174            msg.obj = app;
7175            msg.arg1 = waiting ? 1 : 0;
7176            mHandler.sendMessage(msg);
7177        }
7178    }
7179
7180    @Override
7181    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7182        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7183        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7184        outInfo.availMem = Process.getFreeMemory();
7185        outInfo.totalMem = Process.getTotalMemory();
7186        outInfo.threshold = homeAppMem;
7187        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7188        outInfo.hiddenAppThreshold = cachedAppMem;
7189        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7190                ProcessList.SERVICE_ADJ);
7191        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7192                ProcessList.VISIBLE_APP_ADJ);
7193        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7194                ProcessList.FOREGROUND_APP_ADJ);
7195    }
7196
7197    // =========================================================
7198    // TASK MANAGEMENT
7199    // =========================================================
7200
7201    @Override
7202    public List<IAppTask> getAppTasks() {
7203        final PackageManager pm = mContext.getPackageManager();
7204        int callingUid = Binder.getCallingUid();
7205        long ident = Binder.clearCallingIdentity();
7206
7207        // Compose the list of packages for this id to test against
7208        HashSet<String> packages = new HashSet<String>();
7209        String[] uidPackages = pm.getPackagesForUid(callingUid);
7210        for (int i = 0; i < uidPackages.length; i++) {
7211            packages.add(uidPackages[i]);
7212        }
7213
7214        synchronized(this) {
7215            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7216            try {
7217                if (localLOGV) Slog.v(TAG, "getAppTasks");
7218
7219                final int N = mRecentTasks.size();
7220                for (int i = 0; i < N; i++) {
7221                    TaskRecord tr = mRecentTasks.get(i);
7222                    // Skip tasks that are not created by the caller
7223                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7224                        ActivityManager.RecentTaskInfo taskInfo =
7225                                createRecentTaskInfoFromTaskRecord(tr);
7226                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7227                        list.add(taskImpl);
7228                    }
7229                }
7230            } finally {
7231                Binder.restoreCallingIdentity(ident);
7232            }
7233            return list;
7234        }
7235    }
7236
7237    @Override
7238    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7239        final int callingUid = Binder.getCallingUid();
7240        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7241
7242        synchronized(this) {
7243            if (localLOGV) Slog.v(
7244                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7245
7246            final boolean allowed = checkCallingPermission(
7247                    android.Manifest.permission.GET_TASKS)
7248                    == PackageManager.PERMISSION_GRANTED;
7249            if (!allowed) {
7250                Slog.w(TAG, "getTasks: caller " + callingUid
7251                        + " does not hold GET_TASKS; limiting output");
7252            }
7253
7254            // TODO: Improve with MRU list from all ActivityStacks.
7255            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7256        }
7257
7258        return list;
7259    }
7260
7261    TaskRecord getMostRecentTask() {
7262        return mRecentTasks.get(0);
7263    }
7264
7265    /**
7266     * Creates a new RecentTaskInfo from a TaskRecord.
7267     */
7268    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7269        // Update the task description to reflect any changes in the task stack
7270        tr.updateTaskDescription();
7271
7272        // Compose the recent task info
7273        ActivityManager.RecentTaskInfo rti
7274                = new ActivityManager.RecentTaskInfo();
7275        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7276        rti.persistentId = tr.taskId;
7277        rti.baseIntent = new Intent(tr.getBaseIntent());
7278        rti.origActivity = tr.origActivity;
7279        rti.description = tr.lastDescription;
7280        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7281        rti.userId = tr.userId;
7282        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7283        rti.firstActiveTime = tr.firstActiveTime;
7284        rti.lastActiveTime = tr.lastActiveTime;
7285        return rti;
7286    }
7287
7288    @Override
7289    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7290            int flags, int userId) {
7291        final int callingUid = Binder.getCallingUid();
7292        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7293                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7294
7295        synchronized (this) {
7296            final boolean allowed = checkCallingPermission(
7297                    android.Manifest.permission.GET_TASKS)
7298                    == PackageManager.PERMISSION_GRANTED;
7299            if (!allowed) {
7300                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7301                        + " does not hold GET_TASKS; limiting output");
7302            }
7303            final boolean detailed = checkCallingPermission(
7304                    android.Manifest.permission.GET_DETAILED_TASKS)
7305                    == PackageManager.PERMISSION_GRANTED;
7306
7307            IPackageManager pm = AppGlobals.getPackageManager();
7308
7309            final int N = mRecentTasks.size();
7310            ArrayList<ActivityManager.RecentTaskInfo> res
7311                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7312                            maxNum < N ? maxNum : N);
7313
7314            final Set<Integer> includedUsers;
7315            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7316                includedUsers = getProfileIdsLocked(userId);
7317            } else {
7318                includedUsers = new HashSet<Integer>();
7319            }
7320            includedUsers.add(Integer.valueOf(userId));
7321            for (int i=0; i<N && maxNum > 0; i++) {
7322                TaskRecord tr = mRecentTasks.get(i);
7323                // Only add calling user or related users recent tasks
7324                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7325
7326                // Return the entry if desired by the caller.  We always return
7327                // the first entry, because callers always expect this to be the
7328                // foreground app.  We may filter others if the caller has
7329                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7330                // we should exclude the entry.
7331
7332                if (i == 0
7333                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7334                        || (tr.intent == null)
7335                        || ((tr.intent.getFlags()
7336                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7337                    if (!allowed) {
7338                        // If the caller doesn't have the GET_TASKS permission, then only
7339                        // allow them to see a small subset of tasks -- their own and home.
7340                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7341                            continue;
7342                        }
7343                    }
7344                    if (tr.intent != null &&
7345                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7346                            != 0 && tr.getTopActivity() == null) {
7347                        // Don't include auto remove tasks that are finished or finishing.
7348                        continue;
7349                    }
7350
7351                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7352                    if (!detailed) {
7353                        rti.baseIntent.replaceExtras((Bundle)null);
7354                    }
7355
7356                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7357                        // Check whether this activity is currently available.
7358                        try {
7359                            if (rti.origActivity != null) {
7360                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7361                                        == null) {
7362                                    continue;
7363                                }
7364                            } else if (rti.baseIntent != null) {
7365                                if (pm.queryIntentActivities(rti.baseIntent,
7366                                        null, 0, userId) == null) {
7367                                    continue;
7368                                }
7369                            }
7370                        } catch (RemoteException e) {
7371                            // Will never happen.
7372                        }
7373                    }
7374
7375                    res.add(rti);
7376                    maxNum--;
7377                }
7378            }
7379            return res;
7380        }
7381    }
7382
7383    private TaskRecord recentTaskForIdLocked(int id) {
7384        final int N = mRecentTasks.size();
7385            for (int i=0; i<N; i++) {
7386                TaskRecord tr = mRecentTasks.get(i);
7387                if (tr.taskId == id) {
7388                    return tr;
7389                }
7390            }
7391            return null;
7392    }
7393
7394    @Override
7395    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7396        synchronized (this) {
7397            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7398                    "getTaskThumbnail()");
7399            TaskRecord tr = recentTaskForIdLocked(id);
7400            if (tr != null) {
7401                return tr.getTaskThumbnailLocked();
7402            }
7403        }
7404        return null;
7405    }
7406
7407    @Override
7408    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7409        synchronized (this) {
7410            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7411            if (r != null) {
7412                r.taskDescription = td;
7413                r.task.updateTaskDescription();
7414            }
7415        }
7416    }
7417
7418    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7419        if (!pr.killedByAm) {
7420            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7421            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7422                    pr.processName, pr.setAdj, reason);
7423            pr.killedByAm = true;
7424            Process.killProcessQuiet(pr.pid);
7425        }
7426    }
7427
7428    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7429        tr.disposeThumbnail();
7430        mRecentTasks.remove(tr);
7431        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7432        Intent baseIntent = new Intent(
7433                tr.intent != null ? tr.intent : tr.affinityIntent);
7434        ComponentName component = baseIntent.getComponent();
7435        if (component == null) {
7436            Slog.w(TAG, "Now component for base intent of task: " + tr);
7437            return;
7438        }
7439
7440        // Find any running services associated with this app.
7441        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7442
7443        if (killProcesses) {
7444            // Find any running processes associated with this app.
7445            final String pkg = component.getPackageName();
7446            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7447            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7448            for (int i=0; i<pmap.size(); i++) {
7449                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7450                for (int j=0; j<uids.size(); j++) {
7451                    ProcessRecord proc = uids.valueAt(j);
7452                    if (proc.userId != tr.userId) {
7453                        continue;
7454                    }
7455                    if (!proc.pkgList.containsKey(pkg)) {
7456                        continue;
7457                    }
7458                    procs.add(proc);
7459                }
7460            }
7461
7462            // Kill the running processes.
7463            for (int i=0; i<procs.size(); i++) {
7464                ProcessRecord pr = procs.get(i);
7465                if (pr == mHomeProcess) {
7466                    // Don't kill the home process along with tasks from the same package.
7467                    continue;
7468                }
7469                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7470                    killUnneededProcessLocked(pr, "remove task");
7471                } else {
7472                    pr.waitingToKill = "remove task";
7473                }
7474            }
7475        }
7476    }
7477
7478    /**
7479     * Removes the task with the specified task id.
7480     *
7481     * @param taskId Identifier of the task to be removed.
7482     * @param flags Additional operational flags.  May be 0 or
7483     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7484     * @return Returns true if the given task was found and removed.
7485     */
7486    private boolean removeTaskByIdLocked(int taskId, int flags) {
7487        TaskRecord tr = recentTaskForIdLocked(taskId);
7488        if (tr != null) {
7489            tr.removeTaskActivitiesLocked();
7490            cleanUpRemovedTaskLocked(tr, flags);
7491            if (tr.isPersistable) {
7492                notifyTaskPersisterLocked(tr, true);
7493            }
7494            return true;
7495        }
7496        return false;
7497    }
7498
7499    @Override
7500    public boolean removeTask(int taskId, int flags) {
7501        synchronized (this) {
7502            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7503                    "removeTask()");
7504            long ident = Binder.clearCallingIdentity();
7505            try {
7506                return removeTaskByIdLocked(taskId, flags);
7507            } finally {
7508                Binder.restoreCallingIdentity(ident);
7509            }
7510        }
7511    }
7512
7513    /**
7514     * TODO: Add mController hook
7515     */
7516    @Override
7517    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7518        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7519                "moveTaskToFront()");
7520
7521        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7522        synchronized(this) {
7523            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7524                    Binder.getCallingUid(), "Task to front")) {
7525                ActivityOptions.abort(options);
7526                return;
7527            }
7528            final long origId = Binder.clearCallingIdentity();
7529            try {
7530                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7531                if (task == null) {
7532                    return;
7533                }
7534                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7535                    mStackSupervisor.showLockTaskToast();
7536                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7537                    return;
7538                }
7539                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7540                if (prev != null && prev.isRecentsActivity()) {
7541                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7542                }
7543                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7544            } finally {
7545                Binder.restoreCallingIdentity(origId);
7546            }
7547            ActivityOptions.abort(options);
7548        }
7549    }
7550
7551    @Override
7552    public void moveTaskToBack(int taskId) {
7553        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7554                "moveTaskToBack()");
7555
7556        synchronized(this) {
7557            TaskRecord tr = recentTaskForIdLocked(taskId);
7558            if (tr != null) {
7559                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7560                ActivityStack stack = tr.stack;
7561                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7562                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7563                            Binder.getCallingUid(), "Task to back")) {
7564                        return;
7565                    }
7566                }
7567                final long origId = Binder.clearCallingIdentity();
7568                try {
7569                    stack.moveTaskToBackLocked(taskId, null);
7570                } finally {
7571                    Binder.restoreCallingIdentity(origId);
7572                }
7573            }
7574        }
7575    }
7576
7577    /**
7578     * Moves an activity, and all of the other activities within the same task, to the bottom
7579     * of the history stack.  The activity's order within the task is unchanged.
7580     *
7581     * @param token A reference to the activity we wish to move
7582     * @param nonRoot If false then this only works if the activity is the root
7583     *                of a task; if true it will work for any activity in a task.
7584     * @return Returns true if the move completed, false if not.
7585     */
7586    @Override
7587    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7588        enforceNotIsolatedCaller("moveActivityTaskToBack");
7589        synchronized(this) {
7590            final long origId = Binder.clearCallingIdentity();
7591            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7592            if (taskId >= 0) {
7593                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7594            }
7595            Binder.restoreCallingIdentity(origId);
7596        }
7597        return false;
7598    }
7599
7600    @Override
7601    public void moveTaskBackwards(int task) {
7602        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7603                "moveTaskBackwards()");
7604
7605        synchronized(this) {
7606            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7607                    Binder.getCallingUid(), "Task backwards")) {
7608                return;
7609            }
7610            final long origId = Binder.clearCallingIdentity();
7611            moveTaskBackwardsLocked(task);
7612            Binder.restoreCallingIdentity(origId);
7613        }
7614    }
7615
7616    private final void moveTaskBackwardsLocked(int task) {
7617        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7618    }
7619
7620    @Override
7621    public IBinder getHomeActivityToken() throws RemoteException {
7622        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7623                "getHomeActivityToken()");
7624        synchronized (this) {
7625            return mStackSupervisor.getHomeActivityToken();
7626        }
7627    }
7628
7629    @Override
7630    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7631            IActivityContainerCallback callback) throws RemoteException {
7632        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7633                "createActivityContainer()");
7634        synchronized (this) {
7635            if (parentActivityToken == null) {
7636                throw new IllegalArgumentException("parent token must not be null");
7637            }
7638            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7639            if (r == null) {
7640                return null;
7641            }
7642            if (callback == null) {
7643                throw new IllegalArgumentException("callback must not be null");
7644            }
7645            return mStackSupervisor.createActivityContainer(r, callback);
7646        }
7647    }
7648
7649    @Override
7650    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7651        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7652                "deleteActivityContainer()");
7653        synchronized (this) {
7654            mStackSupervisor.deleteActivityContainer(container);
7655        }
7656    }
7657
7658    @Override
7659    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7660            throws RemoteException {
7661        synchronized (this) {
7662            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7663            if (stack != null) {
7664                return stack.mActivityContainer;
7665            }
7666            return null;
7667        }
7668    }
7669
7670    @Override
7671    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7672        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7673                "moveTaskToStack()");
7674        if (stackId == HOME_STACK_ID) {
7675            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7676                    new RuntimeException("here").fillInStackTrace());
7677        }
7678        synchronized (this) {
7679            long ident = Binder.clearCallingIdentity();
7680            try {
7681                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7682                        + stackId + " toTop=" + toTop);
7683                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7684            } finally {
7685                Binder.restoreCallingIdentity(ident);
7686            }
7687        }
7688    }
7689
7690    @Override
7691    public void resizeStack(int stackBoxId, Rect bounds) {
7692        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7693                "resizeStackBox()");
7694        long ident = Binder.clearCallingIdentity();
7695        try {
7696            mWindowManager.resizeStack(stackBoxId, bounds);
7697        } finally {
7698            Binder.restoreCallingIdentity(ident);
7699        }
7700    }
7701
7702    @Override
7703    public List<StackInfo> getAllStackInfos() {
7704        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7705                "getAllStackInfos()");
7706        long ident = Binder.clearCallingIdentity();
7707        try {
7708            synchronized (this) {
7709                return mStackSupervisor.getAllStackInfosLocked();
7710            }
7711        } finally {
7712            Binder.restoreCallingIdentity(ident);
7713        }
7714    }
7715
7716    @Override
7717    public StackInfo getStackInfo(int stackId) {
7718        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7719                "getStackInfo()");
7720        long ident = Binder.clearCallingIdentity();
7721        try {
7722            synchronized (this) {
7723                return mStackSupervisor.getStackInfoLocked(stackId);
7724            }
7725        } finally {
7726            Binder.restoreCallingIdentity(ident);
7727        }
7728    }
7729
7730    @Override
7731    public boolean isInHomeStack(int taskId) {
7732        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7733                "getStackInfo()");
7734        long ident = Binder.clearCallingIdentity();
7735        try {
7736            synchronized (this) {
7737                TaskRecord tr = recentTaskForIdLocked(taskId);
7738                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7739            }
7740        } finally {
7741            Binder.restoreCallingIdentity(ident);
7742        }
7743    }
7744
7745    @Override
7746    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7747        synchronized(this) {
7748            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7749        }
7750    }
7751
7752    private boolean isLockTaskAuthorized(String pkg) {
7753        final DevicePolicyManager dpm = (DevicePolicyManager)
7754                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7755        try {
7756            int uid = mContext.getPackageManager().getPackageUid(pkg,
7757                    Binder.getCallingUserHandle().getIdentifier());
7758            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7759        } catch (NameNotFoundException e) {
7760            return false;
7761        }
7762    }
7763
7764    void startLockTaskMode(TaskRecord task) {
7765        final String pkg;
7766        synchronized (this) {
7767            pkg = task.intent.getComponent().getPackageName();
7768        }
7769        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7770        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7771            final TaskRecord taskRecord = task;
7772            mHandler.post(new Runnable() {
7773                @Override
7774                public void run() {
7775                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7776                }
7777            });
7778            return;
7779        }
7780        long ident = Binder.clearCallingIdentity();
7781        try {
7782            synchronized (this) {
7783                // Since we lost lock on task, make sure it is still there.
7784                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7785                if (task != null) {
7786                    if (!isSystemInitiated
7787                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7788                        throw new IllegalArgumentException("Invalid task, not in foreground");
7789                    }
7790                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7791                }
7792            }
7793        } finally {
7794            Binder.restoreCallingIdentity(ident);
7795        }
7796    }
7797
7798    @Override
7799    public void startLockTaskMode(int taskId) {
7800        final TaskRecord task;
7801        long ident = Binder.clearCallingIdentity();
7802        try {
7803            synchronized (this) {
7804                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7805            }
7806        } finally {
7807            Binder.restoreCallingIdentity(ident);
7808        }
7809        if (task != null) {
7810            startLockTaskMode(task);
7811        }
7812    }
7813
7814    @Override
7815    public void startLockTaskMode(IBinder token) {
7816        final TaskRecord task;
7817        long ident = Binder.clearCallingIdentity();
7818        try {
7819            synchronized (this) {
7820                final ActivityRecord r = ActivityRecord.forToken(token);
7821                if (r == null) {
7822                    return;
7823                }
7824                task = r.task;
7825            }
7826        } finally {
7827            Binder.restoreCallingIdentity(ident);
7828        }
7829        if (task != null) {
7830            startLockTaskMode(task);
7831        }
7832    }
7833
7834    @Override
7835    public void startLockTaskModeOnCurrent() throws RemoteException {
7836        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7837        ActivityRecord r = null;
7838        synchronized (this) {
7839            r = mStackSupervisor.topRunningActivityLocked();
7840        }
7841        startLockTaskMode(r.task);
7842    }
7843
7844    @Override
7845    public void stopLockTaskMode() {
7846        // Verify that the user matches the package of the intent for the TaskRecord
7847        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7848        // and stopLockTaskMode.
7849        final int callingUid = Binder.getCallingUid();
7850        if (callingUid != Process.SYSTEM_UID) {
7851            try {
7852                String pkg =
7853                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7854                int uid = mContext.getPackageManager().getPackageUid(pkg,
7855                        Binder.getCallingUserHandle().getIdentifier());
7856                if (uid != callingUid) {
7857                    throw new SecurityException("Invalid uid, expected " + uid);
7858                }
7859            } catch (NameNotFoundException e) {
7860                Log.d(TAG, "stopLockTaskMode " + e);
7861                return;
7862            }
7863        }
7864        long ident = Binder.clearCallingIdentity();
7865        try {
7866            Log.d(TAG, "stopLockTaskMode");
7867            // Stop lock task
7868            synchronized (this) {
7869                mStackSupervisor.setLockTaskModeLocked(null, false);
7870            }
7871        } finally {
7872            Binder.restoreCallingIdentity(ident);
7873        }
7874    }
7875
7876    @Override
7877    public void stopLockTaskModeOnCurrent() throws RemoteException {
7878        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7879        long ident = Binder.clearCallingIdentity();
7880        try {
7881            stopLockTaskMode();
7882        } finally {
7883            Binder.restoreCallingIdentity(ident);
7884        }
7885    }
7886
7887    @Override
7888    public boolean isInLockTaskMode() {
7889        synchronized (this) {
7890            return mStackSupervisor.isInLockTaskMode();
7891        }
7892    }
7893
7894    // =========================================================
7895    // CONTENT PROVIDERS
7896    // =========================================================
7897
7898    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7899        List<ProviderInfo> providers = null;
7900        try {
7901            providers = AppGlobals.getPackageManager().
7902                queryContentProviders(app.processName, app.uid,
7903                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7904        } catch (RemoteException ex) {
7905        }
7906        if (DEBUG_MU)
7907            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7908        int userId = app.userId;
7909        if (providers != null) {
7910            int N = providers.size();
7911            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7912            for (int i=0; i<N; i++) {
7913                ProviderInfo cpi =
7914                    (ProviderInfo)providers.get(i);
7915                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7916                        cpi.name, cpi.flags);
7917                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7918                    // This is a singleton provider, but a user besides the
7919                    // default user is asking to initialize a process it runs
7920                    // in...  well, no, it doesn't actually run in this process,
7921                    // it runs in the process of the default user.  Get rid of it.
7922                    providers.remove(i);
7923                    N--;
7924                    i--;
7925                    continue;
7926                }
7927
7928                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7929                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7930                if (cpr == null) {
7931                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7932                    mProviderMap.putProviderByClass(comp, cpr);
7933                }
7934                if (DEBUG_MU)
7935                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7936                app.pubProviders.put(cpi.name, cpr);
7937                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7938                    // Don't add this if it is a platform component that is marked
7939                    // to run in multiple processes, because this is actually
7940                    // part of the framework so doesn't make sense to track as a
7941                    // separate apk in the process.
7942                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7943                            mProcessStats);
7944                }
7945                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7946            }
7947        }
7948        return providers;
7949    }
7950
7951    /**
7952     * Check if {@link ProcessRecord} has a possible chance at accessing the
7953     * given {@link ProviderInfo}. Final permission checking is always done
7954     * in {@link ContentProvider}.
7955     */
7956    private final String checkContentProviderPermissionLocked(
7957            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7958        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7959        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7960        boolean checkedGrants = false;
7961        if (checkUser) {
7962            // Looking for cross-user grants before enforcing the typical cross-users permissions
7963            int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid));
7964            if (tmpTargetUserId != userId) {
7965                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
7966                    return null;
7967                }
7968                checkedGrants = true;
7969            }
7970            userId = handleIncomingUser(callingPid, callingUid, userId,
7971                    false, ALLOW_NON_FULL_IN_PROFILE,
7972                    "checkContentProviderPermissionLocked " + cpi.authority, null);
7973            if (userId != tmpTargetUserId) {
7974                // When we actually went to determine the final targer user ID, this ended
7975                // up different than our initial check for the authority.  This is because
7976                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
7977                // SELF.  So we need to re-check the grants again.
7978                checkedGrants = false;
7979            }
7980        }
7981        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7982                cpi.applicationInfo.uid, cpi.exported)
7983                == PackageManager.PERMISSION_GRANTED) {
7984            return null;
7985        }
7986        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7987                cpi.applicationInfo.uid, cpi.exported)
7988                == PackageManager.PERMISSION_GRANTED) {
7989            return null;
7990        }
7991
7992        PathPermission[] pps = cpi.pathPermissions;
7993        if (pps != null) {
7994            int i = pps.length;
7995            while (i > 0) {
7996                i--;
7997                PathPermission pp = pps[i];
7998                String pprperm = pp.getReadPermission();
7999                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8000                        cpi.applicationInfo.uid, cpi.exported)
8001                        == PackageManager.PERMISSION_GRANTED) {
8002                    return null;
8003                }
8004                String ppwperm = pp.getWritePermission();
8005                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8006                        cpi.applicationInfo.uid, cpi.exported)
8007                        == PackageManager.PERMISSION_GRANTED) {
8008                    return null;
8009                }
8010            }
8011        }
8012        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8013            return null;
8014        }
8015
8016        String msg;
8017        if (!cpi.exported) {
8018            msg = "Permission Denial: opening provider " + cpi.name
8019                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8020                    + ", uid=" + callingUid + ") that is not exported from uid "
8021                    + cpi.applicationInfo.uid;
8022        } else {
8023            msg = "Permission Denial: opening provider " + cpi.name
8024                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8025                    + ", uid=" + callingUid + ") requires "
8026                    + cpi.readPermission + " or " + cpi.writePermission;
8027        }
8028        Slog.w(TAG, msg);
8029        return msg;
8030    }
8031
8032    /**
8033     * Returns if the ContentProvider has granted a uri to callingUid
8034     */
8035    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8036        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8037        if (perms != null) {
8038            for (int i=perms.size()-1; i>=0; i--) {
8039                GrantUri grantUri = perms.keyAt(i);
8040                if (grantUri.sourceUserId == userId || !checkUser) {
8041                    if (matchesProvider(grantUri.uri, cpi)) {
8042                        return true;
8043                    }
8044                }
8045            }
8046        }
8047        return false;
8048    }
8049
8050    /**
8051     * Returns true if the uri authority is one of the authorities specified in the provider.
8052     */
8053    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8054        String uriAuth = uri.getAuthority();
8055        String cpiAuth = cpi.authority;
8056        if (cpiAuth.indexOf(';') == -1) {
8057            return cpiAuth.equals(uriAuth);
8058        }
8059        String[] cpiAuths = cpiAuth.split(";");
8060        int length = cpiAuths.length;
8061        for (int i = 0; i < length; i++) {
8062            if (cpiAuths[i].equals(uriAuth)) return true;
8063        }
8064        return false;
8065    }
8066
8067    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8068            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8069        if (r != null) {
8070            for (int i=0; i<r.conProviders.size(); i++) {
8071                ContentProviderConnection conn = r.conProviders.get(i);
8072                if (conn.provider == cpr) {
8073                    if (DEBUG_PROVIDER) Slog.v(TAG,
8074                            "Adding provider requested by "
8075                            + r.processName + " from process "
8076                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8077                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8078                    if (stable) {
8079                        conn.stableCount++;
8080                        conn.numStableIncs++;
8081                    } else {
8082                        conn.unstableCount++;
8083                        conn.numUnstableIncs++;
8084                    }
8085                    return conn;
8086                }
8087            }
8088            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8089            if (stable) {
8090                conn.stableCount = 1;
8091                conn.numStableIncs = 1;
8092            } else {
8093                conn.unstableCount = 1;
8094                conn.numUnstableIncs = 1;
8095            }
8096            cpr.connections.add(conn);
8097            r.conProviders.add(conn);
8098            return conn;
8099        }
8100        cpr.addExternalProcessHandleLocked(externalProcessToken);
8101        return null;
8102    }
8103
8104    boolean decProviderCountLocked(ContentProviderConnection conn,
8105            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8106        if (conn != null) {
8107            cpr = conn.provider;
8108            if (DEBUG_PROVIDER) Slog.v(TAG,
8109                    "Removing provider requested by "
8110                    + conn.client.processName + " from process "
8111                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8112                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8113            if (stable) {
8114                conn.stableCount--;
8115            } else {
8116                conn.unstableCount--;
8117            }
8118            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8119                cpr.connections.remove(conn);
8120                conn.client.conProviders.remove(conn);
8121                return true;
8122            }
8123            return false;
8124        }
8125        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8126        return false;
8127    }
8128
8129    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8130            String name, IBinder token, boolean stable, int userId) {
8131        ContentProviderRecord cpr;
8132        ContentProviderConnection conn = null;
8133        ProviderInfo cpi = null;
8134
8135        synchronized(this) {
8136            ProcessRecord r = null;
8137            if (caller != null) {
8138                r = getRecordForAppLocked(caller);
8139                if (r == null) {
8140                    throw new SecurityException(
8141                            "Unable to find app for caller " + caller
8142                          + " (pid=" + Binder.getCallingPid()
8143                          + ") when getting content provider " + name);
8144                }
8145            }
8146
8147            boolean checkCrossUser = true;
8148
8149            // First check if this content provider has been published...
8150            cpr = mProviderMap.getProviderByName(name, userId);
8151            // If that didn't work, check if it exists for user 0 and then
8152            // verify that it's a singleton provider before using it.
8153            if (cpr == null && userId != UserHandle.USER_OWNER) {
8154                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8155                if (cpr != null) {
8156                    cpi = cpr.info;
8157                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8158                            cpi.name, cpi.flags)
8159                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8160                        userId = UserHandle.USER_OWNER;
8161                        checkCrossUser = false;
8162                    } else {
8163                        cpr = null;
8164                        cpi = null;
8165                    }
8166                }
8167            }
8168
8169            boolean providerRunning = cpr != null;
8170            if (providerRunning) {
8171                cpi = cpr.info;
8172                String msg;
8173                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8174                        != null) {
8175                    throw new SecurityException(msg);
8176                }
8177
8178                if (r != null && cpr.canRunHere(r)) {
8179                    // This provider has been published or is in the process
8180                    // of being published...  but it is also allowed to run
8181                    // in the caller's process, so don't make a connection
8182                    // and just let the caller instantiate its own instance.
8183                    ContentProviderHolder holder = cpr.newHolder(null);
8184                    // don't give caller the provider object, it needs
8185                    // to make its own.
8186                    holder.provider = null;
8187                    return holder;
8188                }
8189
8190                final long origId = Binder.clearCallingIdentity();
8191
8192                // In this case the provider instance already exists, so we can
8193                // return it right away.
8194                conn = incProviderCountLocked(r, cpr, token, stable);
8195                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8196                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8197                        // If this is a perceptible app accessing the provider,
8198                        // make sure to count it as being accessed and thus
8199                        // back up on the LRU list.  This is good because
8200                        // content providers are often expensive to start.
8201                        updateLruProcessLocked(cpr.proc, false, null);
8202                    }
8203                }
8204
8205                if (cpr.proc != null) {
8206                    if (false) {
8207                        if (cpr.name.flattenToShortString().equals(
8208                                "com.android.providers.calendar/.CalendarProvider2")) {
8209                            Slog.v(TAG, "****************** KILLING "
8210                                + cpr.name.flattenToShortString());
8211                            Process.killProcess(cpr.proc.pid);
8212                        }
8213                    }
8214                    boolean success = updateOomAdjLocked(cpr.proc);
8215                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8216                    // NOTE: there is still a race here where a signal could be
8217                    // pending on the process even though we managed to update its
8218                    // adj level.  Not sure what to do about this, but at least
8219                    // the race is now smaller.
8220                    if (!success) {
8221                        // Uh oh...  it looks like the provider's process
8222                        // has been killed on us.  We need to wait for a new
8223                        // process to be started, and make sure its death
8224                        // doesn't kill our process.
8225                        Slog.i(TAG,
8226                                "Existing provider " + cpr.name.flattenToShortString()
8227                                + " is crashing; detaching " + r);
8228                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8229                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8230                        if (!lastRef) {
8231                            // This wasn't the last ref our process had on
8232                            // the provider...  we have now been killed, bail.
8233                            return null;
8234                        }
8235                        providerRunning = false;
8236                        conn = null;
8237                    }
8238                }
8239
8240                Binder.restoreCallingIdentity(origId);
8241            }
8242
8243            boolean singleton;
8244            if (!providerRunning) {
8245                try {
8246                    cpi = AppGlobals.getPackageManager().
8247                        resolveContentProvider(name,
8248                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8249                } catch (RemoteException ex) {
8250                }
8251                if (cpi == null) {
8252                    return null;
8253                }
8254                // If the provider is a singleton AND
8255                // (it's a call within the same user || the provider is a
8256                // privileged app)
8257                // Then allow connecting to the singleton provider
8258                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8259                        cpi.name, cpi.flags)
8260                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8261                if (singleton) {
8262                    userId = UserHandle.USER_OWNER;
8263                }
8264                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8265
8266                String msg;
8267                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8268                        != null) {
8269                    throw new SecurityException(msg);
8270                }
8271
8272                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8273                        && !cpi.processName.equals("system")) {
8274                    // If this content provider does not run in the system
8275                    // process, and the system is not yet ready to run other
8276                    // processes, then fail fast instead of hanging.
8277                    throw new IllegalArgumentException(
8278                            "Attempt to launch content provider before system ready");
8279                }
8280
8281                // Make sure that the user who owns this provider is started.  If not,
8282                // we don't want to allow it to run.
8283                if (mStartedUsers.get(userId) == null) {
8284                    Slog.w(TAG, "Unable to launch app "
8285                            + cpi.applicationInfo.packageName + "/"
8286                            + cpi.applicationInfo.uid + " for provider "
8287                            + name + ": user " + userId + " is stopped");
8288                    return null;
8289                }
8290
8291                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8292                cpr = mProviderMap.getProviderByClass(comp, userId);
8293                final boolean firstClass = cpr == null;
8294                if (firstClass) {
8295                    try {
8296                        ApplicationInfo ai =
8297                            AppGlobals.getPackageManager().
8298                                getApplicationInfo(
8299                                        cpi.applicationInfo.packageName,
8300                                        STOCK_PM_FLAGS, userId);
8301                        if (ai == null) {
8302                            Slog.w(TAG, "No package info for content provider "
8303                                    + cpi.name);
8304                            return null;
8305                        }
8306                        ai = getAppInfoForUser(ai, userId);
8307                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8308                    } catch (RemoteException ex) {
8309                        // pm is in same process, this will never happen.
8310                    }
8311                }
8312
8313                if (r != null && cpr.canRunHere(r)) {
8314                    // If this is a multiprocess provider, then just return its
8315                    // info and allow the caller to instantiate it.  Only do
8316                    // this if the provider is the same user as the caller's
8317                    // process, or can run as root (so can be in any process).
8318                    return cpr.newHolder(null);
8319                }
8320
8321                if (DEBUG_PROVIDER) {
8322                    RuntimeException e = new RuntimeException("here");
8323                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8324                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8325                }
8326
8327                // This is single process, and our app is now connecting to it.
8328                // See if we are already in the process of launching this
8329                // provider.
8330                final int N = mLaunchingProviders.size();
8331                int i;
8332                for (i=0; i<N; i++) {
8333                    if (mLaunchingProviders.get(i) == cpr) {
8334                        break;
8335                    }
8336                }
8337
8338                // If the provider is not already being launched, then get it
8339                // started.
8340                if (i >= N) {
8341                    final long origId = Binder.clearCallingIdentity();
8342
8343                    try {
8344                        // Content provider is now in use, its package can't be stopped.
8345                        try {
8346                            AppGlobals.getPackageManager().setPackageStoppedState(
8347                                    cpr.appInfo.packageName, false, userId);
8348                        } catch (RemoteException e) {
8349                        } catch (IllegalArgumentException e) {
8350                            Slog.w(TAG, "Failed trying to unstop package "
8351                                    + cpr.appInfo.packageName + ": " + e);
8352                        }
8353
8354                        // Use existing process if already started
8355                        ProcessRecord proc = getProcessRecordLocked(
8356                                cpi.processName, cpr.appInfo.uid, false);
8357                        if (proc != null && proc.thread != null) {
8358                            if (DEBUG_PROVIDER) {
8359                                Slog.d(TAG, "Installing in existing process " + proc);
8360                            }
8361                            proc.pubProviders.put(cpi.name, cpr);
8362                            try {
8363                                proc.thread.scheduleInstallProvider(cpi);
8364                            } catch (RemoteException e) {
8365                            }
8366                        } else {
8367                            proc = startProcessLocked(cpi.processName,
8368                                    cpr.appInfo, false, 0, "content provider",
8369                                    new ComponentName(cpi.applicationInfo.packageName,
8370                                            cpi.name), false, false, false);
8371                            if (proc == null) {
8372                                Slog.w(TAG, "Unable to launch app "
8373                                        + cpi.applicationInfo.packageName + "/"
8374                                        + cpi.applicationInfo.uid + " for provider "
8375                                        + name + ": process is bad");
8376                                return null;
8377                            }
8378                        }
8379                        cpr.launchingApp = proc;
8380                        mLaunchingProviders.add(cpr);
8381                    } finally {
8382                        Binder.restoreCallingIdentity(origId);
8383                    }
8384                }
8385
8386                // Make sure the provider is published (the same provider class
8387                // may be published under multiple names).
8388                if (firstClass) {
8389                    mProviderMap.putProviderByClass(comp, cpr);
8390                }
8391
8392                mProviderMap.putProviderByName(name, cpr);
8393                conn = incProviderCountLocked(r, cpr, token, stable);
8394                if (conn != null) {
8395                    conn.waiting = true;
8396                }
8397            }
8398        }
8399
8400        // Wait for the provider to be published...
8401        synchronized (cpr) {
8402            while (cpr.provider == null) {
8403                if (cpr.launchingApp == null) {
8404                    Slog.w(TAG, "Unable to launch app "
8405                            + cpi.applicationInfo.packageName + "/"
8406                            + cpi.applicationInfo.uid + " for provider "
8407                            + name + ": launching app became null");
8408                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8409                            UserHandle.getUserId(cpi.applicationInfo.uid),
8410                            cpi.applicationInfo.packageName,
8411                            cpi.applicationInfo.uid, name);
8412                    return null;
8413                }
8414                try {
8415                    if (DEBUG_MU) {
8416                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8417                                + cpr.launchingApp);
8418                    }
8419                    if (conn != null) {
8420                        conn.waiting = true;
8421                    }
8422                    cpr.wait();
8423                } catch (InterruptedException ex) {
8424                } finally {
8425                    if (conn != null) {
8426                        conn.waiting = false;
8427                    }
8428                }
8429            }
8430        }
8431        return cpr != null ? cpr.newHolder(conn) : null;
8432    }
8433
8434    @Override
8435    public final ContentProviderHolder getContentProvider(
8436            IApplicationThread caller, String name, int userId, boolean stable) {
8437        enforceNotIsolatedCaller("getContentProvider");
8438        if (caller == null) {
8439            String msg = "null IApplicationThread when getting content provider "
8440                    + name;
8441            Slog.w(TAG, msg);
8442            throw new SecurityException(msg);
8443        }
8444        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8445        // with cross-user grant.
8446        return getContentProviderImpl(caller, name, null, stable, userId);
8447    }
8448
8449    public ContentProviderHolder getContentProviderExternal(
8450            String name, int userId, IBinder token) {
8451        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8452            "Do not have permission in call getContentProviderExternal()");
8453        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8454                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8455        return getContentProviderExternalUnchecked(name, token, userId);
8456    }
8457
8458    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8459            IBinder token, int userId) {
8460        return getContentProviderImpl(null, name, token, true, userId);
8461    }
8462
8463    /**
8464     * Drop a content provider from a ProcessRecord's bookkeeping
8465     */
8466    public void removeContentProvider(IBinder connection, boolean stable) {
8467        enforceNotIsolatedCaller("removeContentProvider");
8468        long ident = Binder.clearCallingIdentity();
8469        try {
8470            synchronized (this) {
8471                ContentProviderConnection conn;
8472                try {
8473                    conn = (ContentProviderConnection)connection;
8474                } catch (ClassCastException e) {
8475                    String msg ="removeContentProvider: " + connection
8476                            + " not a ContentProviderConnection";
8477                    Slog.w(TAG, msg);
8478                    throw new IllegalArgumentException(msg);
8479                }
8480                if (conn == null) {
8481                    throw new NullPointerException("connection is null");
8482                }
8483                if (decProviderCountLocked(conn, null, null, stable)) {
8484                    updateOomAdjLocked();
8485                }
8486            }
8487        } finally {
8488            Binder.restoreCallingIdentity(ident);
8489        }
8490    }
8491
8492    public void removeContentProviderExternal(String name, IBinder token) {
8493        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8494            "Do not have permission in call removeContentProviderExternal()");
8495        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8496    }
8497
8498    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8499        synchronized (this) {
8500            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8501            if(cpr == null) {
8502                //remove from mProvidersByClass
8503                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8504                return;
8505            }
8506
8507            //update content provider record entry info
8508            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8509            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8510            if (localCpr.hasExternalProcessHandles()) {
8511                if (localCpr.removeExternalProcessHandleLocked(token)) {
8512                    updateOomAdjLocked();
8513                } else {
8514                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8515                            + " with no external reference for token: "
8516                            + token + ".");
8517                }
8518            } else {
8519                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8520                        + " with no external references.");
8521            }
8522        }
8523    }
8524
8525    public final void publishContentProviders(IApplicationThread caller,
8526            List<ContentProviderHolder> providers) {
8527        if (providers == null) {
8528            return;
8529        }
8530
8531        enforceNotIsolatedCaller("publishContentProviders");
8532        synchronized (this) {
8533            final ProcessRecord r = getRecordForAppLocked(caller);
8534            if (DEBUG_MU)
8535                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8536            if (r == null) {
8537                throw new SecurityException(
8538                        "Unable to find app for caller " + caller
8539                      + " (pid=" + Binder.getCallingPid()
8540                      + ") when publishing content providers");
8541            }
8542
8543            final long origId = Binder.clearCallingIdentity();
8544
8545            final int N = providers.size();
8546            for (int i=0; i<N; i++) {
8547                ContentProviderHolder src = providers.get(i);
8548                if (src == null || src.info == null || src.provider == null) {
8549                    continue;
8550                }
8551                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8552                if (DEBUG_MU)
8553                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8554                if (dst != null) {
8555                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8556                    mProviderMap.putProviderByClass(comp, dst);
8557                    String names[] = dst.info.authority.split(";");
8558                    for (int j = 0; j < names.length; j++) {
8559                        mProviderMap.putProviderByName(names[j], dst);
8560                    }
8561
8562                    int NL = mLaunchingProviders.size();
8563                    int j;
8564                    for (j=0; j<NL; j++) {
8565                        if (mLaunchingProviders.get(j) == dst) {
8566                            mLaunchingProviders.remove(j);
8567                            j--;
8568                            NL--;
8569                        }
8570                    }
8571                    synchronized (dst) {
8572                        dst.provider = src.provider;
8573                        dst.proc = r;
8574                        dst.notifyAll();
8575                    }
8576                    updateOomAdjLocked(r);
8577                }
8578            }
8579
8580            Binder.restoreCallingIdentity(origId);
8581        }
8582    }
8583
8584    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8585        ContentProviderConnection conn;
8586        try {
8587            conn = (ContentProviderConnection)connection;
8588        } catch (ClassCastException e) {
8589            String msg ="refContentProvider: " + connection
8590                    + " not a ContentProviderConnection";
8591            Slog.w(TAG, msg);
8592            throw new IllegalArgumentException(msg);
8593        }
8594        if (conn == null) {
8595            throw new NullPointerException("connection is null");
8596        }
8597
8598        synchronized (this) {
8599            if (stable > 0) {
8600                conn.numStableIncs += stable;
8601            }
8602            stable = conn.stableCount + stable;
8603            if (stable < 0) {
8604                throw new IllegalStateException("stableCount < 0: " + stable);
8605            }
8606
8607            if (unstable > 0) {
8608                conn.numUnstableIncs += unstable;
8609            }
8610            unstable = conn.unstableCount + unstable;
8611            if (unstable < 0) {
8612                throw new IllegalStateException("unstableCount < 0: " + unstable);
8613            }
8614
8615            if ((stable+unstable) <= 0) {
8616                throw new IllegalStateException("ref counts can't go to zero here: stable="
8617                        + stable + " unstable=" + unstable);
8618            }
8619            conn.stableCount = stable;
8620            conn.unstableCount = unstable;
8621            return !conn.dead;
8622        }
8623    }
8624
8625    public void unstableProviderDied(IBinder connection) {
8626        ContentProviderConnection conn;
8627        try {
8628            conn = (ContentProviderConnection)connection;
8629        } catch (ClassCastException e) {
8630            String msg ="refContentProvider: " + connection
8631                    + " not a ContentProviderConnection";
8632            Slog.w(TAG, msg);
8633            throw new IllegalArgumentException(msg);
8634        }
8635        if (conn == null) {
8636            throw new NullPointerException("connection is null");
8637        }
8638
8639        // Safely retrieve the content provider associated with the connection.
8640        IContentProvider provider;
8641        synchronized (this) {
8642            provider = conn.provider.provider;
8643        }
8644
8645        if (provider == null) {
8646            // Um, yeah, we're way ahead of you.
8647            return;
8648        }
8649
8650        // Make sure the caller is being honest with us.
8651        if (provider.asBinder().pingBinder()) {
8652            // Er, no, still looks good to us.
8653            synchronized (this) {
8654                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8655                        + " says " + conn + " died, but we don't agree");
8656                return;
8657            }
8658        }
8659
8660        // Well look at that!  It's dead!
8661        synchronized (this) {
8662            if (conn.provider.provider != provider) {
8663                // But something changed...  good enough.
8664                return;
8665            }
8666
8667            ProcessRecord proc = conn.provider.proc;
8668            if (proc == null || proc.thread == null) {
8669                // Seems like the process is already cleaned up.
8670                return;
8671            }
8672
8673            // As far as we're concerned, this is just like receiving a
8674            // death notification...  just a bit prematurely.
8675            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8676                    + ") early provider death");
8677            final long ident = Binder.clearCallingIdentity();
8678            try {
8679                appDiedLocked(proc, proc.pid, proc.thread);
8680            } finally {
8681                Binder.restoreCallingIdentity(ident);
8682            }
8683        }
8684    }
8685
8686    @Override
8687    public void appNotRespondingViaProvider(IBinder connection) {
8688        enforceCallingPermission(
8689                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8690
8691        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8692        if (conn == null) {
8693            Slog.w(TAG, "ContentProviderConnection is null");
8694            return;
8695        }
8696
8697        final ProcessRecord host = conn.provider.proc;
8698        if (host == null) {
8699            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8700            return;
8701        }
8702
8703        final long token = Binder.clearCallingIdentity();
8704        try {
8705            appNotResponding(host, null, null, false, "ContentProvider not responding");
8706        } finally {
8707            Binder.restoreCallingIdentity(token);
8708        }
8709    }
8710
8711    public final void installSystemProviders() {
8712        List<ProviderInfo> providers;
8713        synchronized (this) {
8714            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8715            providers = generateApplicationProvidersLocked(app);
8716            if (providers != null) {
8717                for (int i=providers.size()-1; i>=0; i--) {
8718                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8719                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8720                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8721                                + ": not system .apk");
8722                        providers.remove(i);
8723                    }
8724                }
8725            }
8726        }
8727        if (providers != null) {
8728            mSystemThread.installSystemProviders(providers);
8729        }
8730
8731        mCoreSettingsObserver = new CoreSettingsObserver(this);
8732
8733        mUsageStatsService.monitorPackages();
8734    }
8735
8736    /**
8737     * Allows app to retrieve the MIME type of a URI without having permission
8738     * to access its content provider.
8739     *
8740     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8741     *
8742     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8743     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8744     */
8745    public String getProviderMimeType(Uri uri, int userId) {
8746        enforceNotIsolatedCaller("getProviderMimeType");
8747        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8748                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8749        final String name = uri.getAuthority();
8750        final long ident = Binder.clearCallingIdentity();
8751        ContentProviderHolder holder = null;
8752
8753        try {
8754            holder = getContentProviderExternalUnchecked(name, null, userId);
8755            if (holder != null) {
8756                return holder.provider.getType(uri);
8757            }
8758        } catch (RemoteException e) {
8759            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8760            return null;
8761        } finally {
8762            if (holder != null) {
8763                removeContentProviderExternalUnchecked(name, null, userId);
8764            }
8765            Binder.restoreCallingIdentity(ident);
8766        }
8767
8768        return null;
8769    }
8770
8771    // =========================================================
8772    // GLOBAL MANAGEMENT
8773    // =========================================================
8774
8775    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8776            boolean isolated) {
8777        String proc = customProcess != null ? customProcess : info.processName;
8778        BatteryStatsImpl.Uid.Proc ps = null;
8779        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8780        int uid = info.uid;
8781        if (isolated) {
8782            int userId = UserHandle.getUserId(uid);
8783            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8784            while (true) {
8785                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8786                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8787                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8788                }
8789                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8790                mNextIsolatedProcessUid++;
8791                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8792                    // No process for this uid, use it.
8793                    break;
8794                }
8795                stepsLeft--;
8796                if (stepsLeft <= 0) {
8797                    return null;
8798                }
8799            }
8800        }
8801        return new ProcessRecord(stats, info, proc, uid);
8802    }
8803
8804    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8805            String abiOverride) {
8806        ProcessRecord app;
8807        if (!isolated) {
8808            app = getProcessRecordLocked(info.processName, info.uid, true);
8809        } else {
8810            app = null;
8811        }
8812
8813        if (app == null) {
8814            app = newProcessRecordLocked(info, null, isolated);
8815            mProcessNames.put(info.processName, app.uid, app);
8816            if (isolated) {
8817                mIsolatedProcesses.put(app.uid, app);
8818            }
8819            updateLruProcessLocked(app, false, null);
8820            updateOomAdjLocked();
8821        }
8822
8823        // This package really, really can not be stopped.
8824        try {
8825            AppGlobals.getPackageManager().setPackageStoppedState(
8826                    info.packageName, false, UserHandle.getUserId(app.uid));
8827        } catch (RemoteException e) {
8828        } catch (IllegalArgumentException e) {
8829            Slog.w(TAG, "Failed trying to unstop package "
8830                    + info.packageName + ": " + e);
8831        }
8832
8833        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8834                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8835            app.persistent = true;
8836            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8837        }
8838        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8839            mPersistentStartingProcesses.add(app);
8840            startProcessLocked(app, "added application", app.processName,
8841                    abiOverride);
8842        }
8843
8844        return app;
8845    }
8846
8847    public void unhandledBack() {
8848        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8849                "unhandledBack()");
8850
8851        synchronized(this) {
8852            final long origId = Binder.clearCallingIdentity();
8853            try {
8854                getFocusedStack().unhandledBackLocked();
8855            } finally {
8856                Binder.restoreCallingIdentity(origId);
8857            }
8858        }
8859    }
8860
8861    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8862        enforceNotIsolatedCaller("openContentUri");
8863        final int userId = UserHandle.getCallingUserId();
8864        String name = uri.getAuthority();
8865        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8866        ParcelFileDescriptor pfd = null;
8867        if (cph != null) {
8868            // We record the binder invoker's uid in thread-local storage before
8869            // going to the content provider to open the file.  Later, in the code
8870            // that handles all permissions checks, we look for this uid and use
8871            // that rather than the Activity Manager's own uid.  The effect is that
8872            // we do the check against the caller's permissions even though it looks
8873            // to the content provider like the Activity Manager itself is making
8874            // the request.
8875            sCallerIdentity.set(new Identity(
8876                    Binder.getCallingPid(), Binder.getCallingUid()));
8877            try {
8878                pfd = cph.provider.openFile(null, uri, "r", null);
8879            } catch (FileNotFoundException e) {
8880                // do nothing; pfd will be returned null
8881            } finally {
8882                // Ensure that whatever happens, we clean up the identity state
8883                sCallerIdentity.remove();
8884            }
8885
8886            // We've got the fd now, so we're done with the provider.
8887            removeContentProviderExternalUnchecked(name, null, userId);
8888        } else {
8889            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8890        }
8891        return pfd;
8892    }
8893
8894    // Actually is sleeping or shutting down or whatever else in the future
8895    // is an inactive state.
8896    public boolean isSleepingOrShuttingDown() {
8897        return mSleeping || mShuttingDown;
8898    }
8899
8900    public boolean isSleeping() {
8901        return mSleeping;
8902    }
8903
8904    void goingToSleep() {
8905        synchronized(this) {
8906            mWentToSleep = true;
8907            updateEventDispatchingLocked();
8908            goToSleepIfNeededLocked();
8909        }
8910    }
8911
8912    void finishRunningVoiceLocked() {
8913        if (mRunningVoice) {
8914            mRunningVoice = false;
8915            goToSleepIfNeededLocked();
8916        }
8917    }
8918
8919    void goToSleepIfNeededLocked() {
8920        if (mWentToSleep && !mRunningVoice) {
8921            if (!mSleeping) {
8922                mSleeping = true;
8923                mStackSupervisor.goingToSleepLocked();
8924
8925                // Initialize the wake times of all processes.
8926                checkExcessivePowerUsageLocked(false);
8927                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8928                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8929                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8930            }
8931        }
8932    }
8933
8934    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8935        mTaskPersister.notify(task, flush);
8936    }
8937
8938    @Override
8939    public boolean shutdown(int timeout) {
8940        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8941                != PackageManager.PERMISSION_GRANTED) {
8942            throw new SecurityException("Requires permission "
8943                    + android.Manifest.permission.SHUTDOWN);
8944        }
8945
8946        boolean timedout = false;
8947
8948        synchronized(this) {
8949            mShuttingDown = true;
8950            updateEventDispatchingLocked();
8951            timedout = mStackSupervisor.shutdownLocked(timeout);
8952        }
8953
8954        mAppOpsService.shutdown();
8955        mUsageStatsService.shutdown();
8956        mBatteryStatsService.shutdown();
8957        synchronized (this) {
8958            mProcessStats.shutdownLocked();
8959        }
8960        notifyTaskPersisterLocked(null, true);
8961
8962        return timedout;
8963    }
8964
8965    public final void activitySlept(IBinder token) {
8966        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8967
8968        final long origId = Binder.clearCallingIdentity();
8969
8970        synchronized (this) {
8971            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8972            if (r != null) {
8973                mStackSupervisor.activitySleptLocked(r);
8974            }
8975        }
8976
8977        Binder.restoreCallingIdentity(origId);
8978    }
8979
8980    void logLockScreen(String msg) {
8981        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8982                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8983                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8984                mStackSupervisor.mDismissKeyguardOnNextActivity);
8985    }
8986
8987    private void comeOutOfSleepIfNeededLocked() {
8988        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8989            if (mSleeping) {
8990                mSleeping = false;
8991                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8992            }
8993        }
8994    }
8995
8996    void wakingUp() {
8997        synchronized(this) {
8998            mWentToSleep = false;
8999            updateEventDispatchingLocked();
9000            comeOutOfSleepIfNeededLocked();
9001        }
9002    }
9003
9004    void startRunningVoiceLocked() {
9005        if (!mRunningVoice) {
9006            mRunningVoice = true;
9007            comeOutOfSleepIfNeededLocked();
9008        }
9009    }
9010
9011    private void updateEventDispatchingLocked() {
9012        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9013    }
9014
9015    public void setLockScreenShown(boolean shown) {
9016        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9017                != PackageManager.PERMISSION_GRANTED) {
9018            throw new SecurityException("Requires permission "
9019                    + android.Manifest.permission.DEVICE_POWER);
9020        }
9021
9022        synchronized(this) {
9023            long ident = Binder.clearCallingIdentity();
9024            try {
9025                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9026                mLockScreenShown = shown;
9027                comeOutOfSleepIfNeededLocked();
9028            } finally {
9029                Binder.restoreCallingIdentity(ident);
9030            }
9031        }
9032    }
9033
9034    public void stopAppSwitches() {
9035        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9036                != PackageManager.PERMISSION_GRANTED) {
9037            throw new SecurityException("Requires permission "
9038                    + android.Manifest.permission.STOP_APP_SWITCHES);
9039        }
9040
9041        synchronized(this) {
9042            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9043                    + APP_SWITCH_DELAY_TIME;
9044            mDidAppSwitch = false;
9045            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9046            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9047            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9048        }
9049    }
9050
9051    public void resumeAppSwitches() {
9052        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9053                != PackageManager.PERMISSION_GRANTED) {
9054            throw new SecurityException("Requires permission "
9055                    + android.Manifest.permission.STOP_APP_SWITCHES);
9056        }
9057
9058        synchronized(this) {
9059            // Note that we don't execute any pending app switches... we will
9060            // let those wait until either the timeout, or the next start
9061            // activity request.
9062            mAppSwitchesAllowedTime = 0;
9063        }
9064    }
9065
9066    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9067            String name) {
9068        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9069            return true;
9070        }
9071
9072        final int perm = checkComponentPermission(
9073                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9074                callingUid, -1, true);
9075        if (perm == PackageManager.PERMISSION_GRANTED) {
9076            return true;
9077        }
9078
9079        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9080        return false;
9081    }
9082
9083    public void setDebugApp(String packageName, boolean waitForDebugger,
9084            boolean persistent) {
9085        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9086                "setDebugApp()");
9087
9088        long ident = Binder.clearCallingIdentity();
9089        try {
9090            // Note that this is not really thread safe if there are multiple
9091            // callers into it at the same time, but that's not a situation we
9092            // care about.
9093            if (persistent) {
9094                final ContentResolver resolver = mContext.getContentResolver();
9095                Settings.Global.putString(
9096                    resolver, Settings.Global.DEBUG_APP,
9097                    packageName);
9098                Settings.Global.putInt(
9099                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9100                    waitForDebugger ? 1 : 0);
9101            }
9102
9103            synchronized (this) {
9104                if (!persistent) {
9105                    mOrigDebugApp = mDebugApp;
9106                    mOrigWaitForDebugger = mWaitForDebugger;
9107                }
9108                mDebugApp = packageName;
9109                mWaitForDebugger = waitForDebugger;
9110                mDebugTransient = !persistent;
9111                if (packageName != null) {
9112                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9113                            false, UserHandle.USER_ALL, "set debug app");
9114                }
9115            }
9116        } finally {
9117            Binder.restoreCallingIdentity(ident);
9118        }
9119    }
9120
9121    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9122        synchronized (this) {
9123            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9124            if (!isDebuggable) {
9125                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9126                    throw new SecurityException("Process not debuggable: " + app.packageName);
9127                }
9128            }
9129
9130            mOpenGlTraceApp = processName;
9131        }
9132    }
9133
9134    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9135            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9136        synchronized (this) {
9137            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9138            if (!isDebuggable) {
9139                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9140                    throw new SecurityException("Process not debuggable: " + app.packageName);
9141                }
9142            }
9143            mProfileApp = processName;
9144            mProfileFile = profileFile;
9145            if (mProfileFd != null) {
9146                try {
9147                    mProfileFd.close();
9148                } catch (IOException e) {
9149                }
9150                mProfileFd = null;
9151            }
9152            mProfileFd = profileFd;
9153            mProfileType = 0;
9154            mAutoStopProfiler = autoStopProfiler;
9155        }
9156    }
9157
9158    @Override
9159    public void setAlwaysFinish(boolean enabled) {
9160        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9161                "setAlwaysFinish()");
9162
9163        Settings.Global.putInt(
9164                mContext.getContentResolver(),
9165                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9166
9167        synchronized (this) {
9168            mAlwaysFinishActivities = enabled;
9169        }
9170    }
9171
9172    @Override
9173    public void setActivityController(IActivityController controller) {
9174        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9175                "setActivityController()");
9176        synchronized (this) {
9177            mController = controller;
9178            Watchdog.getInstance().setActivityController(controller);
9179        }
9180    }
9181
9182    @Override
9183    public void setUserIsMonkey(boolean userIsMonkey) {
9184        synchronized (this) {
9185            synchronized (mPidsSelfLocked) {
9186                final int callingPid = Binder.getCallingPid();
9187                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9188                if (precessRecord == null) {
9189                    throw new SecurityException("Unknown process: " + callingPid);
9190                }
9191                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9192                    throw new SecurityException("Only an instrumentation process "
9193                            + "with a UiAutomation can call setUserIsMonkey");
9194                }
9195            }
9196            mUserIsMonkey = userIsMonkey;
9197        }
9198    }
9199
9200    @Override
9201    public boolean isUserAMonkey() {
9202        synchronized (this) {
9203            // If there is a controller also implies the user is a monkey.
9204            return (mUserIsMonkey || mController != null);
9205        }
9206    }
9207
9208    public void requestBugReport() {
9209        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9210        SystemProperties.set("ctl.start", "bugreport");
9211    }
9212
9213    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9214        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9215    }
9216
9217    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9218        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9219            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9220        }
9221        return KEY_DISPATCHING_TIMEOUT;
9222    }
9223
9224    @Override
9225    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9226        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9227                != PackageManager.PERMISSION_GRANTED) {
9228            throw new SecurityException("Requires permission "
9229                    + android.Manifest.permission.FILTER_EVENTS);
9230        }
9231        ProcessRecord proc;
9232        long timeout;
9233        synchronized (this) {
9234            synchronized (mPidsSelfLocked) {
9235                proc = mPidsSelfLocked.get(pid);
9236            }
9237            timeout = getInputDispatchingTimeoutLocked(proc);
9238        }
9239
9240        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9241            return -1;
9242        }
9243
9244        return timeout;
9245    }
9246
9247    /**
9248     * Handle input dispatching timeouts.
9249     * Returns whether input dispatching should be aborted or not.
9250     */
9251    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9252            final ActivityRecord activity, final ActivityRecord parent,
9253            final boolean aboveSystem, String reason) {
9254        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9255                != PackageManager.PERMISSION_GRANTED) {
9256            throw new SecurityException("Requires permission "
9257                    + android.Manifest.permission.FILTER_EVENTS);
9258        }
9259
9260        final String annotation;
9261        if (reason == null) {
9262            annotation = "Input dispatching timed out";
9263        } else {
9264            annotation = "Input dispatching timed out (" + reason + ")";
9265        }
9266
9267        if (proc != null) {
9268            synchronized (this) {
9269                if (proc.debugging) {
9270                    return false;
9271                }
9272
9273                if (mDidDexOpt) {
9274                    // Give more time since we were dexopting.
9275                    mDidDexOpt = false;
9276                    return false;
9277                }
9278
9279                if (proc.instrumentationClass != null) {
9280                    Bundle info = new Bundle();
9281                    info.putString("shortMsg", "keyDispatchingTimedOut");
9282                    info.putString("longMsg", annotation);
9283                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9284                    return true;
9285                }
9286            }
9287            mHandler.post(new Runnable() {
9288                @Override
9289                public void run() {
9290                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9291                }
9292            });
9293        }
9294
9295        return true;
9296    }
9297
9298    public Bundle getAssistContextExtras(int requestType) {
9299        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9300                "getAssistContextExtras()");
9301        PendingAssistExtras pae;
9302        Bundle extras = new Bundle();
9303        synchronized (this) {
9304            ActivityRecord activity = getFocusedStack().mResumedActivity;
9305            if (activity == null) {
9306                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9307                return null;
9308            }
9309            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9310            if (activity.app == null || activity.app.thread == null) {
9311                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9312                return extras;
9313            }
9314            if (activity.app.pid == Binder.getCallingPid()) {
9315                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9316                return extras;
9317            }
9318            pae = new PendingAssistExtras(activity);
9319            try {
9320                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9321                        requestType);
9322                mPendingAssistExtras.add(pae);
9323                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9324            } catch (RemoteException e) {
9325                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9326                return extras;
9327            }
9328        }
9329        synchronized (pae) {
9330            while (!pae.haveResult) {
9331                try {
9332                    pae.wait();
9333                } catch (InterruptedException e) {
9334                }
9335            }
9336            if (pae.result != null) {
9337                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9338            }
9339        }
9340        synchronized (this) {
9341            mPendingAssistExtras.remove(pae);
9342            mHandler.removeCallbacks(pae);
9343        }
9344        return extras;
9345    }
9346
9347    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9348        PendingAssistExtras pae = (PendingAssistExtras)token;
9349        synchronized (pae) {
9350            pae.result = extras;
9351            pae.haveResult = true;
9352            pae.notifyAll();
9353        }
9354    }
9355
9356    public void registerProcessObserver(IProcessObserver observer) {
9357        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9358                "registerProcessObserver()");
9359        synchronized (this) {
9360            mProcessObservers.register(observer);
9361        }
9362    }
9363
9364    @Override
9365    public void unregisterProcessObserver(IProcessObserver observer) {
9366        synchronized (this) {
9367            mProcessObservers.unregister(observer);
9368        }
9369    }
9370
9371    @Override
9372    public boolean convertFromTranslucent(IBinder token) {
9373        final long origId = Binder.clearCallingIdentity();
9374        try {
9375            synchronized (this) {
9376                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9377                if (r == null) {
9378                    return false;
9379                }
9380                if (r.changeWindowTranslucency(true)) {
9381                    mWindowManager.setAppFullscreen(token, true);
9382                    r.task.stack.releaseMediaResources();
9383                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9384                    return true;
9385                }
9386                return false;
9387            }
9388        } finally {
9389            Binder.restoreCallingIdentity(origId);
9390        }
9391    }
9392
9393    @Override
9394    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9395        final long origId = Binder.clearCallingIdentity();
9396        try {
9397            synchronized (this) {
9398                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9399                if (r == null) {
9400                    return false;
9401                }
9402                if (r.changeWindowTranslucency(false)) {
9403                    r.task.stack.convertToTranslucent(r, options);
9404                    mWindowManager.setAppFullscreen(token, false);
9405                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9406                    return true;
9407                } else {
9408                    r.task.stack.mReturningActivityOptions = options;
9409                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9410                    return false;
9411                }
9412            }
9413        } finally {
9414            Binder.restoreCallingIdentity(origId);
9415        }
9416    }
9417
9418    @Override
9419    public boolean setMediaPlaying(IBinder token, boolean playing) {
9420        final long origId = Binder.clearCallingIdentity();
9421        try {
9422            synchronized (this) {
9423                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9424                if (r != null) {
9425                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9426                }
9427            }
9428            return false;
9429        } finally {
9430            Binder.restoreCallingIdentity(origId);
9431        }
9432    }
9433
9434    @Override
9435    public boolean isBackgroundMediaPlaying(IBinder token) {
9436        final long origId = Binder.clearCallingIdentity();
9437        try {
9438            synchronized (this) {
9439                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9440                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9441                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9442                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9443                return playing;
9444            }
9445        } finally {
9446            Binder.restoreCallingIdentity(origId);
9447        }
9448    }
9449
9450    @Override
9451    public ActivityOptions getActivityOptions(IBinder token) {
9452        final long origId = Binder.clearCallingIdentity();
9453        try {
9454            synchronized (this) {
9455                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9456                if (r != null) {
9457                    final ActivityOptions activityOptions = r.pendingOptions;
9458                    r.pendingOptions = null;
9459                    return activityOptions;
9460                }
9461                return null;
9462            }
9463        } finally {
9464            Binder.restoreCallingIdentity(origId);
9465        }
9466    }
9467
9468    @Override
9469    public void setImmersive(IBinder token, boolean immersive) {
9470        synchronized(this) {
9471            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9472            if (r == null) {
9473                throw new IllegalArgumentException();
9474            }
9475            r.immersive = immersive;
9476
9477            // update associated state if we're frontmost
9478            if (r == mFocusedActivity) {
9479                if (DEBUG_IMMERSIVE) {
9480                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9481                }
9482                applyUpdateLockStateLocked(r);
9483            }
9484        }
9485    }
9486
9487    @Override
9488    public boolean isImmersive(IBinder token) {
9489        synchronized (this) {
9490            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9491            if (r == null) {
9492                throw new IllegalArgumentException();
9493            }
9494            return r.immersive;
9495        }
9496    }
9497
9498    public boolean isTopActivityImmersive() {
9499        enforceNotIsolatedCaller("startActivity");
9500        synchronized (this) {
9501            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9502            return (r != null) ? r.immersive : false;
9503        }
9504    }
9505
9506    @Override
9507    public boolean isTopOfTask(IBinder token) {
9508        synchronized (this) {
9509            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9510            if (r == null) {
9511                throw new IllegalArgumentException();
9512            }
9513            return r.task.getTopActivity() == r;
9514        }
9515    }
9516
9517    public final void enterSafeMode() {
9518        synchronized(this) {
9519            // It only makes sense to do this before the system is ready
9520            // and started launching other packages.
9521            if (!mSystemReady) {
9522                try {
9523                    AppGlobals.getPackageManager().enterSafeMode();
9524                } catch (RemoteException e) {
9525                }
9526            }
9527
9528            mSafeMode = true;
9529        }
9530    }
9531
9532    public final void showSafeModeOverlay() {
9533        View v = LayoutInflater.from(mContext).inflate(
9534                com.android.internal.R.layout.safe_mode, null);
9535        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9536        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9537        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9538        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9539        lp.gravity = Gravity.BOTTOM | Gravity.START;
9540        lp.format = v.getBackground().getOpacity();
9541        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9542                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9543        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9544        ((WindowManager)mContext.getSystemService(
9545                Context.WINDOW_SERVICE)).addView(v, lp);
9546    }
9547
9548    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9549        if (!(sender instanceof PendingIntentRecord)) {
9550            return;
9551        }
9552        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9553        synchronized (stats) {
9554            if (mBatteryStatsService.isOnBattery()) {
9555                mBatteryStatsService.enforceCallingPermission();
9556                PendingIntentRecord rec = (PendingIntentRecord)sender;
9557                int MY_UID = Binder.getCallingUid();
9558                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9559                BatteryStatsImpl.Uid.Pkg pkg =
9560                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9561                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9562                pkg.incWakeupsLocked();
9563            }
9564        }
9565    }
9566
9567    public boolean killPids(int[] pids, String pReason, boolean secure) {
9568        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9569            throw new SecurityException("killPids only available to the system");
9570        }
9571        String reason = (pReason == null) ? "Unknown" : pReason;
9572        // XXX Note: don't acquire main activity lock here, because the window
9573        // manager calls in with its locks held.
9574
9575        boolean killed = false;
9576        synchronized (mPidsSelfLocked) {
9577            int[] types = new int[pids.length];
9578            int worstType = 0;
9579            for (int i=0; i<pids.length; i++) {
9580                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9581                if (proc != null) {
9582                    int type = proc.setAdj;
9583                    types[i] = type;
9584                    if (type > worstType) {
9585                        worstType = type;
9586                    }
9587                }
9588            }
9589
9590            // If the worst oom_adj is somewhere in the cached proc LRU range,
9591            // then constrain it so we will kill all cached procs.
9592            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9593                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9594                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9595            }
9596
9597            // If this is not a secure call, don't let it kill processes that
9598            // are important.
9599            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9600                worstType = ProcessList.SERVICE_ADJ;
9601            }
9602
9603            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9604            for (int i=0; i<pids.length; i++) {
9605                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9606                if (proc == null) {
9607                    continue;
9608                }
9609                int adj = proc.setAdj;
9610                if (adj >= worstType && !proc.killedByAm) {
9611                    killUnneededProcessLocked(proc, reason);
9612                    killed = true;
9613                }
9614            }
9615        }
9616        return killed;
9617    }
9618
9619    @Override
9620    public void killUid(int uid, String reason) {
9621        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9622            throw new SecurityException("killUid only available to the system");
9623        }
9624        synchronized (this) {
9625            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9626                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9627                    reason != null ? reason : "kill uid");
9628        }
9629    }
9630
9631    @Override
9632    public boolean killProcessesBelowForeground(String reason) {
9633        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9634            throw new SecurityException("killProcessesBelowForeground() only available to system");
9635        }
9636
9637        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9638    }
9639
9640    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9641        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9642            throw new SecurityException("killProcessesBelowAdj() only available to system");
9643        }
9644
9645        boolean killed = false;
9646        synchronized (mPidsSelfLocked) {
9647            final int size = mPidsSelfLocked.size();
9648            for (int i = 0; i < size; i++) {
9649                final int pid = mPidsSelfLocked.keyAt(i);
9650                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9651                if (proc == null) continue;
9652
9653                final int adj = proc.setAdj;
9654                if (adj > belowAdj && !proc.killedByAm) {
9655                    killUnneededProcessLocked(proc, reason);
9656                    killed = true;
9657                }
9658            }
9659        }
9660        return killed;
9661    }
9662
9663    @Override
9664    public void hang(final IBinder who, boolean allowRestart) {
9665        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9666                != PackageManager.PERMISSION_GRANTED) {
9667            throw new SecurityException("Requires permission "
9668                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9669        }
9670
9671        final IBinder.DeathRecipient death = new DeathRecipient() {
9672            @Override
9673            public void binderDied() {
9674                synchronized (this) {
9675                    notifyAll();
9676                }
9677            }
9678        };
9679
9680        try {
9681            who.linkToDeath(death, 0);
9682        } catch (RemoteException e) {
9683            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9684            return;
9685        }
9686
9687        synchronized (this) {
9688            Watchdog.getInstance().setAllowRestart(allowRestart);
9689            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9690            synchronized (death) {
9691                while (who.isBinderAlive()) {
9692                    try {
9693                        death.wait();
9694                    } catch (InterruptedException e) {
9695                    }
9696                }
9697            }
9698            Watchdog.getInstance().setAllowRestart(true);
9699        }
9700    }
9701
9702    @Override
9703    public void restart() {
9704        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9705                != PackageManager.PERMISSION_GRANTED) {
9706            throw new SecurityException("Requires permission "
9707                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9708        }
9709
9710        Log.i(TAG, "Sending shutdown broadcast...");
9711
9712        BroadcastReceiver br = new BroadcastReceiver() {
9713            @Override public void onReceive(Context context, Intent intent) {
9714                // Now the broadcast is done, finish up the low-level shutdown.
9715                Log.i(TAG, "Shutting down activity manager...");
9716                shutdown(10000);
9717                Log.i(TAG, "Shutdown complete, restarting!");
9718                Process.killProcess(Process.myPid());
9719                System.exit(10);
9720            }
9721        };
9722
9723        // First send the high-level shut down broadcast.
9724        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9725        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9726        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9727        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9728        mContext.sendOrderedBroadcastAsUser(intent,
9729                UserHandle.ALL, null, br, mHandler, 0, null, null);
9730        */
9731        br.onReceive(mContext, intent);
9732    }
9733
9734    private long getLowRamTimeSinceIdle(long now) {
9735        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9736    }
9737
9738    @Override
9739    public void performIdleMaintenance() {
9740        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9741                != PackageManager.PERMISSION_GRANTED) {
9742            throw new SecurityException("Requires permission "
9743                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9744        }
9745
9746        synchronized (this) {
9747            final long now = SystemClock.uptimeMillis();
9748            final long timeSinceLastIdle = now - mLastIdleTime;
9749            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9750            mLastIdleTime = now;
9751            mLowRamTimeSinceLastIdle = 0;
9752            if (mLowRamStartTime != 0) {
9753                mLowRamStartTime = now;
9754            }
9755
9756            StringBuilder sb = new StringBuilder(128);
9757            sb.append("Idle maintenance over ");
9758            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9759            sb.append(" low RAM for ");
9760            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9761            Slog.i(TAG, sb.toString());
9762
9763            // If at least 1/3 of our time since the last idle period has been spent
9764            // with RAM low, then we want to kill processes.
9765            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9766
9767            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9768                ProcessRecord proc = mLruProcesses.get(i);
9769                if (proc.notCachedSinceIdle) {
9770                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9771                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9772                        if (doKilling && proc.initialIdlePss != 0
9773                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9774                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9775                                    + " from " + proc.initialIdlePss + ")");
9776                        }
9777                    }
9778                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9779                    proc.notCachedSinceIdle = true;
9780                    proc.initialIdlePss = 0;
9781                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9782                            isSleeping(), now);
9783                }
9784            }
9785
9786            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9787            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9788        }
9789    }
9790
9791    private void retrieveSettings() {
9792        final ContentResolver resolver = mContext.getContentResolver();
9793        String debugApp = Settings.Global.getString(
9794            resolver, Settings.Global.DEBUG_APP);
9795        boolean waitForDebugger = Settings.Global.getInt(
9796            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9797        boolean alwaysFinishActivities = Settings.Global.getInt(
9798            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9799        boolean forceRtl = Settings.Global.getInt(
9800                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9801        // Transfer any global setting for forcing RTL layout, into a System Property
9802        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9803
9804        Configuration configuration = new Configuration();
9805        Settings.System.getConfiguration(resolver, configuration);
9806        if (forceRtl) {
9807            // This will take care of setting the correct layout direction flags
9808            configuration.setLayoutDirection(configuration.locale);
9809        }
9810
9811        synchronized (this) {
9812            mDebugApp = mOrigDebugApp = debugApp;
9813            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9814            mAlwaysFinishActivities = alwaysFinishActivities;
9815            // This happens before any activities are started, so we can
9816            // change mConfiguration in-place.
9817            updateConfigurationLocked(configuration, null, false, true);
9818            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9819        }
9820    }
9821
9822    public boolean testIsSystemReady() {
9823        // no need to synchronize(this) just to read & return the value
9824        return mSystemReady;
9825    }
9826
9827    private static File getCalledPreBootReceiversFile() {
9828        File dataDir = Environment.getDataDirectory();
9829        File systemDir = new File(dataDir, "system");
9830        File fname = new File(systemDir, "called_pre_boots.dat");
9831        return fname;
9832    }
9833
9834    static final int LAST_DONE_VERSION = 10000;
9835
9836    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9837        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9838        File file = getCalledPreBootReceiversFile();
9839        FileInputStream fis = null;
9840        try {
9841            fis = new FileInputStream(file);
9842            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9843            int fvers = dis.readInt();
9844            if (fvers == LAST_DONE_VERSION) {
9845                String vers = dis.readUTF();
9846                String codename = dis.readUTF();
9847                String build = dis.readUTF();
9848                if (android.os.Build.VERSION.RELEASE.equals(vers)
9849                        && android.os.Build.VERSION.CODENAME.equals(codename)
9850                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9851                    int num = dis.readInt();
9852                    while (num > 0) {
9853                        num--;
9854                        String pkg = dis.readUTF();
9855                        String cls = dis.readUTF();
9856                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9857                    }
9858                }
9859            }
9860        } catch (FileNotFoundException e) {
9861        } catch (IOException e) {
9862            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9863        } finally {
9864            if (fis != null) {
9865                try {
9866                    fis.close();
9867                } catch (IOException e) {
9868                }
9869            }
9870        }
9871        return lastDoneReceivers;
9872    }
9873
9874    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9875        File file = getCalledPreBootReceiversFile();
9876        FileOutputStream fos = null;
9877        DataOutputStream dos = null;
9878        try {
9879            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9880            fos = new FileOutputStream(file);
9881            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9882            dos.writeInt(LAST_DONE_VERSION);
9883            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9884            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9885            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9886            dos.writeInt(list.size());
9887            for (int i=0; i<list.size(); i++) {
9888                dos.writeUTF(list.get(i).getPackageName());
9889                dos.writeUTF(list.get(i).getClassName());
9890            }
9891        } catch (IOException e) {
9892            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9893            file.delete();
9894        } finally {
9895            FileUtils.sync(fos);
9896            if (dos != null) {
9897                try {
9898                    dos.close();
9899                } catch (IOException e) {
9900                    // TODO Auto-generated catch block
9901                    e.printStackTrace();
9902                }
9903            }
9904        }
9905    }
9906
9907    public void systemReady(final Runnable goingCallback) {
9908        synchronized(this) {
9909            if (mSystemReady) {
9910                if (goingCallback != null) goingCallback.run();
9911                return;
9912            }
9913
9914            // Make sure we have the current profile info, since it is needed for
9915            // security checks.
9916            updateCurrentProfileIdsLocked();
9917
9918            if (mRecentTasks == null) {
9919                mRecentTasks = mTaskPersister.restoreTasksLocked();
9920                if (!mRecentTasks.isEmpty()) {
9921                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9922                }
9923                mTaskPersister.startPersisting();
9924            }
9925
9926            // Check to see if there are any update receivers to run.
9927            if (!mDidUpdate) {
9928                if (mWaitingUpdate) {
9929                    return;
9930                }
9931                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9932                List<ResolveInfo> ris = null;
9933                try {
9934                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9935                            intent, null, 0, 0);
9936                } catch (RemoteException e) {
9937                }
9938                if (ris != null) {
9939                    for (int i=ris.size()-1; i>=0; i--) {
9940                        if ((ris.get(i).activityInfo.applicationInfo.flags
9941                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9942                            ris.remove(i);
9943                        }
9944                    }
9945                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9946
9947                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9948
9949                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9950                    for (int i=0; i<ris.size(); i++) {
9951                        ActivityInfo ai = ris.get(i).activityInfo;
9952                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9953                        if (lastDoneReceivers.contains(comp)) {
9954                            // We already did the pre boot receiver for this app with the current
9955                            // platform version, so don't do it again...
9956                            ris.remove(i);
9957                            i--;
9958                            // ...however, do keep it as one that has been done, so we don't
9959                            // forget about it when rewriting the file of last done receivers.
9960                            doneReceivers.add(comp);
9961                        }
9962                    }
9963
9964                    final int[] users = getUsersLocked();
9965                    for (int i=0; i<ris.size(); i++) {
9966                        ActivityInfo ai = ris.get(i).activityInfo;
9967                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9968                        doneReceivers.add(comp);
9969                        intent.setComponent(comp);
9970                        for (int j=0; j<users.length; j++) {
9971                            IIntentReceiver finisher = null;
9972                            if (i == ris.size()-1 && j == users.length-1) {
9973                                finisher = new IIntentReceiver.Stub() {
9974                                    public void performReceive(Intent intent, int resultCode,
9975                                            String data, Bundle extras, boolean ordered,
9976                                            boolean sticky, int sendingUser) {
9977                                        // The raw IIntentReceiver interface is called
9978                                        // with the AM lock held, so redispatch to
9979                                        // execute our code without the lock.
9980                                        mHandler.post(new Runnable() {
9981                                            public void run() {
9982                                                synchronized (ActivityManagerService.this) {
9983                                                    mDidUpdate = true;
9984                                                }
9985                                                writeLastDonePreBootReceivers(doneReceivers);
9986                                                showBootMessage(mContext.getText(
9987                                                        R.string.android_upgrading_complete),
9988                                                        false);
9989                                                systemReady(goingCallback);
9990                                            }
9991                                        });
9992                                    }
9993                                };
9994                            }
9995                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9996                                    + " for user " + users[j]);
9997                            broadcastIntentLocked(null, null, intent, null, finisher,
9998                                    0, null, null, null, AppOpsManager.OP_NONE,
9999                                    true, false, MY_PID, Process.SYSTEM_UID,
10000                                    users[j]);
10001                            if (finisher != null) {
10002                                mWaitingUpdate = true;
10003                            }
10004                        }
10005                    }
10006                }
10007                if (mWaitingUpdate) {
10008                    return;
10009                }
10010                mDidUpdate = true;
10011            }
10012
10013            mAppOpsService.systemReady();
10014            mUsageStatsService.systemReady();
10015            mSystemReady = true;
10016        }
10017
10018        ArrayList<ProcessRecord> procsToKill = null;
10019        synchronized(mPidsSelfLocked) {
10020            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10021                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10022                if (!isAllowedWhileBooting(proc.info)){
10023                    if (procsToKill == null) {
10024                        procsToKill = new ArrayList<ProcessRecord>();
10025                    }
10026                    procsToKill.add(proc);
10027                }
10028            }
10029        }
10030
10031        synchronized(this) {
10032            if (procsToKill != null) {
10033                for (int i=procsToKill.size()-1; i>=0; i--) {
10034                    ProcessRecord proc = procsToKill.get(i);
10035                    Slog.i(TAG, "Removing system update proc: " + proc);
10036                    removeProcessLocked(proc, true, false, "system update done");
10037                }
10038            }
10039
10040            // Now that we have cleaned up any update processes, we
10041            // are ready to start launching real processes and know that
10042            // we won't trample on them any more.
10043            mProcessesReady = true;
10044        }
10045
10046        Slog.i(TAG, "System now ready");
10047        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10048            SystemClock.uptimeMillis());
10049
10050        synchronized(this) {
10051            // Make sure we have no pre-ready processes sitting around.
10052
10053            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10054                ResolveInfo ri = mContext.getPackageManager()
10055                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10056                                STOCK_PM_FLAGS);
10057                CharSequence errorMsg = null;
10058                if (ri != null) {
10059                    ActivityInfo ai = ri.activityInfo;
10060                    ApplicationInfo app = ai.applicationInfo;
10061                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10062                        mTopAction = Intent.ACTION_FACTORY_TEST;
10063                        mTopData = null;
10064                        mTopComponent = new ComponentName(app.packageName,
10065                                ai.name);
10066                    } else {
10067                        errorMsg = mContext.getResources().getText(
10068                                com.android.internal.R.string.factorytest_not_system);
10069                    }
10070                } else {
10071                    errorMsg = mContext.getResources().getText(
10072                            com.android.internal.R.string.factorytest_no_action);
10073                }
10074                if (errorMsg != null) {
10075                    mTopAction = null;
10076                    mTopData = null;
10077                    mTopComponent = null;
10078                    Message msg = Message.obtain();
10079                    msg.what = SHOW_FACTORY_ERROR_MSG;
10080                    msg.getData().putCharSequence("msg", errorMsg);
10081                    mHandler.sendMessage(msg);
10082                }
10083            }
10084        }
10085
10086        retrieveSettings();
10087
10088        synchronized (this) {
10089            readGrantedUriPermissionsLocked();
10090        }
10091
10092        if (goingCallback != null) goingCallback.run();
10093
10094        mSystemServiceManager.startUser(mCurrentUserId);
10095
10096        synchronized (this) {
10097            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10098                try {
10099                    List apps = AppGlobals.getPackageManager().
10100                        getPersistentApplications(STOCK_PM_FLAGS);
10101                    if (apps != null) {
10102                        int N = apps.size();
10103                        int i;
10104                        for (i=0; i<N; i++) {
10105                            ApplicationInfo info
10106                                = (ApplicationInfo)apps.get(i);
10107                            if (info != null &&
10108                                    !info.packageName.equals("android")) {
10109                                addAppLocked(info, false, null /* ABI override */);
10110                            }
10111                        }
10112                    }
10113                } catch (RemoteException ex) {
10114                    // pm is in same process, this will never happen.
10115                }
10116            }
10117
10118            // Start up initial activity.
10119            mBooting = true;
10120
10121            try {
10122                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10123                    Message msg = Message.obtain();
10124                    msg.what = SHOW_UID_ERROR_MSG;
10125                    mHandler.sendMessage(msg);
10126                }
10127            } catch (RemoteException e) {
10128            }
10129
10130            long ident = Binder.clearCallingIdentity();
10131            try {
10132                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10133                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10134                        | Intent.FLAG_RECEIVER_FOREGROUND);
10135                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10136                broadcastIntentLocked(null, null, intent,
10137                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10138                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10139                intent = new Intent(Intent.ACTION_USER_STARTING);
10140                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10141                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10142                broadcastIntentLocked(null, null, intent,
10143                        null, new IIntentReceiver.Stub() {
10144                            @Override
10145                            public void performReceive(Intent intent, int resultCode, String data,
10146                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10147                                    throws RemoteException {
10148                            }
10149                        }, 0, null, null,
10150                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10151                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10152            } catch (Throwable t) {
10153                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10154            } finally {
10155                Binder.restoreCallingIdentity(ident);
10156            }
10157            mStackSupervisor.resumeTopActivitiesLocked();
10158            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10159        }
10160    }
10161
10162    private boolean makeAppCrashingLocked(ProcessRecord app,
10163            String shortMsg, String longMsg, String stackTrace) {
10164        app.crashing = true;
10165        app.crashingReport = generateProcessError(app,
10166                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10167        startAppProblemLocked(app);
10168        app.stopFreezingAllLocked();
10169        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10170    }
10171
10172    private void makeAppNotRespondingLocked(ProcessRecord app,
10173            String activity, String shortMsg, String longMsg) {
10174        app.notResponding = true;
10175        app.notRespondingReport = generateProcessError(app,
10176                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10177                activity, shortMsg, longMsg, null);
10178        startAppProblemLocked(app);
10179        app.stopFreezingAllLocked();
10180    }
10181
10182    /**
10183     * Generate a process error record, suitable for attachment to a ProcessRecord.
10184     *
10185     * @param app The ProcessRecord in which the error occurred.
10186     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10187     *                      ActivityManager.AppErrorStateInfo
10188     * @param activity The activity associated with the crash, if known.
10189     * @param shortMsg Short message describing the crash.
10190     * @param longMsg Long message describing the crash.
10191     * @param stackTrace Full crash stack trace, may be null.
10192     *
10193     * @return Returns a fully-formed AppErrorStateInfo record.
10194     */
10195    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10196            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10197        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10198
10199        report.condition = condition;
10200        report.processName = app.processName;
10201        report.pid = app.pid;
10202        report.uid = app.info.uid;
10203        report.tag = activity;
10204        report.shortMsg = shortMsg;
10205        report.longMsg = longMsg;
10206        report.stackTrace = stackTrace;
10207
10208        return report;
10209    }
10210
10211    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10212        synchronized (this) {
10213            app.crashing = false;
10214            app.crashingReport = null;
10215            app.notResponding = false;
10216            app.notRespondingReport = null;
10217            if (app.anrDialog == fromDialog) {
10218                app.anrDialog = null;
10219            }
10220            if (app.waitDialog == fromDialog) {
10221                app.waitDialog = null;
10222            }
10223            if (app.pid > 0 && app.pid != MY_PID) {
10224                handleAppCrashLocked(app, null, null, null);
10225                killUnneededProcessLocked(app, "user request after error");
10226            }
10227        }
10228    }
10229
10230    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10231            String stackTrace) {
10232        long now = SystemClock.uptimeMillis();
10233
10234        Long crashTime;
10235        if (!app.isolated) {
10236            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10237        } else {
10238            crashTime = null;
10239        }
10240        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10241            // This process loses!
10242            Slog.w(TAG, "Process " + app.info.processName
10243                    + " has crashed too many times: killing!");
10244            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10245                    app.userId, app.info.processName, app.uid);
10246            mStackSupervisor.handleAppCrashLocked(app);
10247            if (!app.persistent) {
10248                // We don't want to start this process again until the user
10249                // explicitly does so...  but for persistent process, we really
10250                // need to keep it running.  If a persistent process is actually
10251                // repeatedly crashing, then badness for everyone.
10252                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10253                        app.info.processName);
10254                if (!app.isolated) {
10255                    // XXX We don't have a way to mark isolated processes
10256                    // as bad, since they don't have a peristent identity.
10257                    mBadProcesses.put(app.info.processName, app.uid,
10258                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10259                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10260                }
10261                app.bad = true;
10262                app.removed = true;
10263                // Don't let services in this process be restarted and potentially
10264                // annoy the user repeatedly.  Unless it is persistent, since those
10265                // processes run critical code.
10266                removeProcessLocked(app, false, false, "crash");
10267                mStackSupervisor.resumeTopActivitiesLocked();
10268                return false;
10269            }
10270            mStackSupervisor.resumeTopActivitiesLocked();
10271        } else {
10272            mStackSupervisor.finishTopRunningActivityLocked(app);
10273        }
10274
10275        // Bump up the crash count of any services currently running in the proc.
10276        for (int i=app.services.size()-1; i>=0; i--) {
10277            // Any services running in the application need to be placed
10278            // back in the pending list.
10279            ServiceRecord sr = app.services.valueAt(i);
10280            sr.crashCount++;
10281        }
10282
10283        // If the crashing process is what we consider to be the "home process" and it has been
10284        // replaced by a third-party app, clear the package preferred activities from packages
10285        // with a home activity running in the process to prevent a repeatedly crashing app
10286        // from blocking the user to manually clear the list.
10287        final ArrayList<ActivityRecord> activities = app.activities;
10288        if (app == mHomeProcess && activities.size() > 0
10289                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10290            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10291                final ActivityRecord r = activities.get(activityNdx);
10292                if (r.isHomeActivity()) {
10293                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10294                    try {
10295                        ActivityThread.getPackageManager()
10296                                .clearPackagePreferredActivities(r.packageName);
10297                    } catch (RemoteException c) {
10298                        // pm is in same process, this will never happen.
10299                    }
10300                }
10301            }
10302        }
10303
10304        if (!app.isolated) {
10305            // XXX Can't keep track of crash times for isolated processes,
10306            // because they don't have a perisistent identity.
10307            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10308        }
10309
10310        return true;
10311    }
10312
10313    void startAppProblemLocked(ProcessRecord app) {
10314        if (app.userId == mCurrentUserId) {
10315            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10316                    mContext, app.info.packageName, app.info.flags);
10317        } else {
10318            // If this app is not running under the current user, then we
10319            // can't give it a report button because that would require
10320            // launching the report UI under a different user.
10321            app.errorReportReceiver = null;
10322        }
10323        skipCurrentReceiverLocked(app);
10324    }
10325
10326    void skipCurrentReceiverLocked(ProcessRecord app) {
10327        for (BroadcastQueue queue : mBroadcastQueues) {
10328            queue.skipCurrentReceiverLocked(app);
10329        }
10330    }
10331
10332    /**
10333     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10334     * The application process will exit immediately after this call returns.
10335     * @param app object of the crashing app, null for the system server
10336     * @param crashInfo describing the exception
10337     */
10338    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10339        ProcessRecord r = findAppProcess(app, "Crash");
10340        final String processName = app == null ? "system_server"
10341                : (r == null ? "unknown" : r.processName);
10342
10343        handleApplicationCrashInner("crash", r, processName, crashInfo);
10344    }
10345
10346    /* Native crash reporting uses this inner version because it needs to be somewhat
10347     * decoupled from the AM-managed cleanup lifecycle
10348     */
10349    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10350            ApplicationErrorReport.CrashInfo crashInfo) {
10351        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10352                UserHandle.getUserId(Binder.getCallingUid()), processName,
10353                r == null ? -1 : r.info.flags,
10354                crashInfo.exceptionClassName,
10355                crashInfo.exceptionMessage,
10356                crashInfo.throwFileName,
10357                crashInfo.throwLineNumber);
10358
10359        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10360
10361        crashApplication(r, crashInfo);
10362    }
10363
10364    public void handleApplicationStrictModeViolation(
10365            IBinder app,
10366            int violationMask,
10367            StrictMode.ViolationInfo info) {
10368        ProcessRecord r = findAppProcess(app, "StrictMode");
10369        if (r == null) {
10370            return;
10371        }
10372
10373        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10374            Integer stackFingerprint = info.hashCode();
10375            boolean logIt = true;
10376            synchronized (mAlreadyLoggedViolatedStacks) {
10377                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10378                    logIt = false;
10379                    // TODO: sub-sample into EventLog for these, with
10380                    // the info.durationMillis?  Then we'd get
10381                    // the relative pain numbers, without logging all
10382                    // the stack traces repeatedly.  We'd want to do
10383                    // likewise in the client code, which also does
10384                    // dup suppression, before the Binder call.
10385                } else {
10386                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10387                        mAlreadyLoggedViolatedStacks.clear();
10388                    }
10389                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10390                }
10391            }
10392            if (logIt) {
10393                logStrictModeViolationToDropBox(r, info);
10394            }
10395        }
10396
10397        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10398            AppErrorResult result = new AppErrorResult();
10399            synchronized (this) {
10400                final long origId = Binder.clearCallingIdentity();
10401
10402                Message msg = Message.obtain();
10403                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10404                HashMap<String, Object> data = new HashMap<String, Object>();
10405                data.put("result", result);
10406                data.put("app", r);
10407                data.put("violationMask", violationMask);
10408                data.put("info", info);
10409                msg.obj = data;
10410                mHandler.sendMessage(msg);
10411
10412                Binder.restoreCallingIdentity(origId);
10413            }
10414            int res = result.get();
10415            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10416        }
10417    }
10418
10419    // Depending on the policy in effect, there could be a bunch of
10420    // these in quick succession so we try to batch these together to
10421    // minimize disk writes, number of dropbox entries, and maximize
10422    // compression, by having more fewer, larger records.
10423    private void logStrictModeViolationToDropBox(
10424            ProcessRecord process,
10425            StrictMode.ViolationInfo info) {
10426        if (info == null) {
10427            return;
10428        }
10429        final boolean isSystemApp = process == null ||
10430                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10431                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10432        final String processName = process == null ? "unknown" : process.processName;
10433        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10434        final DropBoxManager dbox = (DropBoxManager)
10435                mContext.getSystemService(Context.DROPBOX_SERVICE);
10436
10437        // Exit early if the dropbox isn't configured to accept this report type.
10438        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10439
10440        boolean bufferWasEmpty;
10441        boolean needsFlush;
10442        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10443        synchronized (sb) {
10444            bufferWasEmpty = sb.length() == 0;
10445            appendDropBoxProcessHeaders(process, processName, sb);
10446            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10447            sb.append("System-App: ").append(isSystemApp).append("\n");
10448            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10449            if (info.violationNumThisLoop != 0) {
10450                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10451            }
10452            if (info.numAnimationsRunning != 0) {
10453                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10454            }
10455            if (info.broadcastIntentAction != null) {
10456                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10457            }
10458            if (info.durationMillis != -1) {
10459                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10460            }
10461            if (info.numInstances != -1) {
10462                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10463            }
10464            if (info.tags != null) {
10465                for (String tag : info.tags) {
10466                    sb.append("Span-Tag: ").append(tag).append("\n");
10467                }
10468            }
10469            sb.append("\n");
10470            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10471                sb.append(info.crashInfo.stackTrace);
10472            }
10473            sb.append("\n");
10474
10475            // Only buffer up to ~64k.  Various logging bits truncate
10476            // things at 128k.
10477            needsFlush = (sb.length() > 64 * 1024);
10478        }
10479
10480        // Flush immediately if the buffer's grown too large, or this
10481        // is a non-system app.  Non-system apps are isolated with a
10482        // different tag & policy and not batched.
10483        //
10484        // Batching is useful during internal testing with
10485        // StrictMode settings turned up high.  Without batching,
10486        // thousands of separate files could be created on boot.
10487        if (!isSystemApp || needsFlush) {
10488            new Thread("Error dump: " + dropboxTag) {
10489                @Override
10490                public void run() {
10491                    String report;
10492                    synchronized (sb) {
10493                        report = sb.toString();
10494                        sb.delete(0, sb.length());
10495                        sb.trimToSize();
10496                    }
10497                    if (report.length() != 0) {
10498                        dbox.addText(dropboxTag, report);
10499                    }
10500                }
10501            }.start();
10502            return;
10503        }
10504
10505        // System app batching:
10506        if (!bufferWasEmpty) {
10507            // An existing dropbox-writing thread is outstanding, so
10508            // we don't need to start it up.  The existing thread will
10509            // catch the buffer appends we just did.
10510            return;
10511        }
10512
10513        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10514        // (After this point, we shouldn't access AMS internal data structures.)
10515        new Thread("Error dump: " + dropboxTag) {
10516            @Override
10517            public void run() {
10518                // 5 second sleep to let stacks arrive and be batched together
10519                try {
10520                    Thread.sleep(5000);  // 5 seconds
10521                } catch (InterruptedException e) {}
10522
10523                String errorReport;
10524                synchronized (mStrictModeBuffer) {
10525                    errorReport = mStrictModeBuffer.toString();
10526                    if (errorReport.length() == 0) {
10527                        return;
10528                    }
10529                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10530                    mStrictModeBuffer.trimToSize();
10531                }
10532                dbox.addText(dropboxTag, errorReport);
10533            }
10534        }.start();
10535    }
10536
10537    /**
10538     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10539     * @param app object of the crashing app, null for the system server
10540     * @param tag reported by the caller
10541     * @param crashInfo describing the context of the error
10542     * @return true if the process should exit immediately (WTF is fatal)
10543     */
10544    public boolean handleApplicationWtf(IBinder app, String tag,
10545            ApplicationErrorReport.CrashInfo crashInfo) {
10546        ProcessRecord r = findAppProcess(app, "WTF");
10547        final String processName = app == null ? "system_server"
10548                : (r == null ? "unknown" : r.processName);
10549
10550        EventLog.writeEvent(EventLogTags.AM_WTF,
10551                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10552                processName,
10553                r == null ? -1 : r.info.flags,
10554                tag, crashInfo.exceptionMessage);
10555
10556        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10557
10558        if (r != null && r.pid != Process.myPid() &&
10559                Settings.Global.getInt(mContext.getContentResolver(),
10560                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10561            crashApplication(r, crashInfo);
10562            return true;
10563        } else {
10564            return false;
10565        }
10566    }
10567
10568    /**
10569     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10570     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10571     */
10572    private ProcessRecord findAppProcess(IBinder app, String reason) {
10573        if (app == null) {
10574            return null;
10575        }
10576
10577        synchronized (this) {
10578            final int NP = mProcessNames.getMap().size();
10579            for (int ip=0; ip<NP; ip++) {
10580                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10581                final int NA = apps.size();
10582                for (int ia=0; ia<NA; ia++) {
10583                    ProcessRecord p = apps.valueAt(ia);
10584                    if (p.thread != null && p.thread.asBinder() == app) {
10585                        return p;
10586                    }
10587                }
10588            }
10589
10590            Slog.w(TAG, "Can't find mystery application for " + reason
10591                    + " from pid=" + Binder.getCallingPid()
10592                    + " uid=" + Binder.getCallingUid() + ": " + app);
10593            return null;
10594        }
10595    }
10596
10597    /**
10598     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10599     * to append various headers to the dropbox log text.
10600     */
10601    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10602            StringBuilder sb) {
10603        // Watchdog thread ends up invoking this function (with
10604        // a null ProcessRecord) to add the stack file to dropbox.
10605        // Do not acquire a lock on this (am) in such cases, as it
10606        // could cause a potential deadlock, if and when watchdog
10607        // is invoked due to unavailability of lock on am and it
10608        // would prevent watchdog from killing system_server.
10609        if (process == null) {
10610            sb.append("Process: ").append(processName).append("\n");
10611            return;
10612        }
10613        // Note: ProcessRecord 'process' is guarded by the service
10614        // instance.  (notably process.pkgList, which could otherwise change
10615        // concurrently during execution of this method)
10616        synchronized (this) {
10617            sb.append("Process: ").append(processName).append("\n");
10618            int flags = process.info.flags;
10619            IPackageManager pm = AppGlobals.getPackageManager();
10620            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10621            for (int ip=0; ip<process.pkgList.size(); ip++) {
10622                String pkg = process.pkgList.keyAt(ip);
10623                sb.append("Package: ").append(pkg);
10624                try {
10625                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10626                    if (pi != null) {
10627                        sb.append(" v").append(pi.versionCode);
10628                        if (pi.versionName != null) {
10629                            sb.append(" (").append(pi.versionName).append(")");
10630                        }
10631                    }
10632                } catch (RemoteException e) {
10633                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10634                }
10635                sb.append("\n");
10636            }
10637        }
10638    }
10639
10640    private static String processClass(ProcessRecord process) {
10641        if (process == null || process.pid == MY_PID) {
10642            return "system_server";
10643        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10644            return "system_app";
10645        } else {
10646            return "data_app";
10647        }
10648    }
10649
10650    /**
10651     * Write a description of an error (crash, WTF, ANR) to the drop box.
10652     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10653     * @param process which caused the error, null means the system server
10654     * @param activity which triggered the error, null if unknown
10655     * @param parent activity related to the error, null if unknown
10656     * @param subject line related to the error, null if absent
10657     * @param report in long form describing the error, null if absent
10658     * @param logFile to include in the report, null if none
10659     * @param crashInfo giving an application stack trace, null if absent
10660     */
10661    public void addErrorToDropBox(String eventType,
10662            ProcessRecord process, String processName, ActivityRecord activity,
10663            ActivityRecord parent, String subject,
10664            final String report, final File logFile,
10665            final ApplicationErrorReport.CrashInfo crashInfo) {
10666        // NOTE -- this must never acquire the ActivityManagerService lock,
10667        // otherwise the watchdog may be prevented from resetting the system.
10668
10669        final String dropboxTag = processClass(process) + "_" + eventType;
10670        final DropBoxManager dbox = (DropBoxManager)
10671                mContext.getSystemService(Context.DROPBOX_SERVICE);
10672
10673        // Exit early if the dropbox isn't configured to accept this report type.
10674        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10675
10676        final StringBuilder sb = new StringBuilder(1024);
10677        appendDropBoxProcessHeaders(process, processName, sb);
10678        if (activity != null) {
10679            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10680        }
10681        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10682            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10683        }
10684        if (parent != null && parent != activity) {
10685            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10686        }
10687        if (subject != null) {
10688            sb.append("Subject: ").append(subject).append("\n");
10689        }
10690        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10691        if (Debug.isDebuggerConnected()) {
10692            sb.append("Debugger: Connected\n");
10693        }
10694        sb.append("\n");
10695
10696        // Do the rest in a worker thread to avoid blocking the caller on I/O
10697        // (After this point, we shouldn't access AMS internal data structures.)
10698        Thread worker = new Thread("Error dump: " + dropboxTag) {
10699            @Override
10700            public void run() {
10701                if (report != null) {
10702                    sb.append(report);
10703                }
10704                if (logFile != null) {
10705                    try {
10706                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10707                                    "\n\n[[TRUNCATED]]"));
10708                    } catch (IOException e) {
10709                        Slog.e(TAG, "Error reading " + logFile, e);
10710                    }
10711                }
10712                if (crashInfo != null && crashInfo.stackTrace != null) {
10713                    sb.append(crashInfo.stackTrace);
10714                }
10715
10716                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10717                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10718                if (lines > 0) {
10719                    sb.append("\n");
10720
10721                    // Merge several logcat streams, and take the last N lines
10722                    InputStreamReader input = null;
10723                    try {
10724                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10725                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10726                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10727
10728                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10729                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10730                        input = new InputStreamReader(logcat.getInputStream());
10731
10732                        int num;
10733                        char[] buf = new char[8192];
10734                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10735                    } catch (IOException e) {
10736                        Slog.e(TAG, "Error running logcat", e);
10737                    } finally {
10738                        if (input != null) try { input.close(); } catch (IOException e) {}
10739                    }
10740                }
10741
10742                dbox.addText(dropboxTag, sb.toString());
10743            }
10744        };
10745
10746        if (process == null) {
10747            // If process is null, we are being called from some internal code
10748            // and may be about to die -- run this synchronously.
10749            worker.run();
10750        } else {
10751            worker.start();
10752        }
10753    }
10754
10755    /**
10756     * Bring up the "unexpected error" dialog box for a crashing app.
10757     * Deal with edge cases (intercepts from instrumented applications,
10758     * ActivityController, error intent receivers, that sort of thing).
10759     * @param r the application crashing
10760     * @param crashInfo describing the failure
10761     */
10762    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10763        long timeMillis = System.currentTimeMillis();
10764        String shortMsg = crashInfo.exceptionClassName;
10765        String longMsg = crashInfo.exceptionMessage;
10766        String stackTrace = crashInfo.stackTrace;
10767        if (shortMsg != null && longMsg != null) {
10768            longMsg = shortMsg + ": " + longMsg;
10769        } else if (shortMsg != null) {
10770            longMsg = shortMsg;
10771        }
10772
10773        AppErrorResult result = new AppErrorResult();
10774        synchronized (this) {
10775            if (mController != null) {
10776                try {
10777                    String name = r != null ? r.processName : null;
10778                    int pid = r != null ? r.pid : Binder.getCallingPid();
10779                    if (!mController.appCrashed(name, pid,
10780                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10781                        Slog.w(TAG, "Force-killing crashed app " + name
10782                                + " at watcher's request");
10783                        Process.killProcess(pid);
10784                        return;
10785                    }
10786                } catch (RemoteException e) {
10787                    mController = null;
10788                    Watchdog.getInstance().setActivityController(null);
10789                }
10790            }
10791
10792            final long origId = Binder.clearCallingIdentity();
10793
10794            // If this process is running instrumentation, finish it.
10795            if (r != null && r.instrumentationClass != null) {
10796                Slog.w(TAG, "Error in app " + r.processName
10797                      + " running instrumentation " + r.instrumentationClass + ":");
10798                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10799                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10800                Bundle info = new Bundle();
10801                info.putString("shortMsg", shortMsg);
10802                info.putString("longMsg", longMsg);
10803                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10804                Binder.restoreCallingIdentity(origId);
10805                return;
10806            }
10807
10808            // If we can't identify the process or it's already exceeded its crash quota,
10809            // quit right away without showing a crash dialog.
10810            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10811                Binder.restoreCallingIdentity(origId);
10812                return;
10813            }
10814
10815            Message msg = Message.obtain();
10816            msg.what = SHOW_ERROR_MSG;
10817            HashMap data = new HashMap();
10818            data.put("result", result);
10819            data.put("app", r);
10820            msg.obj = data;
10821            mHandler.sendMessage(msg);
10822
10823            Binder.restoreCallingIdentity(origId);
10824        }
10825
10826        int res = result.get();
10827
10828        Intent appErrorIntent = null;
10829        synchronized (this) {
10830            if (r != null && !r.isolated) {
10831                // XXX Can't keep track of crash time for isolated processes,
10832                // since they don't have a persistent identity.
10833                mProcessCrashTimes.put(r.info.processName, r.uid,
10834                        SystemClock.uptimeMillis());
10835            }
10836            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10837                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10838            }
10839        }
10840
10841        if (appErrorIntent != null) {
10842            try {
10843                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10844            } catch (ActivityNotFoundException e) {
10845                Slog.w(TAG, "bug report receiver dissappeared", e);
10846            }
10847        }
10848    }
10849
10850    Intent createAppErrorIntentLocked(ProcessRecord r,
10851            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10852        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10853        if (report == null) {
10854            return null;
10855        }
10856        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10857        result.setComponent(r.errorReportReceiver);
10858        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10859        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10860        return result;
10861    }
10862
10863    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10864            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10865        if (r.errorReportReceiver == null) {
10866            return null;
10867        }
10868
10869        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10870            return null;
10871        }
10872
10873        ApplicationErrorReport report = new ApplicationErrorReport();
10874        report.packageName = r.info.packageName;
10875        report.installerPackageName = r.errorReportReceiver.getPackageName();
10876        report.processName = r.processName;
10877        report.time = timeMillis;
10878        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10879
10880        if (r.crashing || r.forceCrashReport) {
10881            report.type = ApplicationErrorReport.TYPE_CRASH;
10882            report.crashInfo = crashInfo;
10883        } else if (r.notResponding) {
10884            report.type = ApplicationErrorReport.TYPE_ANR;
10885            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10886
10887            report.anrInfo.activity = r.notRespondingReport.tag;
10888            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10889            report.anrInfo.info = r.notRespondingReport.longMsg;
10890        }
10891
10892        return report;
10893    }
10894
10895    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10896        enforceNotIsolatedCaller("getProcessesInErrorState");
10897        // assume our apps are happy - lazy create the list
10898        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10899
10900        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10901                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10902        int userId = UserHandle.getUserId(Binder.getCallingUid());
10903
10904        synchronized (this) {
10905
10906            // iterate across all processes
10907            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10908                ProcessRecord app = mLruProcesses.get(i);
10909                if (!allUsers && app.userId != userId) {
10910                    continue;
10911                }
10912                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10913                    // This one's in trouble, so we'll generate a report for it
10914                    // crashes are higher priority (in case there's a crash *and* an anr)
10915                    ActivityManager.ProcessErrorStateInfo report = null;
10916                    if (app.crashing) {
10917                        report = app.crashingReport;
10918                    } else if (app.notResponding) {
10919                        report = app.notRespondingReport;
10920                    }
10921
10922                    if (report != null) {
10923                        if (errList == null) {
10924                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10925                        }
10926                        errList.add(report);
10927                    } else {
10928                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10929                                " crashing = " + app.crashing +
10930                                " notResponding = " + app.notResponding);
10931                    }
10932                }
10933            }
10934        }
10935
10936        return errList;
10937    }
10938
10939    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10940        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10941            if (currApp != null) {
10942                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10943            }
10944            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10945        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10946            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10947        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10948            if (currApp != null) {
10949                currApp.lru = 0;
10950            }
10951            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10952        } else if (adj >= ProcessList.SERVICE_ADJ) {
10953            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10954        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10955            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10956        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10957            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10958        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10959            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10960        } else {
10961            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10962        }
10963    }
10964
10965    private void fillInProcMemInfo(ProcessRecord app,
10966            ActivityManager.RunningAppProcessInfo outInfo) {
10967        outInfo.pid = app.pid;
10968        outInfo.uid = app.info.uid;
10969        if (mHeavyWeightProcess == app) {
10970            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10971        }
10972        if (app.persistent) {
10973            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10974        }
10975        if (app.activities.size() > 0) {
10976            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10977        }
10978        outInfo.lastTrimLevel = app.trimMemoryLevel;
10979        int adj = app.curAdj;
10980        outInfo.importance = oomAdjToImportance(adj, outInfo);
10981        outInfo.importanceReasonCode = app.adjTypeCode;
10982        outInfo.processState = app.curProcState;
10983    }
10984
10985    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10986        enforceNotIsolatedCaller("getRunningAppProcesses");
10987        // Lazy instantiation of list
10988        List<ActivityManager.RunningAppProcessInfo> runList = null;
10989        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10990                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10991        int userId = UserHandle.getUserId(Binder.getCallingUid());
10992        synchronized (this) {
10993            // Iterate across all processes
10994            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10995                ProcessRecord app = mLruProcesses.get(i);
10996                if (!allUsers && app.userId != userId) {
10997                    continue;
10998                }
10999                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11000                    // Generate process state info for running application
11001                    ActivityManager.RunningAppProcessInfo currApp =
11002                        new ActivityManager.RunningAppProcessInfo(app.processName,
11003                                app.pid, app.getPackageList());
11004                    fillInProcMemInfo(app, currApp);
11005                    if (app.adjSource instanceof ProcessRecord) {
11006                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11007                        currApp.importanceReasonImportance = oomAdjToImportance(
11008                                app.adjSourceOom, null);
11009                    } else if (app.adjSource instanceof ActivityRecord) {
11010                        ActivityRecord r = (ActivityRecord)app.adjSource;
11011                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11012                    }
11013                    if (app.adjTarget instanceof ComponentName) {
11014                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11015                    }
11016                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11017                    //        + " lru=" + currApp.lru);
11018                    if (runList == null) {
11019                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11020                    }
11021                    runList.add(currApp);
11022                }
11023            }
11024        }
11025        return runList;
11026    }
11027
11028    public List<ApplicationInfo> getRunningExternalApplications() {
11029        enforceNotIsolatedCaller("getRunningExternalApplications");
11030        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11031        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11032        if (runningApps != null && runningApps.size() > 0) {
11033            Set<String> extList = new HashSet<String>();
11034            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11035                if (app.pkgList != null) {
11036                    for (String pkg : app.pkgList) {
11037                        extList.add(pkg);
11038                    }
11039                }
11040            }
11041            IPackageManager pm = AppGlobals.getPackageManager();
11042            for (String pkg : extList) {
11043                try {
11044                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11045                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11046                        retList.add(info);
11047                    }
11048                } catch (RemoteException e) {
11049                }
11050            }
11051        }
11052        return retList;
11053    }
11054
11055    @Override
11056    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11057        enforceNotIsolatedCaller("getMyMemoryState");
11058        synchronized (this) {
11059            ProcessRecord proc;
11060            synchronized (mPidsSelfLocked) {
11061                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11062            }
11063            fillInProcMemInfo(proc, outInfo);
11064        }
11065    }
11066
11067    @Override
11068    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11069        if (checkCallingPermission(android.Manifest.permission.DUMP)
11070                != PackageManager.PERMISSION_GRANTED) {
11071            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11072                    + Binder.getCallingPid()
11073                    + ", uid=" + Binder.getCallingUid()
11074                    + " without permission "
11075                    + android.Manifest.permission.DUMP);
11076            return;
11077        }
11078
11079        boolean dumpAll = false;
11080        boolean dumpClient = false;
11081        String dumpPackage = null;
11082
11083        int opti = 0;
11084        while (opti < args.length) {
11085            String opt = args[opti];
11086            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11087                break;
11088            }
11089            opti++;
11090            if ("-a".equals(opt)) {
11091                dumpAll = true;
11092            } else if ("-c".equals(opt)) {
11093                dumpClient = true;
11094            } else if ("-h".equals(opt)) {
11095                pw.println("Activity manager dump options:");
11096                pw.println("  [-a] [-c] [-h] [cmd] ...");
11097                pw.println("  cmd may be one of:");
11098                pw.println("    a[ctivities]: activity stack state");
11099                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11100                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11101                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11102                pw.println("    o[om]: out of memory management");
11103                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11104                pw.println("    provider [COMP_SPEC]: provider client-side state");
11105                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11106                pw.println("    service [COMP_SPEC]: service client-side state");
11107                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11108                pw.println("    all: dump all activities");
11109                pw.println("    top: dump the top activity");
11110                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11111                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11112                pw.println("    a partial substring in a component name, a");
11113                pw.println("    hex object identifier.");
11114                pw.println("  -a: include all available server state.");
11115                pw.println("  -c: include client state.");
11116                return;
11117            } else {
11118                pw.println("Unknown argument: " + opt + "; use -h for help");
11119            }
11120        }
11121
11122        long origId = Binder.clearCallingIdentity();
11123        boolean more = false;
11124        // Is the caller requesting to dump a particular piece of data?
11125        if (opti < args.length) {
11126            String cmd = args[opti];
11127            opti++;
11128            if ("activities".equals(cmd) || "a".equals(cmd)) {
11129                synchronized (this) {
11130                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11131                }
11132            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11133                String[] newArgs;
11134                String name;
11135                if (opti >= args.length) {
11136                    name = null;
11137                    newArgs = EMPTY_STRING_ARRAY;
11138                } else {
11139                    name = args[opti];
11140                    opti++;
11141                    newArgs = new String[args.length - opti];
11142                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11143                            args.length - opti);
11144                }
11145                synchronized (this) {
11146                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11147                }
11148            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11149                String[] newArgs;
11150                String name;
11151                if (opti >= args.length) {
11152                    name = null;
11153                    newArgs = EMPTY_STRING_ARRAY;
11154                } else {
11155                    name = args[opti];
11156                    opti++;
11157                    newArgs = new String[args.length - opti];
11158                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11159                            args.length - opti);
11160                }
11161                synchronized (this) {
11162                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11163                }
11164            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11165                String[] newArgs;
11166                String name;
11167                if (opti >= args.length) {
11168                    name = null;
11169                    newArgs = EMPTY_STRING_ARRAY;
11170                } else {
11171                    name = args[opti];
11172                    opti++;
11173                    newArgs = new String[args.length - opti];
11174                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11175                            args.length - opti);
11176                }
11177                synchronized (this) {
11178                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11179                }
11180            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11181                synchronized (this) {
11182                    dumpOomLocked(fd, pw, args, opti, true);
11183                }
11184            } else if ("provider".equals(cmd)) {
11185                String[] newArgs;
11186                String name;
11187                if (opti >= args.length) {
11188                    name = null;
11189                    newArgs = EMPTY_STRING_ARRAY;
11190                } else {
11191                    name = args[opti];
11192                    opti++;
11193                    newArgs = new String[args.length - opti];
11194                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11195                }
11196                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11197                    pw.println("No providers match: " + name);
11198                    pw.println("Use -h for help.");
11199                }
11200            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11201                synchronized (this) {
11202                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11203                }
11204            } else if ("service".equals(cmd)) {
11205                String[] newArgs;
11206                String name;
11207                if (opti >= args.length) {
11208                    name = null;
11209                    newArgs = EMPTY_STRING_ARRAY;
11210                } else {
11211                    name = args[opti];
11212                    opti++;
11213                    newArgs = new String[args.length - opti];
11214                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11215                            args.length - opti);
11216                }
11217                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11218                    pw.println("No services match: " + name);
11219                    pw.println("Use -h for help.");
11220                }
11221            } else if ("package".equals(cmd)) {
11222                String[] newArgs;
11223                if (opti >= args.length) {
11224                    pw.println("package: no package name specified");
11225                    pw.println("Use -h for help.");
11226                } else {
11227                    dumpPackage = args[opti];
11228                    opti++;
11229                    newArgs = new String[args.length - opti];
11230                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11231                            args.length - opti);
11232                    args = newArgs;
11233                    opti = 0;
11234                    more = true;
11235                }
11236            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11237                synchronized (this) {
11238                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11239                }
11240            } else {
11241                // Dumping a single activity?
11242                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11243                    pw.println("Bad activity command, or no activities match: " + cmd);
11244                    pw.println("Use -h for help.");
11245                }
11246            }
11247            if (!more) {
11248                Binder.restoreCallingIdentity(origId);
11249                return;
11250            }
11251        }
11252
11253        // No piece of data specified, dump everything.
11254        synchronized (this) {
11255            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11256            pw.println();
11257            if (dumpAll) {
11258                pw.println("-------------------------------------------------------------------------------");
11259            }
11260            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11261            pw.println();
11262            if (dumpAll) {
11263                pw.println("-------------------------------------------------------------------------------");
11264            }
11265            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11266            pw.println();
11267            if (dumpAll) {
11268                pw.println("-------------------------------------------------------------------------------");
11269            }
11270            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11271            pw.println();
11272            if (dumpAll) {
11273                pw.println("-------------------------------------------------------------------------------");
11274            }
11275            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11276            pw.println();
11277            if (dumpAll) {
11278                pw.println("-------------------------------------------------------------------------------");
11279            }
11280            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11281        }
11282        Binder.restoreCallingIdentity(origId);
11283    }
11284
11285    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11286            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11287        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11288
11289        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11290                dumpPackage);
11291        boolean needSep = printedAnything;
11292
11293        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11294                dumpPackage, needSep, "  mFocusedActivity: ");
11295        if (printed) {
11296            printedAnything = true;
11297            needSep = false;
11298        }
11299
11300        if (dumpPackage == null) {
11301            if (needSep) {
11302                pw.println();
11303            }
11304            needSep = true;
11305            printedAnything = true;
11306            mStackSupervisor.dump(pw, "  ");
11307        }
11308
11309        if (mRecentTasks.size() > 0) {
11310            boolean printedHeader = false;
11311
11312            final int N = mRecentTasks.size();
11313            for (int i=0; i<N; i++) {
11314                TaskRecord tr = mRecentTasks.get(i);
11315                if (dumpPackage != null) {
11316                    if (tr.realActivity == null ||
11317                            !dumpPackage.equals(tr.realActivity)) {
11318                        continue;
11319                    }
11320                }
11321                if (!printedHeader) {
11322                    if (needSep) {
11323                        pw.println();
11324                    }
11325                    pw.println("  Recent tasks:");
11326                    printedHeader = true;
11327                    printedAnything = true;
11328                }
11329                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11330                        pw.println(tr);
11331                if (dumpAll) {
11332                    mRecentTasks.get(i).dump(pw, "    ");
11333                }
11334            }
11335        }
11336
11337        if (!printedAnything) {
11338            pw.println("  (nothing)");
11339        }
11340    }
11341
11342    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11343            int opti, boolean dumpAll, String dumpPackage) {
11344        boolean needSep = false;
11345        boolean printedAnything = false;
11346        int numPers = 0;
11347
11348        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11349
11350        if (dumpAll) {
11351            final int NP = mProcessNames.getMap().size();
11352            for (int ip=0; ip<NP; ip++) {
11353                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11354                final int NA = procs.size();
11355                for (int ia=0; ia<NA; ia++) {
11356                    ProcessRecord r = procs.valueAt(ia);
11357                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11358                        continue;
11359                    }
11360                    if (!needSep) {
11361                        pw.println("  All known processes:");
11362                        needSep = true;
11363                        printedAnything = true;
11364                    }
11365                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11366                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11367                        pw.print(" "); pw.println(r);
11368                    r.dump(pw, "    ");
11369                    if (r.persistent) {
11370                        numPers++;
11371                    }
11372                }
11373            }
11374        }
11375
11376        if (mIsolatedProcesses.size() > 0) {
11377            boolean printed = false;
11378            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11379                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11380                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11381                    continue;
11382                }
11383                if (!printed) {
11384                    if (needSep) {
11385                        pw.println();
11386                    }
11387                    pw.println("  Isolated process list (sorted by uid):");
11388                    printedAnything = true;
11389                    printed = true;
11390                    needSep = true;
11391                }
11392                pw.println(String.format("%sIsolated #%2d: %s",
11393                        "    ", i, r.toString()));
11394            }
11395        }
11396
11397        if (mLruProcesses.size() > 0) {
11398            if (needSep) {
11399                pw.println();
11400            }
11401            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11402                    pw.print(" total, non-act at ");
11403                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11404                    pw.print(", non-svc at ");
11405                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11406                    pw.println("):");
11407            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11408            needSep = true;
11409            printedAnything = true;
11410        }
11411
11412        if (dumpAll || dumpPackage != null) {
11413            synchronized (mPidsSelfLocked) {
11414                boolean printed = false;
11415                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11416                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11417                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11418                        continue;
11419                    }
11420                    if (!printed) {
11421                        if (needSep) pw.println();
11422                        needSep = true;
11423                        pw.println("  PID mappings:");
11424                        printed = true;
11425                        printedAnything = true;
11426                    }
11427                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11428                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11429                }
11430            }
11431        }
11432
11433        if (mForegroundProcesses.size() > 0) {
11434            synchronized (mPidsSelfLocked) {
11435                boolean printed = false;
11436                for (int i=0; i<mForegroundProcesses.size(); i++) {
11437                    ProcessRecord r = mPidsSelfLocked.get(
11438                            mForegroundProcesses.valueAt(i).pid);
11439                    if (dumpPackage != null && (r == null
11440                            || !r.pkgList.containsKey(dumpPackage))) {
11441                        continue;
11442                    }
11443                    if (!printed) {
11444                        if (needSep) pw.println();
11445                        needSep = true;
11446                        pw.println("  Foreground Processes:");
11447                        printed = true;
11448                        printedAnything = true;
11449                    }
11450                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11451                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11452                }
11453            }
11454        }
11455
11456        if (mPersistentStartingProcesses.size() > 0) {
11457            if (needSep) pw.println();
11458            needSep = true;
11459            printedAnything = true;
11460            pw.println("  Persisent processes that are starting:");
11461            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11462                    "Starting Norm", "Restarting PERS", dumpPackage);
11463        }
11464
11465        if (mRemovedProcesses.size() > 0) {
11466            if (needSep) pw.println();
11467            needSep = true;
11468            printedAnything = true;
11469            pw.println("  Processes that are being removed:");
11470            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11471                    "Removed Norm", "Removed PERS", dumpPackage);
11472        }
11473
11474        if (mProcessesOnHold.size() > 0) {
11475            if (needSep) pw.println();
11476            needSep = true;
11477            printedAnything = true;
11478            pw.println("  Processes that are on old until the system is ready:");
11479            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11480                    "OnHold Norm", "OnHold PERS", dumpPackage);
11481        }
11482
11483        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11484
11485        if (mProcessCrashTimes.getMap().size() > 0) {
11486            boolean printed = false;
11487            long now = SystemClock.uptimeMillis();
11488            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11489            final int NP = pmap.size();
11490            for (int ip=0; ip<NP; ip++) {
11491                String pname = pmap.keyAt(ip);
11492                SparseArray<Long> uids = pmap.valueAt(ip);
11493                final int N = uids.size();
11494                for (int i=0; i<N; i++) {
11495                    int puid = uids.keyAt(i);
11496                    ProcessRecord r = mProcessNames.get(pname, puid);
11497                    if (dumpPackage != null && (r == null
11498                            || !r.pkgList.containsKey(dumpPackage))) {
11499                        continue;
11500                    }
11501                    if (!printed) {
11502                        if (needSep) pw.println();
11503                        needSep = true;
11504                        pw.println("  Time since processes crashed:");
11505                        printed = true;
11506                        printedAnything = true;
11507                    }
11508                    pw.print("    Process "); pw.print(pname);
11509                            pw.print(" uid "); pw.print(puid);
11510                            pw.print(": last crashed ");
11511                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11512                            pw.println(" ago");
11513                }
11514            }
11515        }
11516
11517        if (mBadProcesses.getMap().size() > 0) {
11518            boolean printed = false;
11519            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11520            final int NP = pmap.size();
11521            for (int ip=0; ip<NP; ip++) {
11522                String pname = pmap.keyAt(ip);
11523                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11524                final int N = uids.size();
11525                for (int i=0; i<N; i++) {
11526                    int puid = uids.keyAt(i);
11527                    ProcessRecord r = mProcessNames.get(pname, puid);
11528                    if (dumpPackage != null && (r == null
11529                            || !r.pkgList.containsKey(dumpPackage))) {
11530                        continue;
11531                    }
11532                    if (!printed) {
11533                        if (needSep) pw.println();
11534                        needSep = true;
11535                        pw.println("  Bad processes:");
11536                        printedAnything = true;
11537                    }
11538                    BadProcessInfo info = uids.valueAt(i);
11539                    pw.print("    Bad process "); pw.print(pname);
11540                            pw.print(" uid "); pw.print(puid);
11541                            pw.print(": crashed at time "); pw.println(info.time);
11542                    if (info.shortMsg != null) {
11543                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11544                    }
11545                    if (info.longMsg != null) {
11546                        pw.print("      Long msg: "); pw.println(info.longMsg);
11547                    }
11548                    if (info.stack != null) {
11549                        pw.println("      Stack:");
11550                        int lastPos = 0;
11551                        for (int pos=0; pos<info.stack.length(); pos++) {
11552                            if (info.stack.charAt(pos) == '\n') {
11553                                pw.print("        ");
11554                                pw.write(info.stack, lastPos, pos-lastPos);
11555                                pw.println();
11556                                lastPos = pos+1;
11557                            }
11558                        }
11559                        if (lastPos < info.stack.length()) {
11560                            pw.print("        ");
11561                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11562                            pw.println();
11563                        }
11564                    }
11565                }
11566            }
11567        }
11568
11569        if (dumpPackage == null) {
11570            pw.println();
11571            needSep = false;
11572            pw.println("  mStartedUsers:");
11573            for (int i=0; i<mStartedUsers.size(); i++) {
11574                UserStartedState uss = mStartedUsers.valueAt(i);
11575                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11576                        pw.print(": "); uss.dump("", pw);
11577            }
11578            pw.print("  mStartedUserArray: [");
11579            for (int i=0; i<mStartedUserArray.length; i++) {
11580                if (i > 0) pw.print(", ");
11581                pw.print(mStartedUserArray[i]);
11582            }
11583            pw.println("]");
11584            pw.print("  mUserLru: [");
11585            for (int i=0; i<mUserLru.size(); i++) {
11586                if (i > 0) pw.print(", ");
11587                pw.print(mUserLru.get(i));
11588            }
11589            pw.println("]");
11590            if (dumpAll) {
11591                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11592            }
11593            synchronized (mUserProfileGroupIdsSelfLocked) {
11594                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11595                    pw.println("  mUserProfileGroupIds:");
11596                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11597                        pw.print("    User #");
11598                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11599                        pw.print(" -> profile #");
11600                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11601                    }
11602                }
11603            }
11604        }
11605        if (mHomeProcess != null && (dumpPackage == null
11606                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11607            if (needSep) {
11608                pw.println();
11609                needSep = false;
11610            }
11611            pw.println("  mHomeProcess: " + mHomeProcess);
11612        }
11613        if (mPreviousProcess != null && (dumpPackage == null
11614                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11615            if (needSep) {
11616                pw.println();
11617                needSep = false;
11618            }
11619            pw.println("  mPreviousProcess: " + mPreviousProcess);
11620        }
11621        if (dumpAll) {
11622            StringBuilder sb = new StringBuilder(128);
11623            sb.append("  mPreviousProcessVisibleTime: ");
11624            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11625            pw.println(sb);
11626        }
11627        if (mHeavyWeightProcess != null && (dumpPackage == null
11628                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11629            if (needSep) {
11630                pw.println();
11631                needSep = false;
11632            }
11633            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11634        }
11635        if (dumpPackage == null) {
11636            pw.println("  mConfiguration: " + mConfiguration);
11637        }
11638        if (dumpAll) {
11639            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11640            if (mCompatModePackages.getPackages().size() > 0) {
11641                boolean printed = false;
11642                for (Map.Entry<String, Integer> entry
11643                        : mCompatModePackages.getPackages().entrySet()) {
11644                    String pkg = entry.getKey();
11645                    int mode = entry.getValue();
11646                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11647                        continue;
11648                    }
11649                    if (!printed) {
11650                        pw.println("  mScreenCompatPackages:");
11651                        printed = true;
11652                    }
11653                    pw.print("    "); pw.print(pkg); pw.print(": ");
11654                            pw.print(mode); pw.println();
11655                }
11656            }
11657        }
11658        if (dumpPackage == null) {
11659            if (mSleeping || mWentToSleep || mLockScreenShown) {
11660                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11661                        + " mLockScreenShown " + mLockScreenShown);
11662            }
11663            if (mShuttingDown || mRunningVoice) {
11664                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11665            }
11666        }
11667        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11668                || mOrigWaitForDebugger) {
11669            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11670                    || dumpPackage.equals(mOrigDebugApp)) {
11671                if (needSep) {
11672                    pw.println();
11673                    needSep = false;
11674                }
11675                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11676                        + " mDebugTransient=" + mDebugTransient
11677                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11678            }
11679        }
11680        if (mOpenGlTraceApp != null) {
11681            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11682                if (needSep) {
11683                    pw.println();
11684                    needSep = false;
11685                }
11686                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11687            }
11688        }
11689        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11690                || mProfileFd != null) {
11691            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11692                if (needSep) {
11693                    pw.println();
11694                    needSep = false;
11695                }
11696                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11697                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11698                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11699                        + mAutoStopProfiler);
11700            }
11701        }
11702        if (dumpPackage == null) {
11703            if (mAlwaysFinishActivities || mController != null) {
11704                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11705                        + " mController=" + mController);
11706            }
11707            if (dumpAll) {
11708                pw.println("  Total persistent processes: " + numPers);
11709                pw.println("  mProcessesReady=" + mProcessesReady
11710                        + " mSystemReady=" + mSystemReady);
11711                pw.println("  mBooting=" + mBooting
11712                        + " mBooted=" + mBooted
11713                        + " mFactoryTest=" + mFactoryTest);
11714                pw.print("  mLastPowerCheckRealtime=");
11715                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11716                        pw.println("");
11717                pw.print("  mLastPowerCheckUptime=");
11718                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11719                        pw.println("");
11720                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11721                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11722                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11723                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11724                        + " (" + mLruProcesses.size() + " total)"
11725                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11726                        + " mNumServiceProcs=" + mNumServiceProcs
11727                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11728                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11729                        + " mLastMemoryLevel" + mLastMemoryLevel
11730                        + " mLastNumProcesses" + mLastNumProcesses);
11731                long now = SystemClock.uptimeMillis();
11732                pw.print("  mLastIdleTime=");
11733                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11734                        pw.print(" mLowRamSinceLastIdle=");
11735                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11736                        pw.println();
11737            }
11738        }
11739
11740        if (!printedAnything) {
11741            pw.println("  (nothing)");
11742        }
11743    }
11744
11745    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11746            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11747        if (mProcessesToGc.size() > 0) {
11748            boolean printed = false;
11749            long now = SystemClock.uptimeMillis();
11750            for (int i=0; i<mProcessesToGc.size(); i++) {
11751                ProcessRecord proc = mProcessesToGc.get(i);
11752                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11753                    continue;
11754                }
11755                if (!printed) {
11756                    if (needSep) pw.println();
11757                    needSep = true;
11758                    pw.println("  Processes that are waiting to GC:");
11759                    printed = true;
11760                }
11761                pw.print("    Process "); pw.println(proc);
11762                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11763                        pw.print(", last gced=");
11764                        pw.print(now-proc.lastRequestedGc);
11765                        pw.print(" ms ago, last lowMem=");
11766                        pw.print(now-proc.lastLowMemory);
11767                        pw.println(" ms ago");
11768
11769            }
11770        }
11771        return needSep;
11772    }
11773
11774    void printOomLevel(PrintWriter pw, String name, int adj) {
11775        pw.print("    ");
11776        if (adj >= 0) {
11777            pw.print(' ');
11778            if (adj < 10) pw.print(' ');
11779        } else {
11780            if (adj > -10) pw.print(' ');
11781        }
11782        pw.print(adj);
11783        pw.print(": ");
11784        pw.print(name);
11785        pw.print(" (");
11786        pw.print(mProcessList.getMemLevel(adj)/1024);
11787        pw.println(" kB)");
11788    }
11789
11790    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11791            int opti, boolean dumpAll) {
11792        boolean needSep = false;
11793
11794        if (mLruProcesses.size() > 0) {
11795            if (needSep) pw.println();
11796            needSep = true;
11797            pw.println("  OOM levels:");
11798            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11799            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11800            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11801            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11802            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11803            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11804            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11805            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11806            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11807            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11808            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11809            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11810            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11811
11812            if (needSep) pw.println();
11813            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11814                    pw.print(" total, non-act at ");
11815                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11816                    pw.print(", non-svc at ");
11817                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11818                    pw.println("):");
11819            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11820            needSep = true;
11821        }
11822
11823        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11824
11825        pw.println();
11826        pw.println("  mHomeProcess: " + mHomeProcess);
11827        pw.println("  mPreviousProcess: " + mPreviousProcess);
11828        if (mHeavyWeightProcess != null) {
11829            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11830        }
11831
11832        return true;
11833    }
11834
11835    /**
11836     * There are three ways to call this:
11837     *  - no provider specified: dump all the providers
11838     *  - a flattened component name that matched an existing provider was specified as the
11839     *    first arg: dump that one provider
11840     *  - the first arg isn't the flattened component name of an existing provider:
11841     *    dump all providers whose component contains the first arg as a substring
11842     */
11843    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11844            int opti, boolean dumpAll) {
11845        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11846    }
11847
11848    static class ItemMatcher {
11849        ArrayList<ComponentName> components;
11850        ArrayList<String> strings;
11851        ArrayList<Integer> objects;
11852        boolean all;
11853
11854        ItemMatcher() {
11855            all = true;
11856        }
11857
11858        void build(String name) {
11859            ComponentName componentName = ComponentName.unflattenFromString(name);
11860            if (componentName != null) {
11861                if (components == null) {
11862                    components = new ArrayList<ComponentName>();
11863                }
11864                components.add(componentName);
11865                all = false;
11866            } else {
11867                int objectId = 0;
11868                // Not a '/' separated full component name; maybe an object ID?
11869                try {
11870                    objectId = Integer.parseInt(name, 16);
11871                    if (objects == null) {
11872                        objects = new ArrayList<Integer>();
11873                    }
11874                    objects.add(objectId);
11875                    all = false;
11876                } catch (RuntimeException e) {
11877                    // Not an integer; just do string match.
11878                    if (strings == null) {
11879                        strings = new ArrayList<String>();
11880                    }
11881                    strings.add(name);
11882                    all = false;
11883                }
11884            }
11885        }
11886
11887        int build(String[] args, int opti) {
11888            for (; opti<args.length; opti++) {
11889                String name = args[opti];
11890                if ("--".equals(name)) {
11891                    return opti+1;
11892                }
11893                build(name);
11894            }
11895            return opti;
11896        }
11897
11898        boolean match(Object object, ComponentName comp) {
11899            if (all) {
11900                return true;
11901            }
11902            if (components != null) {
11903                for (int i=0; i<components.size(); i++) {
11904                    if (components.get(i).equals(comp)) {
11905                        return true;
11906                    }
11907                }
11908            }
11909            if (objects != null) {
11910                for (int i=0; i<objects.size(); i++) {
11911                    if (System.identityHashCode(object) == objects.get(i)) {
11912                        return true;
11913                    }
11914                }
11915            }
11916            if (strings != null) {
11917                String flat = comp.flattenToString();
11918                for (int i=0; i<strings.size(); i++) {
11919                    if (flat.contains(strings.get(i))) {
11920                        return true;
11921                    }
11922                }
11923            }
11924            return false;
11925        }
11926    }
11927
11928    /**
11929     * There are three things that cmd can be:
11930     *  - a flattened component name that matches an existing activity
11931     *  - the cmd arg isn't the flattened component name of an existing activity:
11932     *    dump all activity whose component contains the cmd as a substring
11933     *  - A hex number of the ActivityRecord object instance.
11934     */
11935    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11936            int opti, boolean dumpAll) {
11937        ArrayList<ActivityRecord> activities;
11938
11939        synchronized (this) {
11940            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11941        }
11942
11943        if (activities.size() <= 0) {
11944            return false;
11945        }
11946
11947        String[] newArgs = new String[args.length - opti];
11948        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11949
11950        TaskRecord lastTask = null;
11951        boolean needSep = false;
11952        for (int i=activities.size()-1; i>=0; i--) {
11953            ActivityRecord r = activities.get(i);
11954            if (needSep) {
11955                pw.println();
11956            }
11957            needSep = true;
11958            synchronized (this) {
11959                if (lastTask != r.task) {
11960                    lastTask = r.task;
11961                    pw.print("TASK "); pw.print(lastTask.affinity);
11962                            pw.print(" id="); pw.println(lastTask.taskId);
11963                    if (dumpAll) {
11964                        lastTask.dump(pw, "  ");
11965                    }
11966                }
11967            }
11968            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11969        }
11970        return true;
11971    }
11972
11973    /**
11974     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11975     * there is a thread associated with the activity.
11976     */
11977    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11978            final ActivityRecord r, String[] args, boolean dumpAll) {
11979        String innerPrefix = prefix + "  ";
11980        synchronized (this) {
11981            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11982                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11983                    pw.print(" pid=");
11984                    if (r.app != null) pw.println(r.app.pid);
11985                    else pw.println("(not running)");
11986            if (dumpAll) {
11987                r.dump(pw, innerPrefix);
11988            }
11989        }
11990        if (r.app != null && r.app.thread != null) {
11991            // flush anything that is already in the PrintWriter since the thread is going
11992            // to write to the file descriptor directly
11993            pw.flush();
11994            try {
11995                TransferPipe tp = new TransferPipe();
11996                try {
11997                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11998                            r.appToken, innerPrefix, args);
11999                    tp.go(fd);
12000                } finally {
12001                    tp.kill();
12002                }
12003            } catch (IOException e) {
12004                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12005            } catch (RemoteException e) {
12006                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12007            }
12008        }
12009    }
12010
12011    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12012            int opti, boolean dumpAll, String dumpPackage) {
12013        boolean needSep = false;
12014        boolean onlyHistory = false;
12015        boolean printedAnything = false;
12016
12017        if ("history".equals(dumpPackage)) {
12018            if (opti < args.length && "-s".equals(args[opti])) {
12019                dumpAll = false;
12020            }
12021            onlyHistory = true;
12022            dumpPackage = null;
12023        }
12024
12025        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12026        if (!onlyHistory && dumpAll) {
12027            if (mRegisteredReceivers.size() > 0) {
12028                boolean printed = false;
12029                Iterator it = mRegisteredReceivers.values().iterator();
12030                while (it.hasNext()) {
12031                    ReceiverList r = (ReceiverList)it.next();
12032                    if (dumpPackage != null && (r.app == null ||
12033                            !dumpPackage.equals(r.app.info.packageName))) {
12034                        continue;
12035                    }
12036                    if (!printed) {
12037                        pw.println("  Registered Receivers:");
12038                        needSep = true;
12039                        printed = true;
12040                        printedAnything = true;
12041                    }
12042                    pw.print("  * "); pw.println(r);
12043                    r.dump(pw, "    ");
12044                }
12045            }
12046
12047            if (mReceiverResolver.dump(pw, needSep ?
12048                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12049                    "    ", dumpPackage, false)) {
12050                needSep = true;
12051                printedAnything = true;
12052            }
12053        }
12054
12055        for (BroadcastQueue q : mBroadcastQueues) {
12056            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12057            printedAnything |= needSep;
12058        }
12059
12060        needSep = true;
12061
12062        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12063            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12064                if (needSep) {
12065                    pw.println();
12066                }
12067                needSep = true;
12068                printedAnything = true;
12069                pw.print("  Sticky broadcasts for user ");
12070                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12071                StringBuilder sb = new StringBuilder(128);
12072                for (Map.Entry<String, ArrayList<Intent>> ent
12073                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12074                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12075                    if (dumpAll) {
12076                        pw.println(":");
12077                        ArrayList<Intent> intents = ent.getValue();
12078                        final int N = intents.size();
12079                        for (int i=0; i<N; i++) {
12080                            sb.setLength(0);
12081                            sb.append("    Intent: ");
12082                            intents.get(i).toShortString(sb, false, true, false, false);
12083                            pw.println(sb.toString());
12084                            Bundle bundle = intents.get(i).getExtras();
12085                            if (bundle != null) {
12086                                pw.print("      ");
12087                                pw.println(bundle.toString());
12088                            }
12089                        }
12090                    } else {
12091                        pw.println("");
12092                    }
12093                }
12094            }
12095        }
12096
12097        if (!onlyHistory && dumpAll) {
12098            pw.println();
12099            for (BroadcastQueue queue : mBroadcastQueues) {
12100                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12101                        + queue.mBroadcastsScheduled);
12102            }
12103            pw.println("  mHandler:");
12104            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12105            needSep = true;
12106            printedAnything = true;
12107        }
12108
12109        if (!printedAnything) {
12110            pw.println("  (nothing)");
12111        }
12112    }
12113
12114    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12115            int opti, boolean dumpAll, String dumpPackage) {
12116        boolean needSep;
12117        boolean printedAnything = false;
12118
12119        ItemMatcher matcher = new ItemMatcher();
12120        matcher.build(args, opti);
12121
12122        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12123
12124        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12125        printedAnything |= needSep;
12126
12127        if (mLaunchingProviders.size() > 0) {
12128            boolean printed = false;
12129            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12130                ContentProviderRecord r = mLaunchingProviders.get(i);
12131                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12132                    continue;
12133                }
12134                if (!printed) {
12135                    if (needSep) pw.println();
12136                    needSep = true;
12137                    pw.println("  Launching content providers:");
12138                    printed = true;
12139                    printedAnything = true;
12140                }
12141                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12142                        pw.println(r);
12143            }
12144        }
12145
12146        if (mGrantedUriPermissions.size() > 0) {
12147            boolean printed = false;
12148            int dumpUid = -2;
12149            if (dumpPackage != null) {
12150                try {
12151                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12152                } catch (NameNotFoundException e) {
12153                    dumpUid = -1;
12154                }
12155            }
12156            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12157                int uid = mGrantedUriPermissions.keyAt(i);
12158                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12159                    continue;
12160                }
12161                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12162                if (!printed) {
12163                    if (needSep) pw.println();
12164                    needSep = true;
12165                    pw.println("  Granted Uri Permissions:");
12166                    printed = true;
12167                    printedAnything = true;
12168                }
12169                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12170                for (UriPermission perm : perms.values()) {
12171                    pw.print("    "); pw.println(perm);
12172                    if (dumpAll) {
12173                        perm.dump(pw, "      ");
12174                    }
12175                }
12176            }
12177        }
12178
12179        if (!printedAnything) {
12180            pw.println("  (nothing)");
12181        }
12182    }
12183
12184    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12185            int opti, boolean dumpAll, String dumpPackage) {
12186        boolean printed = false;
12187
12188        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12189
12190        if (mIntentSenderRecords.size() > 0) {
12191            Iterator<WeakReference<PendingIntentRecord>> it
12192                    = mIntentSenderRecords.values().iterator();
12193            while (it.hasNext()) {
12194                WeakReference<PendingIntentRecord> ref = it.next();
12195                PendingIntentRecord rec = ref != null ? ref.get(): null;
12196                if (dumpPackage != null && (rec == null
12197                        || !dumpPackage.equals(rec.key.packageName))) {
12198                    continue;
12199                }
12200                printed = true;
12201                if (rec != null) {
12202                    pw.print("  * "); pw.println(rec);
12203                    if (dumpAll) {
12204                        rec.dump(pw, "    ");
12205                    }
12206                } else {
12207                    pw.print("  * "); pw.println(ref);
12208                }
12209            }
12210        }
12211
12212        if (!printed) {
12213            pw.println("  (nothing)");
12214        }
12215    }
12216
12217    private static final int dumpProcessList(PrintWriter pw,
12218            ActivityManagerService service, List list,
12219            String prefix, String normalLabel, String persistentLabel,
12220            String dumpPackage) {
12221        int numPers = 0;
12222        final int N = list.size()-1;
12223        for (int i=N; i>=0; i--) {
12224            ProcessRecord r = (ProcessRecord)list.get(i);
12225            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12226                continue;
12227            }
12228            pw.println(String.format("%s%s #%2d: %s",
12229                    prefix, (r.persistent ? persistentLabel : normalLabel),
12230                    i, r.toString()));
12231            if (r.persistent) {
12232                numPers++;
12233            }
12234        }
12235        return numPers;
12236    }
12237
12238    private static final boolean dumpProcessOomList(PrintWriter pw,
12239            ActivityManagerService service, List<ProcessRecord> origList,
12240            String prefix, String normalLabel, String persistentLabel,
12241            boolean inclDetails, String dumpPackage) {
12242
12243        ArrayList<Pair<ProcessRecord, Integer>> list
12244                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12245        for (int i=0; i<origList.size(); i++) {
12246            ProcessRecord r = origList.get(i);
12247            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12248                continue;
12249            }
12250            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12251        }
12252
12253        if (list.size() <= 0) {
12254            return false;
12255        }
12256
12257        Comparator<Pair<ProcessRecord, Integer>> comparator
12258                = new Comparator<Pair<ProcessRecord, Integer>>() {
12259            @Override
12260            public int compare(Pair<ProcessRecord, Integer> object1,
12261                    Pair<ProcessRecord, Integer> object2) {
12262                if (object1.first.setAdj != object2.first.setAdj) {
12263                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12264                }
12265                if (object1.second.intValue() != object2.second.intValue()) {
12266                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12267                }
12268                return 0;
12269            }
12270        };
12271
12272        Collections.sort(list, comparator);
12273
12274        final long curRealtime = SystemClock.elapsedRealtime();
12275        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12276        final long curUptime = SystemClock.uptimeMillis();
12277        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12278
12279        for (int i=list.size()-1; i>=0; i--) {
12280            ProcessRecord r = list.get(i).first;
12281            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12282            char schedGroup;
12283            switch (r.setSchedGroup) {
12284                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12285                    schedGroup = 'B';
12286                    break;
12287                case Process.THREAD_GROUP_DEFAULT:
12288                    schedGroup = 'F';
12289                    break;
12290                default:
12291                    schedGroup = '?';
12292                    break;
12293            }
12294            char foreground;
12295            if (r.foregroundActivities) {
12296                foreground = 'A';
12297            } else if (r.foregroundServices) {
12298                foreground = 'S';
12299            } else {
12300                foreground = ' ';
12301            }
12302            String procState = ProcessList.makeProcStateString(r.curProcState);
12303            pw.print(prefix);
12304            pw.print(r.persistent ? persistentLabel : normalLabel);
12305            pw.print(" #");
12306            int num = (origList.size()-1)-list.get(i).second;
12307            if (num < 10) pw.print(' ');
12308            pw.print(num);
12309            pw.print(": ");
12310            pw.print(oomAdj);
12311            pw.print(' ');
12312            pw.print(schedGroup);
12313            pw.print('/');
12314            pw.print(foreground);
12315            pw.print('/');
12316            pw.print(procState);
12317            pw.print(" trm:");
12318            if (r.trimMemoryLevel < 10) pw.print(' ');
12319            pw.print(r.trimMemoryLevel);
12320            pw.print(' ');
12321            pw.print(r.toShortString());
12322            pw.print(" (");
12323            pw.print(r.adjType);
12324            pw.println(')');
12325            if (r.adjSource != null || r.adjTarget != null) {
12326                pw.print(prefix);
12327                pw.print("    ");
12328                if (r.adjTarget instanceof ComponentName) {
12329                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12330                } else if (r.adjTarget != null) {
12331                    pw.print(r.adjTarget.toString());
12332                } else {
12333                    pw.print("{null}");
12334                }
12335                pw.print("<=");
12336                if (r.adjSource instanceof ProcessRecord) {
12337                    pw.print("Proc{");
12338                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12339                    pw.println("}");
12340                } else if (r.adjSource != null) {
12341                    pw.println(r.adjSource.toString());
12342                } else {
12343                    pw.println("{null}");
12344                }
12345            }
12346            if (inclDetails) {
12347                pw.print(prefix);
12348                pw.print("    ");
12349                pw.print("oom: max="); pw.print(r.maxAdj);
12350                pw.print(" curRaw="); pw.print(r.curRawAdj);
12351                pw.print(" setRaw="); pw.print(r.setRawAdj);
12352                pw.print(" cur="); pw.print(r.curAdj);
12353                pw.print(" set="); pw.println(r.setAdj);
12354                pw.print(prefix);
12355                pw.print("    ");
12356                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12357                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12358                pw.print(" lastPss="); pw.print(r.lastPss);
12359                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12360                pw.print(prefix);
12361                pw.print("    ");
12362                pw.print("keeping="); pw.print(r.keeping);
12363                pw.print(" cached="); pw.print(r.cached);
12364                pw.print(" empty="); pw.print(r.empty);
12365                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12366
12367                if (!r.keeping) {
12368                    if (r.lastWakeTime != 0) {
12369                        long wtime;
12370                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12371                        synchronized (stats) {
12372                            wtime = stats.getProcessWakeTime(r.info.uid,
12373                                    r.pid, curRealtime);
12374                        }
12375                        long timeUsed = wtime - r.lastWakeTime;
12376                        pw.print(prefix);
12377                        pw.print("    ");
12378                        pw.print("keep awake over ");
12379                        TimeUtils.formatDuration(realtimeSince, pw);
12380                        pw.print(" used ");
12381                        TimeUtils.formatDuration(timeUsed, pw);
12382                        pw.print(" (");
12383                        pw.print((timeUsed*100)/realtimeSince);
12384                        pw.println("%)");
12385                    }
12386                    if (r.lastCpuTime != 0) {
12387                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12388                        pw.print(prefix);
12389                        pw.print("    ");
12390                        pw.print("run cpu over ");
12391                        TimeUtils.formatDuration(uptimeSince, pw);
12392                        pw.print(" used ");
12393                        TimeUtils.formatDuration(timeUsed, pw);
12394                        pw.print(" (");
12395                        pw.print((timeUsed*100)/uptimeSince);
12396                        pw.println("%)");
12397                    }
12398                }
12399            }
12400        }
12401        return true;
12402    }
12403
12404    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12405        ArrayList<ProcessRecord> procs;
12406        synchronized (this) {
12407            if (args != null && args.length > start
12408                    && args[start].charAt(0) != '-') {
12409                procs = new ArrayList<ProcessRecord>();
12410                int pid = -1;
12411                try {
12412                    pid = Integer.parseInt(args[start]);
12413                } catch (NumberFormatException e) {
12414                }
12415                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12416                    ProcessRecord proc = mLruProcesses.get(i);
12417                    if (proc.pid == pid) {
12418                        procs.add(proc);
12419                    } else if (proc.processName.equals(args[start])) {
12420                        procs.add(proc);
12421                    }
12422                }
12423                if (procs.size() <= 0) {
12424                    return null;
12425                }
12426            } else {
12427                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12428            }
12429        }
12430        return procs;
12431    }
12432
12433    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12434            PrintWriter pw, String[] args) {
12435        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12436        if (procs == null) {
12437            pw.println("No process found for: " + args[0]);
12438            return;
12439        }
12440
12441        long uptime = SystemClock.uptimeMillis();
12442        long realtime = SystemClock.elapsedRealtime();
12443        pw.println("Applications Graphics Acceleration Info:");
12444        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12445
12446        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12447            ProcessRecord r = procs.get(i);
12448            if (r.thread != null) {
12449                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12450                pw.flush();
12451                try {
12452                    TransferPipe tp = new TransferPipe();
12453                    try {
12454                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12455                        tp.go(fd);
12456                    } finally {
12457                        tp.kill();
12458                    }
12459                } catch (IOException e) {
12460                    pw.println("Failure while dumping the app: " + r);
12461                    pw.flush();
12462                } catch (RemoteException e) {
12463                    pw.println("Got a RemoteException while dumping the app " + r);
12464                    pw.flush();
12465                }
12466            }
12467        }
12468    }
12469
12470    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12471        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12472        if (procs == null) {
12473            pw.println("No process found for: " + args[0]);
12474            return;
12475        }
12476
12477        pw.println("Applications Database Info:");
12478
12479        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12480            ProcessRecord r = procs.get(i);
12481            if (r.thread != null) {
12482                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12483                pw.flush();
12484                try {
12485                    TransferPipe tp = new TransferPipe();
12486                    try {
12487                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12488                        tp.go(fd);
12489                    } finally {
12490                        tp.kill();
12491                    }
12492                } catch (IOException e) {
12493                    pw.println("Failure while dumping the app: " + r);
12494                    pw.flush();
12495                } catch (RemoteException e) {
12496                    pw.println("Got a RemoteException while dumping the app " + r);
12497                    pw.flush();
12498                }
12499            }
12500        }
12501    }
12502
12503    final static class MemItem {
12504        final boolean isProc;
12505        final String label;
12506        final String shortLabel;
12507        final long pss;
12508        final int id;
12509        final boolean hasActivities;
12510        ArrayList<MemItem> subitems;
12511
12512        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12513                boolean _hasActivities) {
12514            isProc = true;
12515            label = _label;
12516            shortLabel = _shortLabel;
12517            pss = _pss;
12518            id = _id;
12519            hasActivities = _hasActivities;
12520        }
12521
12522        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12523            isProc = false;
12524            label = _label;
12525            shortLabel = _shortLabel;
12526            pss = _pss;
12527            id = _id;
12528            hasActivities = false;
12529        }
12530    }
12531
12532    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12533            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12534        if (sort && !isCompact) {
12535            Collections.sort(items, new Comparator<MemItem>() {
12536                @Override
12537                public int compare(MemItem lhs, MemItem rhs) {
12538                    if (lhs.pss < rhs.pss) {
12539                        return 1;
12540                    } else if (lhs.pss > rhs.pss) {
12541                        return -1;
12542                    }
12543                    return 0;
12544                }
12545            });
12546        }
12547
12548        for (int i=0; i<items.size(); i++) {
12549            MemItem mi = items.get(i);
12550            if (!isCompact) {
12551                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12552            } else if (mi.isProc) {
12553                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12554                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12555                pw.println(mi.hasActivities ? ",a" : ",e");
12556            } else {
12557                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12558                pw.println(mi.pss);
12559            }
12560            if (mi.subitems != null) {
12561                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12562                        true, isCompact);
12563            }
12564        }
12565    }
12566
12567    // These are in KB.
12568    static final long[] DUMP_MEM_BUCKETS = new long[] {
12569        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12570        120*1024, 160*1024, 200*1024,
12571        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12572        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12573    };
12574
12575    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12576            boolean stackLike) {
12577        int start = label.lastIndexOf('.');
12578        if (start >= 0) start++;
12579        else start = 0;
12580        int end = label.length();
12581        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12582            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12583                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12584                out.append(bucket);
12585                out.append(stackLike ? "MB." : "MB ");
12586                out.append(label, start, end);
12587                return;
12588            }
12589        }
12590        out.append(memKB/1024);
12591        out.append(stackLike ? "MB." : "MB ");
12592        out.append(label, start, end);
12593    }
12594
12595    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12596            ProcessList.NATIVE_ADJ,
12597            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12598            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12599            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12600            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12601            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12602    };
12603    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12604            "Native",
12605            "System", "Persistent", "Foreground",
12606            "Visible", "Perceptible",
12607            "Heavy Weight", "Backup",
12608            "A Services", "Home",
12609            "Previous", "B Services", "Cached"
12610    };
12611    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12612            "native",
12613            "sys", "pers", "fore",
12614            "vis", "percept",
12615            "heavy", "backup",
12616            "servicea", "home",
12617            "prev", "serviceb", "cached"
12618    };
12619
12620    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12621            long realtime, boolean isCheckinRequest, boolean isCompact) {
12622        if (isCheckinRequest || isCompact) {
12623            // short checkin version
12624            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12625        } else {
12626            pw.println("Applications Memory Usage (kB):");
12627            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12628        }
12629    }
12630
12631    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12632            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12633        boolean dumpDetails = false;
12634        boolean dumpFullDetails = false;
12635        boolean dumpDalvik = false;
12636        boolean oomOnly = false;
12637        boolean isCompact = false;
12638        boolean localOnly = false;
12639
12640        int opti = 0;
12641        while (opti < args.length) {
12642            String opt = args[opti];
12643            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12644                break;
12645            }
12646            opti++;
12647            if ("-a".equals(opt)) {
12648                dumpDetails = true;
12649                dumpFullDetails = true;
12650                dumpDalvik = true;
12651            } else if ("-d".equals(opt)) {
12652                dumpDalvik = true;
12653            } else if ("-c".equals(opt)) {
12654                isCompact = true;
12655            } else if ("--oom".equals(opt)) {
12656                oomOnly = true;
12657            } else if ("--local".equals(opt)) {
12658                localOnly = true;
12659            } else if ("-h".equals(opt)) {
12660                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12661                pw.println("  -a: include all available information for each process.");
12662                pw.println("  -d: include dalvik details when dumping process details.");
12663                pw.println("  -c: dump in a compact machine-parseable representation.");
12664                pw.println("  --oom: only show processes organized by oom adj.");
12665                pw.println("  --local: only collect details locally, don't call process.");
12666                pw.println("If [process] is specified it can be the name or ");
12667                pw.println("pid of a specific process to dump.");
12668                return;
12669            } else {
12670                pw.println("Unknown argument: " + opt + "; use -h for help");
12671            }
12672        }
12673
12674        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12675        long uptime = SystemClock.uptimeMillis();
12676        long realtime = SystemClock.elapsedRealtime();
12677        final long[] tmpLong = new long[1];
12678
12679        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12680        if (procs == null) {
12681            // No Java processes.  Maybe they want to print a native process.
12682            if (args != null && args.length > opti
12683                    && args[opti].charAt(0) != '-') {
12684                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12685                        = new ArrayList<ProcessCpuTracker.Stats>();
12686                updateCpuStatsNow();
12687                int findPid = -1;
12688                try {
12689                    findPid = Integer.parseInt(args[opti]);
12690                } catch (NumberFormatException e) {
12691                }
12692                synchronized (mProcessCpuThread) {
12693                    final int N = mProcessCpuTracker.countStats();
12694                    for (int i=0; i<N; i++) {
12695                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12696                        if (st.pid == findPid || (st.baseName != null
12697                                && st.baseName.equals(args[opti]))) {
12698                            nativeProcs.add(st);
12699                        }
12700                    }
12701                }
12702                if (nativeProcs.size() > 0) {
12703                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12704                            isCompact);
12705                    Debug.MemoryInfo mi = null;
12706                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12707                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12708                        final int pid = r.pid;
12709                        if (!isCheckinRequest && dumpDetails) {
12710                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12711                        }
12712                        if (mi == null) {
12713                            mi = new Debug.MemoryInfo();
12714                        }
12715                        if (dumpDetails || (!brief && !oomOnly)) {
12716                            Debug.getMemoryInfo(pid, mi);
12717                        } else {
12718                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12719                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12720                        }
12721                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12722                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12723                        if (isCheckinRequest) {
12724                            pw.println();
12725                        }
12726                    }
12727                    return;
12728                }
12729            }
12730            pw.println("No process found for: " + args[opti]);
12731            return;
12732        }
12733
12734        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12735            dumpDetails = true;
12736        }
12737
12738        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12739
12740        String[] innerArgs = new String[args.length-opti];
12741        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12742
12743        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12744        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12745        long nativePss=0, dalvikPss=0, otherPss=0;
12746        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12747
12748        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12749        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12750                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12751
12752        long totalPss = 0;
12753        long cachedPss = 0;
12754
12755        Debug.MemoryInfo mi = null;
12756        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12757            final ProcessRecord r = procs.get(i);
12758            final IApplicationThread thread;
12759            final int pid;
12760            final int oomAdj;
12761            final boolean hasActivities;
12762            synchronized (this) {
12763                thread = r.thread;
12764                pid = r.pid;
12765                oomAdj = r.getSetAdjWithServices();
12766                hasActivities = r.activities.size() > 0;
12767            }
12768            if (thread != null) {
12769                if (!isCheckinRequest && dumpDetails) {
12770                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12771                }
12772                if (mi == null) {
12773                    mi = new Debug.MemoryInfo();
12774                }
12775                if (dumpDetails || (!brief && !oomOnly)) {
12776                    Debug.getMemoryInfo(pid, mi);
12777                } else {
12778                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12779                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12780                }
12781                if (dumpDetails) {
12782                    if (localOnly) {
12783                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12784                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12785                        if (isCheckinRequest) {
12786                            pw.println();
12787                        }
12788                    } else {
12789                        try {
12790                            pw.flush();
12791                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12792                                    dumpDalvik, innerArgs);
12793                        } catch (RemoteException e) {
12794                            if (!isCheckinRequest) {
12795                                pw.println("Got RemoteException!");
12796                                pw.flush();
12797                            }
12798                        }
12799                    }
12800                }
12801
12802                final long myTotalPss = mi.getTotalPss();
12803                final long myTotalUss = mi.getTotalUss();
12804
12805                synchronized (this) {
12806                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12807                        // Record this for posterity if the process has been stable.
12808                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12809                    }
12810                }
12811
12812                if (!isCheckinRequest && mi != null) {
12813                    totalPss += myTotalPss;
12814                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12815                            (hasActivities ? " / activities)" : ")"),
12816                            r.processName, myTotalPss, pid, hasActivities);
12817                    procMems.add(pssItem);
12818                    procMemsMap.put(pid, pssItem);
12819
12820                    nativePss += mi.nativePss;
12821                    dalvikPss += mi.dalvikPss;
12822                    otherPss += mi.otherPss;
12823                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12824                        long mem = mi.getOtherPss(j);
12825                        miscPss[j] += mem;
12826                        otherPss -= mem;
12827                    }
12828
12829                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12830                        cachedPss += myTotalPss;
12831                    }
12832
12833                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12834                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12835                                || oomIndex == (oomPss.length-1)) {
12836                            oomPss[oomIndex] += myTotalPss;
12837                            if (oomProcs[oomIndex] == null) {
12838                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12839                            }
12840                            oomProcs[oomIndex].add(pssItem);
12841                            break;
12842                        }
12843                    }
12844                }
12845            }
12846        }
12847
12848        long nativeProcTotalPss = 0;
12849
12850        if (!isCheckinRequest && procs.size() > 1) {
12851            // If we are showing aggregations, also look for native processes to
12852            // include so that our aggregations are more accurate.
12853            updateCpuStatsNow();
12854            synchronized (mProcessCpuThread) {
12855                final int N = mProcessCpuTracker.countStats();
12856                for (int i=0; i<N; i++) {
12857                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12858                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12859                        if (mi == null) {
12860                            mi = new Debug.MemoryInfo();
12861                        }
12862                        if (!brief && !oomOnly) {
12863                            Debug.getMemoryInfo(st.pid, mi);
12864                        } else {
12865                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12866                            mi.nativePrivateDirty = (int)tmpLong[0];
12867                        }
12868
12869                        final long myTotalPss = mi.getTotalPss();
12870                        totalPss += myTotalPss;
12871                        nativeProcTotalPss += myTotalPss;
12872
12873                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12874                                st.name, myTotalPss, st.pid, false);
12875                        procMems.add(pssItem);
12876
12877                        nativePss += mi.nativePss;
12878                        dalvikPss += mi.dalvikPss;
12879                        otherPss += mi.otherPss;
12880                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12881                            long mem = mi.getOtherPss(j);
12882                            miscPss[j] += mem;
12883                            otherPss -= mem;
12884                        }
12885                        oomPss[0] += myTotalPss;
12886                        if (oomProcs[0] == null) {
12887                            oomProcs[0] = new ArrayList<MemItem>();
12888                        }
12889                        oomProcs[0].add(pssItem);
12890                    }
12891                }
12892            }
12893
12894            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12895
12896            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12897            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12898            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12899            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12900                String label = Debug.MemoryInfo.getOtherLabel(j);
12901                catMems.add(new MemItem(label, label, miscPss[j], j));
12902            }
12903
12904            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12905            for (int j=0; j<oomPss.length; j++) {
12906                if (oomPss[j] != 0) {
12907                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12908                            : DUMP_MEM_OOM_LABEL[j];
12909                    MemItem item = new MemItem(label, label, oomPss[j],
12910                            DUMP_MEM_OOM_ADJ[j]);
12911                    item.subitems = oomProcs[j];
12912                    oomMems.add(item);
12913                }
12914            }
12915
12916            if (!brief && !oomOnly && !isCompact) {
12917                pw.println();
12918                pw.println("Total PSS by process:");
12919                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12920                pw.println();
12921            }
12922            if (!isCompact) {
12923                pw.println("Total PSS by OOM adjustment:");
12924            }
12925            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12926            if (!brief && !oomOnly) {
12927                PrintWriter out = categoryPw != null ? categoryPw : pw;
12928                if (!isCompact) {
12929                    out.println();
12930                    out.println("Total PSS by category:");
12931                }
12932                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12933            }
12934            if (!isCompact) {
12935                pw.println();
12936            }
12937            MemInfoReader memInfo = new MemInfoReader();
12938            memInfo.readMemInfo();
12939            if (nativeProcTotalPss > 0) {
12940                synchronized (this) {
12941                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12942                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12943                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12944                            nativeProcTotalPss);
12945                }
12946            }
12947            if (!brief) {
12948                if (!isCompact) {
12949                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12950                    pw.print(" kB (status ");
12951                    switch (mLastMemoryLevel) {
12952                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12953                            pw.println("normal)");
12954                            break;
12955                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12956                            pw.println("moderate)");
12957                            break;
12958                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12959                            pw.println("low)");
12960                            break;
12961                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12962                            pw.println("critical)");
12963                            break;
12964                        default:
12965                            pw.print(mLastMemoryLevel);
12966                            pw.println(")");
12967                            break;
12968                    }
12969                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12970                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12971                            pw.print(cachedPss); pw.print(" cached pss + ");
12972                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12973                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12974                } else {
12975                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12976                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12977                            + memInfo.getFreeSizeKb()); pw.print(",");
12978                    pw.println(totalPss - cachedPss);
12979                }
12980            }
12981            if (!isCompact) {
12982                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12983                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12984                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12985                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12986                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12987                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12988                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12989                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12990                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12991                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12992                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12993            }
12994            if (!brief) {
12995                if (memInfo.getZramTotalSizeKb() != 0) {
12996                    if (!isCompact) {
12997                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12998                                pw.print(" kB physical used for ");
12999                                pw.print(memInfo.getSwapTotalSizeKb()
13000                                        - memInfo.getSwapFreeSizeKb());
13001                                pw.print(" kB in swap (");
13002                                pw.print(memInfo.getSwapTotalSizeKb());
13003                                pw.println(" kB total swap)");
13004                    } else {
13005                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13006                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13007                                pw.println(memInfo.getSwapFreeSizeKb());
13008                    }
13009                }
13010                final int[] SINGLE_LONG_FORMAT = new int[] {
13011                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13012                };
13013                long[] longOut = new long[1];
13014                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13015                        SINGLE_LONG_FORMAT, null, longOut, null);
13016                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13017                longOut[0] = 0;
13018                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13019                        SINGLE_LONG_FORMAT, null, longOut, null);
13020                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13021                longOut[0] = 0;
13022                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13023                        SINGLE_LONG_FORMAT, null, longOut, null);
13024                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13025                longOut[0] = 0;
13026                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13027                        SINGLE_LONG_FORMAT, null, longOut, null);
13028                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13029                if (!isCompact) {
13030                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13031                        pw.print("      KSM: "); pw.print(sharing);
13032                                pw.print(" kB saved from shared ");
13033                                pw.print(shared); pw.println(" kB");
13034                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13035                                pw.print(voltile); pw.println(" kB volatile");
13036                    }
13037                    pw.print("   Tuning: ");
13038                    pw.print(ActivityManager.staticGetMemoryClass());
13039                    pw.print(" (large ");
13040                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13041                    pw.print("), oom ");
13042                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13043                    pw.print(" kB");
13044                    pw.print(", restore limit ");
13045                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13046                    pw.print(" kB");
13047                    if (ActivityManager.isLowRamDeviceStatic()) {
13048                        pw.print(" (low-ram)");
13049                    }
13050                    if (ActivityManager.isHighEndGfx()) {
13051                        pw.print(" (high-end-gfx)");
13052                    }
13053                    pw.println();
13054                } else {
13055                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13056                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13057                    pw.println(voltile);
13058                    pw.print("tuning,");
13059                    pw.print(ActivityManager.staticGetMemoryClass());
13060                    pw.print(',');
13061                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13062                    pw.print(',');
13063                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13064                    if (ActivityManager.isLowRamDeviceStatic()) {
13065                        pw.print(",low-ram");
13066                    }
13067                    if (ActivityManager.isHighEndGfx()) {
13068                        pw.print(",high-end-gfx");
13069                    }
13070                    pw.println();
13071                }
13072            }
13073        }
13074    }
13075
13076    /**
13077     * Searches array of arguments for the specified string
13078     * @param args array of argument strings
13079     * @param value value to search for
13080     * @return true if the value is contained in the array
13081     */
13082    private static boolean scanArgs(String[] args, String value) {
13083        if (args != null) {
13084            for (String arg : args) {
13085                if (value.equals(arg)) {
13086                    return true;
13087                }
13088            }
13089        }
13090        return false;
13091    }
13092
13093    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13094            ContentProviderRecord cpr, boolean always) {
13095        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13096
13097        if (!inLaunching || always) {
13098            synchronized (cpr) {
13099                cpr.launchingApp = null;
13100                cpr.notifyAll();
13101            }
13102            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13103            String names[] = cpr.info.authority.split(";");
13104            for (int j = 0; j < names.length; j++) {
13105                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13106            }
13107        }
13108
13109        for (int i=0; i<cpr.connections.size(); i++) {
13110            ContentProviderConnection conn = cpr.connections.get(i);
13111            if (conn.waiting) {
13112                // If this connection is waiting for the provider, then we don't
13113                // need to mess with its process unless we are always removing
13114                // or for some reason the provider is not currently launching.
13115                if (inLaunching && !always) {
13116                    continue;
13117                }
13118            }
13119            ProcessRecord capp = conn.client;
13120            conn.dead = true;
13121            if (conn.stableCount > 0) {
13122                if (!capp.persistent && capp.thread != null
13123                        && capp.pid != 0
13124                        && capp.pid != MY_PID) {
13125                    killUnneededProcessLocked(capp, "depends on provider "
13126                            + cpr.name.flattenToShortString()
13127                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13128                }
13129            } else if (capp.thread != null && conn.provider.provider != null) {
13130                try {
13131                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13132                } catch (RemoteException e) {
13133                }
13134                // In the protocol here, we don't expect the client to correctly
13135                // clean up this connection, we'll just remove it.
13136                cpr.connections.remove(i);
13137                conn.client.conProviders.remove(conn);
13138            }
13139        }
13140
13141        if (inLaunching && always) {
13142            mLaunchingProviders.remove(cpr);
13143        }
13144        return inLaunching;
13145    }
13146
13147    /**
13148     * Main code for cleaning up a process when it has gone away.  This is
13149     * called both as a result of the process dying, or directly when stopping
13150     * a process when running in single process mode.
13151     */
13152    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13153            boolean restarting, boolean allowRestart, int index) {
13154        if (index >= 0) {
13155            removeLruProcessLocked(app);
13156            ProcessList.remove(app.pid);
13157        }
13158
13159        mProcessesToGc.remove(app);
13160        mPendingPssProcesses.remove(app);
13161
13162        // Dismiss any open dialogs.
13163        if (app.crashDialog != null && !app.forceCrashReport) {
13164            app.crashDialog.dismiss();
13165            app.crashDialog = null;
13166        }
13167        if (app.anrDialog != null) {
13168            app.anrDialog.dismiss();
13169            app.anrDialog = null;
13170        }
13171        if (app.waitDialog != null) {
13172            app.waitDialog.dismiss();
13173            app.waitDialog = null;
13174        }
13175
13176        app.crashing = false;
13177        app.notResponding = false;
13178
13179        app.resetPackageList(mProcessStats);
13180        app.unlinkDeathRecipient();
13181        app.makeInactive(mProcessStats);
13182        app.waitingToKill = null;
13183        app.forcingToForeground = null;
13184        updateProcessForegroundLocked(app, false, false);
13185        app.foregroundActivities = false;
13186        app.hasShownUi = false;
13187        app.treatLikeActivity = false;
13188        app.hasAboveClient = false;
13189        app.hasClientActivities = false;
13190
13191        mServices.killServicesLocked(app, allowRestart);
13192
13193        boolean restart = false;
13194
13195        // Remove published content providers.
13196        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13197            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13198            final boolean always = app.bad || !allowRestart;
13199            if (removeDyingProviderLocked(app, cpr, always) || always) {
13200                // We left the provider in the launching list, need to
13201                // restart it.
13202                restart = true;
13203            }
13204
13205            cpr.provider = null;
13206            cpr.proc = null;
13207        }
13208        app.pubProviders.clear();
13209
13210        // Take care of any launching providers waiting for this process.
13211        if (checkAppInLaunchingProvidersLocked(app, false)) {
13212            restart = true;
13213        }
13214
13215        // Unregister from connected content providers.
13216        if (!app.conProviders.isEmpty()) {
13217            for (int i=0; i<app.conProviders.size(); i++) {
13218                ContentProviderConnection conn = app.conProviders.get(i);
13219                conn.provider.connections.remove(conn);
13220            }
13221            app.conProviders.clear();
13222        }
13223
13224        // At this point there may be remaining entries in mLaunchingProviders
13225        // where we were the only one waiting, so they are no longer of use.
13226        // Look for these and clean up if found.
13227        // XXX Commented out for now.  Trying to figure out a way to reproduce
13228        // the actual situation to identify what is actually going on.
13229        if (false) {
13230            for (int i=0; i<mLaunchingProviders.size(); i++) {
13231                ContentProviderRecord cpr = (ContentProviderRecord)
13232                        mLaunchingProviders.get(i);
13233                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13234                    synchronized (cpr) {
13235                        cpr.launchingApp = null;
13236                        cpr.notifyAll();
13237                    }
13238                }
13239            }
13240        }
13241
13242        skipCurrentReceiverLocked(app);
13243
13244        // Unregister any receivers.
13245        for (int i=app.receivers.size()-1; i>=0; i--) {
13246            removeReceiverLocked(app.receivers.valueAt(i));
13247        }
13248        app.receivers.clear();
13249
13250        // If the app is undergoing backup, tell the backup manager about it
13251        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13252            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13253                    + mBackupTarget.appInfo + " died during backup");
13254            try {
13255                IBackupManager bm = IBackupManager.Stub.asInterface(
13256                        ServiceManager.getService(Context.BACKUP_SERVICE));
13257                bm.agentDisconnected(app.info.packageName);
13258            } catch (RemoteException e) {
13259                // can't happen; backup manager is local
13260            }
13261        }
13262
13263        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13264            ProcessChangeItem item = mPendingProcessChanges.get(i);
13265            if (item.pid == app.pid) {
13266                mPendingProcessChanges.remove(i);
13267                mAvailProcessChanges.add(item);
13268            }
13269        }
13270        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13271
13272        // If the caller is restarting this app, then leave it in its
13273        // current lists and let the caller take care of it.
13274        if (restarting) {
13275            return;
13276        }
13277
13278        if (!app.persistent || app.isolated) {
13279            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13280                    "Removing non-persistent process during cleanup: " + app);
13281            mProcessNames.remove(app.processName, app.uid);
13282            mIsolatedProcesses.remove(app.uid);
13283            if (mHeavyWeightProcess == app) {
13284                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13285                        mHeavyWeightProcess.userId, 0));
13286                mHeavyWeightProcess = null;
13287            }
13288        } else if (!app.removed) {
13289            // This app is persistent, so we need to keep its record around.
13290            // If it is not already on the pending app list, add it there
13291            // and start a new process for it.
13292            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13293                mPersistentStartingProcesses.add(app);
13294                restart = true;
13295            }
13296        }
13297        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13298                "Clean-up removing on hold: " + app);
13299        mProcessesOnHold.remove(app);
13300
13301        if (app == mHomeProcess) {
13302            mHomeProcess = null;
13303        }
13304        if (app == mPreviousProcess) {
13305            mPreviousProcess = null;
13306        }
13307
13308        if (restart && !app.isolated) {
13309            // We have components that still need to be running in the
13310            // process, so re-launch it.
13311            mProcessNames.put(app.processName, app.uid, app);
13312            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13313        } else if (app.pid > 0 && app.pid != MY_PID) {
13314            // Goodbye!
13315            boolean removed;
13316            synchronized (mPidsSelfLocked) {
13317                mPidsSelfLocked.remove(app.pid);
13318                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13319            }
13320            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13321            if (app.isolated) {
13322                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13323            }
13324            app.setPid(0);
13325        }
13326    }
13327
13328    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13329        // Look through the content providers we are waiting to have launched,
13330        // and if any run in this process then either schedule a restart of
13331        // the process or kill the client waiting for it if this process has
13332        // gone bad.
13333        int NL = mLaunchingProviders.size();
13334        boolean restart = false;
13335        for (int i=0; i<NL; i++) {
13336            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13337            if (cpr.launchingApp == app) {
13338                if (!alwaysBad && !app.bad) {
13339                    restart = true;
13340                } else {
13341                    removeDyingProviderLocked(app, cpr, true);
13342                    // cpr should have been removed from mLaunchingProviders
13343                    NL = mLaunchingProviders.size();
13344                    i--;
13345                }
13346            }
13347        }
13348        return restart;
13349    }
13350
13351    // =========================================================
13352    // SERVICES
13353    // =========================================================
13354
13355    @Override
13356    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13357            int flags) {
13358        enforceNotIsolatedCaller("getServices");
13359        synchronized (this) {
13360            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13361        }
13362    }
13363
13364    @Override
13365    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13366        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13367        synchronized (this) {
13368            return mServices.getRunningServiceControlPanelLocked(name);
13369        }
13370    }
13371
13372    @Override
13373    public ComponentName startService(IApplicationThread caller, Intent service,
13374            String resolvedType, int userId) {
13375        enforceNotIsolatedCaller("startService");
13376        // Refuse possible leaked file descriptors
13377        if (service != null && service.hasFileDescriptors() == true) {
13378            throw new IllegalArgumentException("File descriptors passed in Intent");
13379        }
13380
13381        if (DEBUG_SERVICE)
13382            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13383        synchronized(this) {
13384            final int callingPid = Binder.getCallingPid();
13385            final int callingUid = Binder.getCallingUid();
13386            final long origId = Binder.clearCallingIdentity();
13387            ComponentName res = mServices.startServiceLocked(caller, service,
13388                    resolvedType, callingPid, callingUid, userId);
13389            Binder.restoreCallingIdentity(origId);
13390            return res;
13391        }
13392    }
13393
13394    ComponentName startServiceInPackage(int uid,
13395            Intent service, String resolvedType, int userId) {
13396        synchronized(this) {
13397            if (DEBUG_SERVICE)
13398                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13399            final long origId = Binder.clearCallingIdentity();
13400            ComponentName res = mServices.startServiceLocked(null, service,
13401                    resolvedType, -1, uid, userId);
13402            Binder.restoreCallingIdentity(origId);
13403            return res;
13404        }
13405    }
13406
13407    @Override
13408    public int stopService(IApplicationThread caller, Intent service,
13409            String resolvedType, int userId) {
13410        enforceNotIsolatedCaller("stopService");
13411        // Refuse possible leaked file descriptors
13412        if (service != null && service.hasFileDescriptors() == true) {
13413            throw new IllegalArgumentException("File descriptors passed in Intent");
13414        }
13415
13416        synchronized(this) {
13417            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13418        }
13419    }
13420
13421    @Override
13422    public IBinder peekService(Intent service, String resolvedType) {
13423        enforceNotIsolatedCaller("peekService");
13424        // Refuse possible leaked file descriptors
13425        if (service != null && service.hasFileDescriptors() == true) {
13426            throw new IllegalArgumentException("File descriptors passed in Intent");
13427        }
13428        synchronized(this) {
13429            return mServices.peekServiceLocked(service, resolvedType);
13430        }
13431    }
13432
13433    @Override
13434    public boolean stopServiceToken(ComponentName className, IBinder token,
13435            int startId) {
13436        synchronized(this) {
13437            return mServices.stopServiceTokenLocked(className, token, startId);
13438        }
13439    }
13440
13441    @Override
13442    public void setServiceForeground(ComponentName className, IBinder token,
13443            int id, Notification notification, boolean removeNotification) {
13444        synchronized(this) {
13445            mServices.setServiceForegroundLocked(className, token, id, notification,
13446                    removeNotification);
13447        }
13448    }
13449
13450    @Override
13451    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13452            boolean requireFull, String name, String callerPackage) {
13453        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13454                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13455    }
13456
13457    int unsafeConvertIncomingUser(int userId) {
13458        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13459                ? mCurrentUserId : userId;
13460    }
13461
13462    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13463            int allowMode, String name, String callerPackage) {
13464        final int callingUserId = UserHandle.getUserId(callingUid);
13465        if (callingUserId == userId) {
13466            return userId;
13467        }
13468
13469        // Note that we may be accessing mCurrentUserId outside of a lock...
13470        // shouldn't be a big deal, if this is being called outside
13471        // of a locked context there is intrinsically a race with
13472        // the value the caller will receive and someone else changing it.
13473        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13474        // we will switch to the calling user if access to the current user fails.
13475        int targetUserId = unsafeConvertIncomingUser(userId);
13476
13477        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13478            final boolean allow;
13479            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13480                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13481                // If the caller has this permission, they always pass go.  And collect $200.
13482                allow = true;
13483            } else if (allowMode == ALLOW_FULL_ONLY) {
13484                // We require full access, sucks to be you.
13485                allow = false;
13486            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13487                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13488                // If the caller does not have either permission, they are always doomed.
13489                allow = false;
13490            } else if (allowMode == ALLOW_NON_FULL) {
13491                // We are blanket allowing non-full access, you lucky caller!
13492                allow = true;
13493            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13494                // We may or may not allow this depending on whether the two users are
13495                // in the same profile.
13496                synchronized (mUserProfileGroupIdsSelfLocked) {
13497                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13498                            UserInfo.NO_PROFILE_GROUP_ID);
13499                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13500                            UserInfo.NO_PROFILE_GROUP_ID);
13501                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13502                            && callingProfile == targetProfile;
13503                }
13504            } else {
13505                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13506            }
13507            if (!allow) {
13508                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13509                    // In this case, they would like to just execute as their
13510                    // owner user instead of failing.
13511                    targetUserId = callingUserId;
13512                } else {
13513                    StringBuilder builder = new StringBuilder(128);
13514                    builder.append("Permission Denial: ");
13515                    builder.append(name);
13516                    if (callerPackage != null) {
13517                        builder.append(" from ");
13518                        builder.append(callerPackage);
13519                    }
13520                    builder.append(" asks to run as user ");
13521                    builder.append(userId);
13522                    builder.append(" but is calling from user ");
13523                    builder.append(UserHandle.getUserId(callingUid));
13524                    builder.append("; this requires ");
13525                    builder.append(INTERACT_ACROSS_USERS_FULL);
13526                    if (allowMode != ALLOW_FULL_ONLY) {
13527                        builder.append(" or ");
13528                        builder.append(INTERACT_ACROSS_USERS);
13529                    }
13530                    String msg = builder.toString();
13531                    Slog.w(TAG, msg);
13532                    throw new SecurityException(msg);
13533                }
13534            }
13535        }
13536        if (!allowAll && targetUserId < 0) {
13537            throw new IllegalArgumentException(
13538                    "Call does not support special user #" + targetUserId);
13539        }
13540        return targetUserId;
13541    }
13542
13543    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13544            String className, int flags) {
13545        boolean result = false;
13546        // For apps that don't have pre-defined UIDs, check for permission
13547        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13548            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13549                if (ActivityManager.checkUidPermission(
13550                        INTERACT_ACROSS_USERS,
13551                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13552                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13553                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13554                            + " requests FLAG_SINGLE_USER, but app does not hold "
13555                            + INTERACT_ACROSS_USERS;
13556                    Slog.w(TAG, msg);
13557                    throw new SecurityException(msg);
13558                }
13559                // Permission passed
13560                result = true;
13561            }
13562        } else if ("system".equals(componentProcessName)) {
13563            result = true;
13564        } else {
13565            // App with pre-defined UID, check if it's a persistent app
13566            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13567        }
13568        if (DEBUG_MU) {
13569            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13570                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13571        }
13572        return result;
13573    }
13574
13575    /**
13576     * Checks to see if the caller is in the same app as the singleton
13577     * component, or the component is in a special app. It allows special apps
13578     * to export singleton components but prevents exporting singleton
13579     * components for regular apps.
13580     */
13581    boolean isValidSingletonCall(int callingUid, int componentUid) {
13582        int componentAppId = UserHandle.getAppId(componentUid);
13583        return UserHandle.isSameApp(callingUid, componentUid)
13584                || componentAppId == Process.SYSTEM_UID
13585                || componentAppId == Process.PHONE_UID
13586                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13587                        == PackageManager.PERMISSION_GRANTED;
13588    }
13589
13590    public int bindService(IApplicationThread caller, IBinder token,
13591            Intent service, String resolvedType,
13592            IServiceConnection connection, int flags, int userId) {
13593        enforceNotIsolatedCaller("bindService");
13594        // Refuse possible leaked file descriptors
13595        if (service != null && service.hasFileDescriptors() == true) {
13596            throw new IllegalArgumentException("File descriptors passed in Intent");
13597        }
13598
13599        synchronized(this) {
13600            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13601                    connection, flags, userId);
13602        }
13603    }
13604
13605    public boolean unbindService(IServiceConnection connection) {
13606        synchronized (this) {
13607            return mServices.unbindServiceLocked(connection);
13608        }
13609    }
13610
13611    public void publishService(IBinder token, Intent intent, IBinder service) {
13612        // Refuse possible leaked file descriptors
13613        if (intent != null && intent.hasFileDescriptors() == true) {
13614            throw new IllegalArgumentException("File descriptors passed in Intent");
13615        }
13616
13617        synchronized(this) {
13618            if (!(token instanceof ServiceRecord)) {
13619                throw new IllegalArgumentException("Invalid service token");
13620            }
13621            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13622        }
13623    }
13624
13625    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13626        // Refuse possible leaked file descriptors
13627        if (intent != null && intent.hasFileDescriptors() == true) {
13628            throw new IllegalArgumentException("File descriptors passed in Intent");
13629        }
13630
13631        synchronized(this) {
13632            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13633        }
13634    }
13635
13636    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13637        synchronized(this) {
13638            if (!(token instanceof ServiceRecord)) {
13639                throw new IllegalArgumentException("Invalid service token");
13640            }
13641            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13642        }
13643    }
13644
13645    // =========================================================
13646    // BACKUP AND RESTORE
13647    // =========================================================
13648
13649    // Cause the target app to be launched if necessary and its backup agent
13650    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13651    // activity manager to announce its creation.
13652    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13653        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13654        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13655
13656        synchronized(this) {
13657            // !!! TODO: currently no check here that we're already bound
13658            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13659            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13660            synchronized (stats) {
13661                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13662            }
13663
13664            // Backup agent is now in use, its package can't be stopped.
13665            try {
13666                AppGlobals.getPackageManager().setPackageStoppedState(
13667                        app.packageName, false, UserHandle.getUserId(app.uid));
13668            } catch (RemoteException e) {
13669            } catch (IllegalArgumentException e) {
13670                Slog.w(TAG, "Failed trying to unstop package "
13671                        + app.packageName + ": " + e);
13672            }
13673
13674            BackupRecord r = new BackupRecord(ss, app, backupMode);
13675            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13676                    ? new ComponentName(app.packageName, app.backupAgentName)
13677                    : new ComponentName("android", "FullBackupAgent");
13678            // startProcessLocked() returns existing proc's record if it's already running
13679            ProcessRecord proc = startProcessLocked(app.processName, app,
13680                    false, 0, "backup", hostingName, false, false, false);
13681            if (proc == null) {
13682                Slog.e(TAG, "Unable to start backup agent process " + r);
13683                return false;
13684            }
13685
13686            r.app = proc;
13687            mBackupTarget = r;
13688            mBackupAppName = app.packageName;
13689
13690            // Try not to kill the process during backup
13691            updateOomAdjLocked(proc);
13692
13693            // If the process is already attached, schedule the creation of the backup agent now.
13694            // If it is not yet live, this will be done when it attaches to the framework.
13695            if (proc.thread != null) {
13696                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13697                try {
13698                    proc.thread.scheduleCreateBackupAgent(app,
13699                            compatibilityInfoForPackageLocked(app), backupMode);
13700                } catch (RemoteException e) {
13701                    // Will time out on the backup manager side
13702                }
13703            } else {
13704                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13705            }
13706            // Invariants: at this point, the target app process exists and the application
13707            // is either already running or in the process of coming up.  mBackupTarget and
13708            // mBackupAppName describe the app, so that when it binds back to the AM we
13709            // know that it's scheduled for a backup-agent operation.
13710        }
13711
13712        return true;
13713    }
13714
13715    @Override
13716    public void clearPendingBackup() {
13717        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13718        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13719
13720        synchronized (this) {
13721            mBackupTarget = null;
13722            mBackupAppName = null;
13723        }
13724    }
13725
13726    // A backup agent has just come up
13727    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13728        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13729                + " = " + agent);
13730
13731        synchronized(this) {
13732            if (!agentPackageName.equals(mBackupAppName)) {
13733                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13734                return;
13735            }
13736        }
13737
13738        long oldIdent = Binder.clearCallingIdentity();
13739        try {
13740            IBackupManager bm = IBackupManager.Stub.asInterface(
13741                    ServiceManager.getService(Context.BACKUP_SERVICE));
13742            bm.agentConnected(agentPackageName, agent);
13743        } catch (RemoteException e) {
13744            // can't happen; the backup manager service is local
13745        } catch (Exception e) {
13746            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13747            e.printStackTrace();
13748        } finally {
13749            Binder.restoreCallingIdentity(oldIdent);
13750        }
13751    }
13752
13753    // done with this agent
13754    public void unbindBackupAgent(ApplicationInfo appInfo) {
13755        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13756        if (appInfo == null) {
13757            Slog.w(TAG, "unbind backup agent for null app");
13758            return;
13759        }
13760
13761        synchronized(this) {
13762            try {
13763                if (mBackupAppName == null) {
13764                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13765                    return;
13766                }
13767
13768                if (!mBackupAppName.equals(appInfo.packageName)) {
13769                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13770                    return;
13771                }
13772
13773                // Not backing this app up any more; reset its OOM adjustment
13774                final ProcessRecord proc = mBackupTarget.app;
13775                updateOomAdjLocked(proc);
13776
13777                // If the app crashed during backup, 'thread' will be null here
13778                if (proc.thread != null) {
13779                    try {
13780                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13781                                compatibilityInfoForPackageLocked(appInfo));
13782                    } catch (Exception e) {
13783                        Slog.e(TAG, "Exception when unbinding backup agent:");
13784                        e.printStackTrace();
13785                    }
13786                }
13787            } finally {
13788                mBackupTarget = null;
13789                mBackupAppName = null;
13790            }
13791        }
13792    }
13793    // =========================================================
13794    // BROADCASTS
13795    // =========================================================
13796
13797    private final List getStickiesLocked(String action, IntentFilter filter,
13798            List cur, int userId) {
13799        final ContentResolver resolver = mContext.getContentResolver();
13800        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13801        if (stickies == null) {
13802            return cur;
13803        }
13804        final ArrayList<Intent> list = stickies.get(action);
13805        if (list == null) {
13806            return cur;
13807        }
13808        int N = list.size();
13809        for (int i=0; i<N; i++) {
13810            Intent intent = list.get(i);
13811            if (filter.match(resolver, intent, true, TAG) >= 0) {
13812                if (cur == null) {
13813                    cur = new ArrayList<Intent>();
13814                }
13815                cur.add(intent);
13816            }
13817        }
13818        return cur;
13819    }
13820
13821    boolean isPendingBroadcastProcessLocked(int pid) {
13822        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13823                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13824    }
13825
13826    void skipPendingBroadcastLocked(int pid) {
13827            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13828            for (BroadcastQueue queue : mBroadcastQueues) {
13829                queue.skipPendingBroadcastLocked(pid);
13830            }
13831    }
13832
13833    // The app just attached; send any pending broadcasts that it should receive
13834    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13835        boolean didSomething = false;
13836        for (BroadcastQueue queue : mBroadcastQueues) {
13837            didSomething |= queue.sendPendingBroadcastsLocked(app);
13838        }
13839        return didSomething;
13840    }
13841
13842    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13843            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13844        enforceNotIsolatedCaller("registerReceiver");
13845        int callingUid;
13846        int callingPid;
13847        synchronized(this) {
13848            ProcessRecord callerApp = null;
13849            if (caller != null) {
13850                callerApp = getRecordForAppLocked(caller);
13851                if (callerApp == null) {
13852                    throw new SecurityException(
13853                            "Unable to find app for caller " + caller
13854                            + " (pid=" + Binder.getCallingPid()
13855                            + ") when registering receiver " + receiver);
13856                }
13857                if (callerApp.info.uid != Process.SYSTEM_UID &&
13858                        !callerApp.pkgList.containsKey(callerPackage) &&
13859                        !"android".equals(callerPackage)) {
13860                    throw new SecurityException("Given caller package " + callerPackage
13861                            + " is not running in process " + callerApp);
13862                }
13863                callingUid = callerApp.info.uid;
13864                callingPid = callerApp.pid;
13865            } else {
13866                callerPackage = null;
13867                callingUid = Binder.getCallingUid();
13868                callingPid = Binder.getCallingPid();
13869            }
13870
13871            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13872                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13873
13874            List allSticky = null;
13875
13876            // Look for any matching sticky broadcasts...
13877            Iterator actions = filter.actionsIterator();
13878            if (actions != null) {
13879                while (actions.hasNext()) {
13880                    String action = (String)actions.next();
13881                    allSticky = getStickiesLocked(action, filter, allSticky,
13882                            UserHandle.USER_ALL);
13883                    allSticky = getStickiesLocked(action, filter, allSticky,
13884                            UserHandle.getUserId(callingUid));
13885                }
13886            } else {
13887                allSticky = getStickiesLocked(null, filter, allSticky,
13888                        UserHandle.USER_ALL);
13889                allSticky = getStickiesLocked(null, filter, allSticky,
13890                        UserHandle.getUserId(callingUid));
13891            }
13892
13893            // The first sticky in the list is returned directly back to
13894            // the client.
13895            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13896
13897            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13898                    + ": " + sticky);
13899
13900            if (receiver == null) {
13901                return sticky;
13902            }
13903
13904            ReceiverList rl
13905                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13906            if (rl == null) {
13907                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13908                        userId, receiver);
13909                if (rl.app != null) {
13910                    rl.app.receivers.add(rl);
13911                } else {
13912                    try {
13913                        receiver.asBinder().linkToDeath(rl, 0);
13914                    } catch (RemoteException e) {
13915                        return sticky;
13916                    }
13917                    rl.linkedToDeath = true;
13918                }
13919                mRegisteredReceivers.put(receiver.asBinder(), rl);
13920            } else if (rl.uid != callingUid) {
13921                throw new IllegalArgumentException(
13922                        "Receiver requested to register for uid " + callingUid
13923                        + " was previously registered for uid " + rl.uid);
13924            } else if (rl.pid != callingPid) {
13925                throw new IllegalArgumentException(
13926                        "Receiver requested to register for pid " + callingPid
13927                        + " was previously registered for pid " + rl.pid);
13928            } else if (rl.userId != userId) {
13929                throw new IllegalArgumentException(
13930                        "Receiver requested to register for user " + userId
13931                        + " was previously registered for user " + rl.userId);
13932            }
13933            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13934                    permission, callingUid, userId);
13935            rl.add(bf);
13936            if (!bf.debugCheck()) {
13937                Slog.w(TAG, "==> For Dynamic broadast");
13938            }
13939            mReceiverResolver.addFilter(bf);
13940
13941            // Enqueue broadcasts for all existing stickies that match
13942            // this filter.
13943            if (allSticky != null) {
13944                ArrayList receivers = new ArrayList();
13945                receivers.add(bf);
13946
13947                int N = allSticky.size();
13948                for (int i=0; i<N; i++) {
13949                    Intent intent = (Intent)allSticky.get(i);
13950                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13951                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13952                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13953                            null, null, false, true, true, -1);
13954                    queue.enqueueParallelBroadcastLocked(r);
13955                    queue.scheduleBroadcastsLocked();
13956                }
13957            }
13958
13959            return sticky;
13960        }
13961    }
13962
13963    public void unregisterReceiver(IIntentReceiver receiver) {
13964        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13965
13966        final long origId = Binder.clearCallingIdentity();
13967        try {
13968            boolean doTrim = false;
13969
13970            synchronized(this) {
13971                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13972                if (rl != null) {
13973                    if (rl.curBroadcast != null) {
13974                        BroadcastRecord r = rl.curBroadcast;
13975                        final boolean doNext = finishReceiverLocked(
13976                                receiver.asBinder(), r.resultCode, r.resultData,
13977                                r.resultExtras, r.resultAbort);
13978                        if (doNext) {
13979                            doTrim = true;
13980                            r.queue.processNextBroadcast(false);
13981                        }
13982                    }
13983
13984                    if (rl.app != null) {
13985                        rl.app.receivers.remove(rl);
13986                    }
13987                    removeReceiverLocked(rl);
13988                    if (rl.linkedToDeath) {
13989                        rl.linkedToDeath = false;
13990                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13991                    }
13992                }
13993            }
13994
13995            // If we actually concluded any broadcasts, we might now be able
13996            // to trim the recipients' apps from our working set
13997            if (doTrim) {
13998                trimApplications();
13999                return;
14000            }
14001
14002        } finally {
14003            Binder.restoreCallingIdentity(origId);
14004        }
14005    }
14006
14007    void removeReceiverLocked(ReceiverList rl) {
14008        mRegisteredReceivers.remove(rl.receiver.asBinder());
14009        int N = rl.size();
14010        for (int i=0; i<N; i++) {
14011            mReceiverResolver.removeFilter(rl.get(i));
14012        }
14013    }
14014
14015    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14016        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14017            ProcessRecord r = mLruProcesses.get(i);
14018            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14019                try {
14020                    r.thread.dispatchPackageBroadcast(cmd, packages);
14021                } catch (RemoteException ex) {
14022                }
14023            }
14024        }
14025    }
14026
14027    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14028            int[] users) {
14029        List<ResolveInfo> receivers = null;
14030        try {
14031            HashSet<ComponentName> singleUserReceivers = null;
14032            boolean scannedFirstReceivers = false;
14033            for (int user : users) {
14034                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14035                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14036                if (user != 0 && newReceivers != null) {
14037                    // If this is not the primary user, we need to check for
14038                    // any receivers that should be filtered out.
14039                    for (int i=0; i<newReceivers.size(); i++) {
14040                        ResolveInfo ri = newReceivers.get(i);
14041                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14042                            newReceivers.remove(i);
14043                            i--;
14044                        }
14045                    }
14046                }
14047                if (newReceivers != null && newReceivers.size() == 0) {
14048                    newReceivers = null;
14049                }
14050                if (receivers == null) {
14051                    receivers = newReceivers;
14052                } else if (newReceivers != null) {
14053                    // We need to concatenate the additional receivers
14054                    // found with what we have do far.  This would be easy,
14055                    // but we also need to de-dup any receivers that are
14056                    // singleUser.
14057                    if (!scannedFirstReceivers) {
14058                        // Collect any single user receivers we had already retrieved.
14059                        scannedFirstReceivers = true;
14060                        for (int i=0; i<receivers.size(); i++) {
14061                            ResolveInfo ri = receivers.get(i);
14062                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14063                                ComponentName cn = new ComponentName(
14064                                        ri.activityInfo.packageName, ri.activityInfo.name);
14065                                if (singleUserReceivers == null) {
14066                                    singleUserReceivers = new HashSet<ComponentName>();
14067                                }
14068                                singleUserReceivers.add(cn);
14069                            }
14070                        }
14071                    }
14072                    // Add the new results to the existing results, tracking
14073                    // and de-dupping single user receivers.
14074                    for (int i=0; i<newReceivers.size(); i++) {
14075                        ResolveInfo ri = newReceivers.get(i);
14076                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14077                            ComponentName cn = new ComponentName(
14078                                    ri.activityInfo.packageName, ri.activityInfo.name);
14079                            if (singleUserReceivers == null) {
14080                                singleUserReceivers = new HashSet<ComponentName>();
14081                            }
14082                            if (!singleUserReceivers.contains(cn)) {
14083                                singleUserReceivers.add(cn);
14084                                receivers.add(ri);
14085                            }
14086                        } else {
14087                            receivers.add(ri);
14088                        }
14089                    }
14090                }
14091            }
14092        } catch (RemoteException ex) {
14093            // pm is in same process, this will never happen.
14094        }
14095        return receivers;
14096    }
14097
14098    private final int broadcastIntentLocked(ProcessRecord callerApp,
14099            String callerPackage, Intent intent, String resolvedType,
14100            IIntentReceiver resultTo, int resultCode, String resultData,
14101            Bundle map, String requiredPermission, int appOp,
14102            boolean ordered, boolean sticky, int callingPid, int callingUid,
14103            int userId) {
14104        intent = new Intent(intent);
14105
14106        // By default broadcasts do not go to stopped apps.
14107        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14108
14109        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14110            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14111            + " ordered=" + ordered + " userid=" + userId);
14112        if ((resultTo != null) && !ordered) {
14113            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14114        }
14115
14116        userId = handleIncomingUser(callingPid, callingUid, userId,
14117                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14118
14119        // Make sure that the user who is receiving this broadcast is started.
14120        // If not, we will just skip it.
14121
14122
14123        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14124            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14125                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14126                Slog.w(TAG, "Skipping broadcast of " + intent
14127                        + ": user " + userId + " is stopped");
14128                return ActivityManager.BROADCAST_SUCCESS;
14129            }
14130        }
14131
14132        /*
14133         * Prevent non-system code (defined here to be non-persistent
14134         * processes) from sending protected broadcasts.
14135         */
14136        int callingAppId = UserHandle.getAppId(callingUid);
14137        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14138            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14139            || callingAppId == Process.NFC_UID || callingUid == 0) {
14140            // Always okay.
14141        } else if (callerApp == null || !callerApp.persistent) {
14142            try {
14143                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14144                        intent.getAction())) {
14145                    String msg = "Permission Denial: not allowed to send broadcast "
14146                            + intent.getAction() + " from pid="
14147                            + callingPid + ", uid=" + callingUid;
14148                    Slog.w(TAG, msg);
14149                    throw new SecurityException(msg);
14150                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14151                    // Special case for compatibility: we don't want apps to send this,
14152                    // but historically it has not been protected and apps may be using it
14153                    // to poke their own app widget.  So, instead of making it protected,
14154                    // just limit it to the caller.
14155                    if (callerApp == null) {
14156                        String msg = "Permission Denial: not allowed to send broadcast "
14157                                + intent.getAction() + " from unknown caller.";
14158                        Slog.w(TAG, msg);
14159                        throw new SecurityException(msg);
14160                    } else if (intent.getComponent() != null) {
14161                        // They are good enough to send to an explicit component...  verify
14162                        // it is being sent to the calling app.
14163                        if (!intent.getComponent().getPackageName().equals(
14164                                callerApp.info.packageName)) {
14165                            String msg = "Permission Denial: not allowed to send broadcast "
14166                                    + intent.getAction() + " to "
14167                                    + intent.getComponent().getPackageName() + " from "
14168                                    + callerApp.info.packageName;
14169                            Slog.w(TAG, msg);
14170                            throw new SecurityException(msg);
14171                        }
14172                    } else {
14173                        // Limit broadcast to their own package.
14174                        intent.setPackage(callerApp.info.packageName);
14175                    }
14176                }
14177            } catch (RemoteException e) {
14178                Slog.w(TAG, "Remote exception", e);
14179                return ActivityManager.BROADCAST_SUCCESS;
14180            }
14181        }
14182
14183        // Handle special intents: if this broadcast is from the package
14184        // manager about a package being removed, we need to remove all of
14185        // its activities from the history stack.
14186        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14187                intent.getAction());
14188        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14189                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14190                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14191                || uidRemoved) {
14192            if (checkComponentPermission(
14193                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14194                    callingPid, callingUid, -1, true)
14195                    == PackageManager.PERMISSION_GRANTED) {
14196                if (uidRemoved) {
14197                    final Bundle intentExtras = intent.getExtras();
14198                    final int uid = intentExtras != null
14199                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14200                    if (uid >= 0) {
14201                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14202                        synchronized (bs) {
14203                            bs.removeUidStatsLocked(uid);
14204                        }
14205                        mAppOpsService.uidRemoved(uid);
14206                    }
14207                } else {
14208                    // If resources are unavailable just force stop all
14209                    // those packages and flush the attribute cache as well.
14210                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14211                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14212                        if (list != null && (list.length > 0)) {
14213                            for (String pkg : list) {
14214                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14215                                        "storage unmount");
14216                            }
14217                            sendPackageBroadcastLocked(
14218                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14219                        }
14220                    } else {
14221                        Uri data = intent.getData();
14222                        String ssp;
14223                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14224                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14225                                    intent.getAction());
14226                            boolean fullUninstall = removed &&
14227                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14228                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14229                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14230                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14231                                        false, fullUninstall, userId,
14232                                        removed ? "pkg removed" : "pkg changed");
14233                            }
14234                            if (removed) {
14235                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14236                                        new String[] {ssp}, userId);
14237                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14238                                    mAppOpsService.packageRemoved(
14239                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14240
14241                                    // Remove all permissions granted from/to this package
14242                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14243                                }
14244                            }
14245                        }
14246                    }
14247                }
14248            } else {
14249                String msg = "Permission Denial: " + intent.getAction()
14250                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14251                        + ", uid=" + callingUid + ")"
14252                        + " requires "
14253                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14254                Slog.w(TAG, msg);
14255                throw new SecurityException(msg);
14256            }
14257
14258        // Special case for adding a package: by default turn on compatibility
14259        // mode.
14260        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14261            Uri data = intent.getData();
14262            String ssp;
14263            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14264                mCompatModePackages.handlePackageAddedLocked(ssp,
14265                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14266            }
14267        }
14268
14269        /*
14270         * If this is the time zone changed action, queue up a message that will reset the timezone
14271         * of all currently running processes. This message will get queued up before the broadcast
14272         * happens.
14273         */
14274        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14275            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14276        }
14277
14278        /*
14279         * If the user set the time, let all running processes know.
14280         */
14281        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14282            final int is24Hour = intent.getBooleanExtra(
14283                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14284            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14285        }
14286
14287        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14288            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14289        }
14290
14291        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14292            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14293            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14294        }
14295
14296        // Add to the sticky list if requested.
14297        if (sticky) {
14298            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14299                    callingPid, callingUid)
14300                    != PackageManager.PERMISSION_GRANTED) {
14301                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14302                        + callingPid + ", uid=" + callingUid
14303                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14304                Slog.w(TAG, msg);
14305                throw new SecurityException(msg);
14306            }
14307            if (requiredPermission != null) {
14308                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14309                        + " and enforce permission " + requiredPermission);
14310                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14311            }
14312            if (intent.getComponent() != null) {
14313                throw new SecurityException(
14314                        "Sticky broadcasts can't target a specific component");
14315            }
14316            // We use userId directly here, since the "all" target is maintained
14317            // as a separate set of sticky broadcasts.
14318            if (userId != UserHandle.USER_ALL) {
14319                // But first, if this is not a broadcast to all users, then
14320                // make sure it doesn't conflict with an existing broadcast to
14321                // all users.
14322                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14323                        UserHandle.USER_ALL);
14324                if (stickies != null) {
14325                    ArrayList<Intent> list = stickies.get(intent.getAction());
14326                    if (list != null) {
14327                        int N = list.size();
14328                        int i;
14329                        for (i=0; i<N; i++) {
14330                            if (intent.filterEquals(list.get(i))) {
14331                                throw new IllegalArgumentException(
14332                                        "Sticky broadcast " + intent + " for user "
14333                                        + userId + " conflicts with existing global broadcast");
14334                            }
14335                        }
14336                    }
14337                }
14338            }
14339            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14340            if (stickies == null) {
14341                stickies = new ArrayMap<String, ArrayList<Intent>>();
14342                mStickyBroadcasts.put(userId, stickies);
14343            }
14344            ArrayList<Intent> list = stickies.get(intent.getAction());
14345            if (list == null) {
14346                list = new ArrayList<Intent>();
14347                stickies.put(intent.getAction(), list);
14348            }
14349            int N = list.size();
14350            int i;
14351            for (i=0; i<N; i++) {
14352                if (intent.filterEquals(list.get(i))) {
14353                    // This sticky already exists, replace it.
14354                    list.set(i, new Intent(intent));
14355                    break;
14356                }
14357            }
14358            if (i >= N) {
14359                list.add(new Intent(intent));
14360            }
14361        }
14362
14363        int[] users;
14364        if (userId == UserHandle.USER_ALL) {
14365            // Caller wants broadcast to go to all started users.
14366            users = mStartedUserArray;
14367        } else {
14368            // Caller wants broadcast to go to one specific user.
14369            users = new int[] {userId};
14370        }
14371
14372        // Figure out who all will receive this broadcast.
14373        List receivers = null;
14374        List<BroadcastFilter> registeredReceivers = null;
14375        // Need to resolve the intent to interested receivers...
14376        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14377                 == 0) {
14378            receivers = collectReceiverComponents(intent, resolvedType, users);
14379        }
14380        if (intent.getComponent() == null) {
14381            registeredReceivers = mReceiverResolver.queryIntent(intent,
14382                    resolvedType, false, userId);
14383        }
14384
14385        final boolean replacePending =
14386                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14387
14388        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14389                + " replacePending=" + replacePending);
14390
14391        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14392        if (!ordered && NR > 0) {
14393            // If we are not serializing this broadcast, then send the
14394            // registered receivers separately so they don't wait for the
14395            // components to be launched.
14396            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14397            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14398                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14399                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14400                    ordered, sticky, false, userId);
14401            if (DEBUG_BROADCAST) Slog.v(
14402                    TAG, "Enqueueing parallel broadcast " + r);
14403            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14404            if (!replaced) {
14405                queue.enqueueParallelBroadcastLocked(r);
14406                queue.scheduleBroadcastsLocked();
14407            }
14408            registeredReceivers = null;
14409            NR = 0;
14410        }
14411
14412        // Merge into one list.
14413        int ir = 0;
14414        if (receivers != null) {
14415            // A special case for PACKAGE_ADDED: do not allow the package
14416            // being added to see this broadcast.  This prevents them from
14417            // using this as a back door to get run as soon as they are
14418            // installed.  Maybe in the future we want to have a special install
14419            // broadcast or such for apps, but we'd like to deliberately make
14420            // this decision.
14421            String skipPackages[] = null;
14422            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14423                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14424                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14425                Uri data = intent.getData();
14426                if (data != null) {
14427                    String pkgName = data.getSchemeSpecificPart();
14428                    if (pkgName != null) {
14429                        skipPackages = new String[] { pkgName };
14430                    }
14431                }
14432            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14433                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14434            }
14435            if (skipPackages != null && (skipPackages.length > 0)) {
14436                for (String skipPackage : skipPackages) {
14437                    if (skipPackage != null) {
14438                        int NT = receivers.size();
14439                        for (int it=0; it<NT; it++) {
14440                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14441                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14442                                receivers.remove(it);
14443                                it--;
14444                                NT--;
14445                            }
14446                        }
14447                    }
14448                }
14449            }
14450
14451            int NT = receivers != null ? receivers.size() : 0;
14452            int it = 0;
14453            ResolveInfo curt = null;
14454            BroadcastFilter curr = null;
14455            while (it < NT && ir < NR) {
14456                if (curt == null) {
14457                    curt = (ResolveInfo)receivers.get(it);
14458                }
14459                if (curr == null) {
14460                    curr = registeredReceivers.get(ir);
14461                }
14462                if (curr.getPriority() >= curt.priority) {
14463                    // Insert this broadcast record into the final list.
14464                    receivers.add(it, curr);
14465                    ir++;
14466                    curr = null;
14467                    it++;
14468                    NT++;
14469                } else {
14470                    // Skip to the next ResolveInfo in the final list.
14471                    it++;
14472                    curt = null;
14473                }
14474            }
14475        }
14476        while (ir < NR) {
14477            if (receivers == null) {
14478                receivers = new ArrayList();
14479            }
14480            receivers.add(registeredReceivers.get(ir));
14481            ir++;
14482        }
14483
14484        if ((receivers != null && receivers.size() > 0)
14485                || resultTo != null) {
14486            BroadcastQueue queue = broadcastQueueForIntent(intent);
14487            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14488                    callerPackage, callingPid, callingUid, resolvedType,
14489                    requiredPermission, appOp, receivers, resultTo, resultCode,
14490                    resultData, map, ordered, sticky, false, userId);
14491            if (DEBUG_BROADCAST) Slog.v(
14492                    TAG, "Enqueueing ordered broadcast " + r
14493                    + ": prev had " + queue.mOrderedBroadcasts.size());
14494            if (DEBUG_BROADCAST) {
14495                int seq = r.intent.getIntExtra("seq", -1);
14496                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14497            }
14498            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14499            if (!replaced) {
14500                queue.enqueueOrderedBroadcastLocked(r);
14501                queue.scheduleBroadcastsLocked();
14502            }
14503        }
14504
14505        return ActivityManager.BROADCAST_SUCCESS;
14506    }
14507
14508    final Intent verifyBroadcastLocked(Intent intent) {
14509        // Refuse possible leaked file descriptors
14510        if (intent != null && intent.hasFileDescriptors() == true) {
14511            throw new IllegalArgumentException("File descriptors passed in Intent");
14512        }
14513
14514        int flags = intent.getFlags();
14515
14516        if (!mProcessesReady) {
14517            // if the caller really truly claims to know what they're doing, go
14518            // ahead and allow the broadcast without launching any receivers
14519            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14520                intent = new Intent(intent);
14521                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14522            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14523                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14524                        + " before boot completion");
14525                throw new IllegalStateException("Cannot broadcast before boot completed");
14526            }
14527        }
14528
14529        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14530            throw new IllegalArgumentException(
14531                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14532        }
14533
14534        return intent;
14535    }
14536
14537    public final int broadcastIntent(IApplicationThread caller,
14538            Intent intent, String resolvedType, IIntentReceiver resultTo,
14539            int resultCode, String resultData, Bundle map,
14540            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14541        enforceNotIsolatedCaller("broadcastIntent");
14542        synchronized(this) {
14543            intent = verifyBroadcastLocked(intent);
14544
14545            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14546            final int callingPid = Binder.getCallingPid();
14547            final int callingUid = Binder.getCallingUid();
14548            final long origId = Binder.clearCallingIdentity();
14549            int res = broadcastIntentLocked(callerApp,
14550                    callerApp != null ? callerApp.info.packageName : null,
14551                    intent, resolvedType, resultTo,
14552                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14553                    callingPid, callingUid, userId);
14554            Binder.restoreCallingIdentity(origId);
14555            return res;
14556        }
14557    }
14558
14559    int broadcastIntentInPackage(String packageName, int uid,
14560            Intent intent, String resolvedType, IIntentReceiver resultTo,
14561            int resultCode, String resultData, Bundle map,
14562            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14563        synchronized(this) {
14564            intent = verifyBroadcastLocked(intent);
14565
14566            final long origId = Binder.clearCallingIdentity();
14567            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14568                    resultTo, resultCode, resultData, map, requiredPermission,
14569                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14570            Binder.restoreCallingIdentity(origId);
14571            return res;
14572        }
14573    }
14574
14575    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14576        // Refuse possible leaked file descriptors
14577        if (intent != null && intent.hasFileDescriptors() == true) {
14578            throw new IllegalArgumentException("File descriptors passed in Intent");
14579        }
14580
14581        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14582                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14583
14584        synchronized(this) {
14585            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14586                    != PackageManager.PERMISSION_GRANTED) {
14587                String msg = "Permission Denial: unbroadcastIntent() from pid="
14588                        + Binder.getCallingPid()
14589                        + ", uid=" + Binder.getCallingUid()
14590                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14591                Slog.w(TAG, msg);
14592                throw new SecurityException(msg);
14593            }
14594            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14595            if (stickies != null) {
14596                ArrayList<Intent> list = stickies.get(intent.getAction());
14597                if (list != null) {
14598                    int N = list.size();
14599                    int i;
14600                    for (i=0; i<N; i++) {
14601                        if (intent.filterEquals(list.get(i))) {
14602                            list.remove(i);
14603                            break;
14604                        }
14605                    }
14606                    if (list.size() <= 0) {
14607                        stickies.remove(intent.getAction());
14608                    }
14609                }
14610                if (stickies.size() <= 0) {
14611                    mStickyBroadcasts.remove(userId);
14612                }
14613            }
14614        }
14615    }
14616
14617    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14618            String resultData, Bundle resultExtras, boolean resultAbort) {
14619        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14620        if (r == null) {
14621            Slog.w(TAG, "finishReceiver called but not found on queue");
14622            return false;
14623        }
14624
14625        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14626    }
14627
14628    void backgroundServicesFinishedLocked(int userId) {
14629        for (BroadcastQueue queue : mBroadcastQueues) {
14630            queue.backgroundServicesFinishedLocked(userId);
14631        }
14632    }
14633
14634    public void finishReceiver(IBinder who, int resultCode, String resultData,
14635            Bundle resultExtras, boolean resultAbort) {
14636        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14637
14638        // Refuse possible leaked file descriptors
14639        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14640            throw new IllegalArgumentException("File descriptors passed in Bundle");
14641        }
14642
14643        final long origId = Binder.clearCallingIdentity();
14644        try {
14645            boolean doNext = false;
14646            BroadcastRecord r;
14647
14648            synchronized(this) {
14649                r = broadcastRecordForReceiverLocked(who);
14650                if (r != null) {
14651                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14652                        resultData, resultExtras, resultAbort, true);
14653                }
14654            }
14655
14656            if (doNext) {
14657                r.queue.processNextBroadcast(false);
14658            }
14659            trimApplications();
14660        } finally {
14661            Binder.restoreCallingIdentity(origId);
14662        }
14663    }
14664
14665    // =========================================================
14666    // INSTRUMENTATION
14667    // =========================================================
14668
14669    public boolean startInstrumentation(ComponentName className,
14670            String profileFile, int flags, Bundle arguments,
14671            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14672            int userId, String abiOverride) {
14673        enforceNotIsolatedCaller("startInstrumentation");
14674        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14675                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14676        // Refuse possible leaked file descriptors
14677        if (arguments != null && arguments.hasFileDescriptors()) {
14678            throw new IllegalArgumentException("File descriptors passed in Bundle");
14679        }
14680
14681        synchronized(this) {
14682            InstrumentationInfo ii = null;
14683            ApplicationInfo ai = null;
14684            try {
14685                ii = mContext.getPackageManager().getInstrumentationInfo(
14686                    className, STOCK_PM_FLAGS);
14687                ai = AppGlobals.getPackageManager().getApplicationInfo(
14688                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14689            } catch (PackageManager.NameNotFoundException e) {
14690            } catch (RemoteException e) {
14691            }
14692            if (ii == null) {
14693                reportStartInstrumentationFailure(watcher, className,
14694                        "Unable to find instrumentation info for: " + className);
14695                return false;
14696            }
14697            if (ai == null) {
14698                reportStartInstrumentationFailure(watcher, className,
14699                        "Unable to find instrumentation target package: " + ii.targetPackage);
14700                return false;
14701            }
14702
14703            int match = mContext.getPackageManager().checkSignatures(
14704                    ii.targetPackage, ii.packageName);
14705            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14706                String msg = "Permission Denial: starting instrumentation "
14707                        + className + " from pid="
14708                        + Binder.getCallingPid()
14709                        + ", uid=" + Binder.getCallingPid()
14710                        + " not allowed because package " + ii.packageName
14711                        + " does not have a signature matching the target "
14712                        + ii.targetPackage;
14713                reportStartInstrumentationFailure(watcher, className, msg);
14714                throw new SecurityException(msg);
14715            }
14716
14717            final long origId = Binder.clearCallingIdentity();
14718            // Instrumentation can kill and relaunch even persistent processes
14719            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14720                    "start instr");
14721            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14722            app.instrumentationClass = className;
14723            app.instrumentationInfo = ai;
14724            app.instrumentationProfileFile = profileFile;
14725            app.instrumentationArguments = arguments;
14726            app.instrumentationWatcher = watcher;
14727            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14728            app.instrumentationResultClass = className;
14729            Binder.restoreCallingIdentity(origId);
14730        }
14731
14732        return true;
14733    }
14734
14735    /**
14736     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14737     * error to the logs, but if somebody is watching, send the report there too.  This enables
14738     * the "am" command to report errors with more information.
14739     *
14740     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14741     * @param cn The component name of the instrumentation.
14742     * @param report The error report.
14743     */
14744    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14745            ComponentName cn, String report) {
14746        Slog.w(TAG, report);
14747        try {
14748            if (watcher != null) {
14749                Bundle results = new Bundle();
14750                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14751                results.putString("Error", report);
14752                watcher.instrumentationStatus(cn, -1, results);
14753            }
14754        } catch (RemoteException e) {
14755            Slog.w(TAG, e);
14756        }
14757    }
14758
14759    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14760        if (app.instrumentationWatcher != null) {
14761            try {
14762                // NOTE:  IInstrumentationWatcher *must* be oneway here
14763                app.instrumentationWatcher.instrumentationFinished(
14764                    app.instrumentationClass,
14765                    resultCode,
14766                    results);
14767            } catch (RemoteException e) {
14768            }
14769        }
14770        if (app.instrumentationUiAutomationConnection != null) {
14771            try {
14772                app.instrumentationUiAutomationConnection.shutdown();
14773            } catch (RemoteException re) {
14774                /* ignore */
14775            }
14776            // Only a UiAutomation can set this flag and now that
14777            // it is finished we make sure it is reset to its default.
14778            mUserIsMonkey = false;
14779        }
14780        app.instrumentationWatcher = null;
14781        app.instrumentationUiAutomationConnection = null;
14782        app.instrumentationClass = null;
14783        app.instrumentationInfo = null;
14784        app.instrumentationProfileFile = null;
14785        app.instrumentationArguments = null;
14786
14787        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14788                "finished inst");
14789    }
14790
14791    public void finishInstrumentation(IApplicationThread target,
14792            int resultCode, Bundle results) {
14793        int userId = UserHandle.getCallingUserId();
14794        // Refuse possible leaked file descriptors
14795        if (results != null && results.hasFileDescriptors()) {
14796            throw new IllegalArgumentException("File descriptors passed in Intent");
14797        }
14798
14799        synchronized(this) {
14800            ProcessRecord app = getRecordForAppLocked(target);
14801            if (app == null) {
14802                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14803                return;
14804            }
14805            final long origId = Binder.clearCallingIdentity();
14806            finishInstrumentationLocked(app, resultCode, results);
14807            Binder.restoreCallingIdentity(origId);
14808        }
14809    }
14810
14811    // =========================================================
14812    // CONFIGURATION
14813    // =========================================================
14814
14815    public ConfigurationInfo getDeviceConfigurationInfo() {
14816        ConfigurationInfo config = new ConfigurationInfo();
14817        synchronized (this) {
14818            config.reqTouchScreen = mConfiguration.touchscreen;
14819            config.reqKeyboardType = mConfiguration.keyboard;
14820            config.reqNavigation = mConfiguration.navigation;
14821            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14822                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14823                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14824            }
14825            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14826                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14827                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14828            }
14829            config.reqGlEsVersion = GL_ES_VERSION;
14830        }
14831        return config;
14832    }
14833
14834    ActivityStack getFocusedStack() {
14835        return mStackSupervisor.getFocusedStack();
14836    }
14837
14838    public Configuration getConfiguration() {
14839        Configuration ci;
14840        synchronized(this) {
14841            ci = new Configuration(mConfiguration);
14842        }
14843        return ci;
14844    }
14845
14846    public void updatePersistentConfiguration(Configuration values) {
14847        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14848                "updateConfiguration()");
14849        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14850                "updateConfiguration()");
14851        if (values == null) {
14852            throw new NullPointerException("Configuration must not be null");
14853        }
14854
14855        synchronized(this) {
14856            final long origId = Binder.clearCallingIdentity();
14857            updateConfigurationLocked(values, null, true, false);
14858            Binder.restoreCallingIdentity(origId);
14859        }
14860    }
14861
14862    public void updateConfiguration(Configuration values) {
14863        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14864                "updateConfiguration()");
14865
14866        synchronized(this) {
14867            if (values == null && mWindowManager != null) {
14868                // sentinel: fetch the current configuration from the window manager
14869                values = mWindowManager.computeNewConfiguration();
14870            }
14871
14872            if (mWindowManager != null) {
14873                mProcessList.applyDisplaySize(mWindowManager);
14874            }
14875
14876            final long origId = Binder.clearCallingIdentity();
14877            if (values != null) {
14878                Settings.System.clearConfiguration(values);
14879            }
14880            updateConfigurationLocked(values, null, false, false);
14881            Binder.restoreCallingIdentity(origId);
14882        }
14883    }
14884
14885    /**
14886     * Do either or both things: (1) change the current configuration, and (2)
14887     * make sure the given activity is running with the (now) current
14888     * configuration.  Returns true if the activity has been left running, or
14889     * false if <var>starting</var> is being destroyed to match the new
14890     * configuration.
14891     * @param persistent TODO
14892     */
14893    boolean updateConfigurationLocked(Configuration values,
14894            ActivityRecord starting, boolean persistent, boolean initLocale) {
14895        int changes = 0;
14896
14897        if (values != null) {
14898            Configuration newConfig = new Configuration(mConfiguration);
14899            changes = newConfig.updateFrom(values);
14900            if (changes != 0) {
14901                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14902                    Slog.i(TAG, "Updating configuration to: " + values);
14903                }
14904
14905                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14906
14907                if (values.locale != null && !initLocale) {
14908                    saveLocaleLocked(values.locale,
14909                                     !values.locale.equals(mConfiguration.locale),
14910                                     values.userSetLocale);
14911                }
14912
14913                mConfigurationSeq++;
14914                if (mConfigurationSeq <= 0) {
14915                    mConfigurationSeq = 1;
14916                }
14917                newConfig.seq = mConfigurationSeq;
14918                mConfiguration = newConfig;
14919                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14920                mUsageStatsService.noteStartConfig(newConfig);
14921
14922                final Configuration configCopy = new Configuration(mConfiguration);
14923
14924                // TODO: If our config changes, should we auto dismiss any currently
14925                // showing dialogs?
14926                mShowDialogs = shouldShowDialogs(newConfig);
14927
14928                AttributeCache ac = AttributeCache.instance();
14929                if (ac != null) {
14930                    ac.updateConfiguration(configCopy);
14931                }
14932
14933                // Make sure all resources in our process are updated
14934                // right now, so that anyone who is going to retrieve
14935                // resource values after we return will be sure to get
14936                // the new ones.  This is especially important during
14937                // boot, where the first config change needs to guarantee
14938                // all resources have that config before following boot
14939                // code is executed.
14940                mSystemThread.applyConfigurationToResources(configCopy);
14941
14942                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14943                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14944                    msg.obj = new Configuration(configCopy);
14945                    mHandler.sendMessage(msg);
14946                }
14947
14948                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14949                    ProcessRecord app = mLruProcesses.get(i);
14950                    try {
14951                        if (app.thread != null) {
14952                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14953                                    + app.processName + " new config " + mConfiguration);
14954                            app.thread.scheduleConfigurationChanged(configCopy);
14955                        }
14956                    } catch (Exception e) {
14957                    }
14958                }
14959                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14960                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14961                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14962                        | Intent.FLAG_RECEIVER_FOREGROUND);
14963                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14964                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14965                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14966                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14967                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14968                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14969                    broadcastIntentLocked(null, null, intent,
14970                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14971                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14972                }
14973            }
14974        }
14975
14976        boolean kept = true;
14977        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14978        // mainStack is null during startup.
14979        if (mainStack != null) {
14980            if (changes != 0 && starting == null) {
14981                // If the configuration changed, and the caller is not already
14982                // in the process of starting an activity, then find the top
14983                // activity to check if its configuration needs to change.
14984                starting = mainStack.topRunningActivityLocked(null);
14985            }
14986
14987            if (starting != null) {
14988                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14989                // And we need to make sure at this point that all other activities
14990                // are made visible with the correct configuration.
14991                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14992            }
14993        }
14994
14995        if (values != null && mWindowManager != null) {
14996            mWindowManager.setNewConfiguration(mConfiguration);
14997        }
14998
14999        return kept;
15000    }
15001
15002    /**
15003     * Decide based on the configuration whether we should shouw the ANR,
15004     * crash, etc dialogs.  The idea is that if there is no affordnace to
15005     * press the on-screen buttons, we shouldn't show the dialog.
15006     *
15007     * A thought: SystemUI might also want to get told about this, the Power
15008     * dialog / global actions also might want different behaviors.
15009     */
15010    private static final boolean shouldShowDialogs(Configuration config) {
15011        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15012                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15013    }
15014
15015    /**
15016     * Save the locale.  You must be inside a synchronized (this) block.
15017     */
15018    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15019        if(isDiff) {
15020            SystemProperties.set("user.language", l.getLanguage());
15021            SystemProperties.set("user.region", l.getCountry());
15022        }
15023
15024        if(isPersist) {
15025            SystemProperties.set("persist.sys.language", l.getLanguage());
15026            SystemProperties.set("persist.sys.country", l.getCountry());
15027            SystemProperties.set("persist.sys.localevar", l.getVariant());
15028        }
15029    }
15030
15031    @Override
15032    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15033        ActivityRecord srec = ActivityRecord.forToken(token);
15034        return srec != null && srec.task.affinity != null &&
15035                srec.task.affinity.equals(destAffinity);
15036    }
15037
15038    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15039            Intent resultData) {
15040
15041        synchronized (this) {
15042            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15043            if (stack != null) {
15044                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15045            }
15046            return false;
15047        }
15048    }
15049
15050    public int getLaunchedFromUid(IBinder activityToken) {
15051        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15052        if (srec == null) {
15053            return -1;
15054        }
15055        return srec.launchedFromUid;
15056    }
15057
15058    public String getLaunchedFromPackage(IBinder activityToken) {
15059        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15060        if (srec == null) {
15061            return null;
15062        }
15063        return srec.launchedFromPackage;
15064    }
15065
15066    // =========================================================
15067    // LIFETIME MANAGEMENT
15068    // =========================================================
15069
15070    // Returns which broadcast queue the app is the current [or imminent] receiver
15071    // on, or 'null' if the app is not an active broadcast recipient.
15072    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15073        BroadcastRecord r = app.curReceiver;
15074        if (r != null) {
15075            return r.queue;
15076        }
15077
15078        // It's not the current receiver, but it might be starting up to become one
15079        synchronized (this) {
15080            for (BroadcastQueue queue : mBroadcastQueues) {
15081                r = queue.mPendingBroadcast;
15082                if (r != null && r.curApp == app) {
15083                    // found it; report which queue it's in
15084                    return queue;
15085                }
15086            }
15087        }
15088
15089        return null;
15090    }
15091
15092    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15093            boolean doingAll, long now) {
15094        if (mAdjSeq == app.adjSeq) {
15095            // This adjustment has already been computed.
15096            return app.curRawAdj;
15097        }
15098
15099        if (app.thread == null) {
15100            app.adjSeq = mAdjSeq;
15101            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15102            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15103            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15104        }
15105
15106        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15107        app.adjSource = null;
15108        app.adjTarget = null;
15109        app.empty = false;
15110        app.cached = false;
15111
15112        final int activitiesSize = app.activities.size();
15113
15114        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15115            // The max adjustment doesn't allow this app to be anything
15116            // below foreground, so it is not worth doing work for it.
15117            app.adjType = "fixed";
15118            app.adjSeq = mAdjSeq;
15119            app.curRawAdj = app.maxAdj;
15120            app.foregroundActivities = false;
15121            app.keeping = true;
15122            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15123            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15124            // System processes can do UI, and when they do we want to have
15125            // them trim their memory after the user leaves the UI.  To
15126            // facilitate this, here we need to determine whether or not it
15127            // is currently showing UI.
15128            app.systemNoUi = true;
15129            if (app == TOP_APP) {
15130                app.systemNoUi = false;
15131            } else if (activitiesSize > 0) {
15132                for (int j = 0; j < activitiesSize; j++) {
15133                    final ActivityRecord r = app.activities.get(j);
15134                    if (r.visible) {
15135                        app.systemNoUi = false;
15136                    }
15137                }
15138            }
15139            if (!app.systemNoUi) {
15140                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15141            }
15142            return (app.curAdj=app.maxAdj);
15143        }
15144
15145        app.keeping = false;
15146        app.systemNoUi = false;
15147
15148        // Determine the importance of the process, starting with most
15149        // important to least, and assign an appropriate OOM adjustment.
15150        int adj;
15151        int schedGroup;
15152        int procState;
15153        boolean foregroundActivities = false;
15154        BroadcastQueue queue;
15155        if (app == TOP_APP) {
15156            // The last app on the list is the foreground app.
15157            adj = ProcessList.FOREGROUND_APP_ADJ;
15158            schedGroup = Process.THREAD_GROUP_DEFAULT;
15159            app.adjType = "top-activity";
15160            foregroundActivities = true;
15161            procState = ActivityManager.PROCESS_STATE_TOP;
15162        } else if (app.instrumentationClass != null) {
15163            // Don't want to kill running instrumentation.
15164            adj = ProcessList.FOREGROUND_APP_ADJ;
15165            schedGroup = Process.THREAD_GROUP_DEFAULT;
15166            app.adjType = "instrumentation";
15167            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15168        } else if ((queue = isReceivingBroadcast(app)) != null) {
15169            // An app that is currently receiving a broadcast also
15170            // counts as being in the foreground for OOM killer purposes.
15171            // It's placed in a sched group based on the nature of the
15172            // broadcast as reflected by which queue it's active in.
15173            adj = ProcessList.FOREGROUND_APP_ADJ;
15174            schedGroup = (queue == mFgBroadcastQueue)
15175                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15176            app.adjType = "broadcast";
15177            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15178        } else if (app.executingServices.size() > 0) {
15179            // An app that is currently executing a service callback also
15180            // counts as being in the foreground.
15181            adj = ProcessList.FOREGROUND_APP_ADJ;
15182            schedGroup = app.execServicesFg ?
15183                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15184            app.adjType = "exec-service";
15185            procState = ActivityManager.PROCESS_STATE_SERVICE;
15186            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15187        } else {
15188            // As far as we know the process is empty.  We may change our mind later.
15189            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15190            // At this point we don't actually know the adjustment.  Use the cached adj
15191            // value that the caller wants us to.
15192            adj = cachedAdj;
15193            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15194            app.cached = true;
15195            app.empty = true;
15196            app.adjType = "cch-empty";
15197        }
15198
15199        // Examine all activities if not already foreground.
15200        if (!foregroundActivities && activitiesSize > 0) {
15201            for (int j = 0; j < activitiesSize; j++) {
15202                final ActivityRecord r = app.activities.get(j);
15203                if (r.app != app) {
15204                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15205                            + app + "?!?");
15206                    continue;
15207                }
15208                if (r.visible) {
15209                    // App has a visible activity; only upgrade adjustment.
15210                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15211                        adj = ProcessList.VISIBLE_APP_ADJ;
15212                        app.adjType = "visible";
15213                    }
15214                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15215                        procState = ActivityManager.PROCESS_STATE_TOP;
15216                    }
15217                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15218                    app.cached = false;
15219                    app.empty = false;
15220                    foregroundActivities = true;
15221                    break;
15222                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15223                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15224                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15225                        app.adjType = "pausing";
15226                    }
15227                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15228                        procState = ActivityManager.PROCESS_STATE_TOP;
15229                    }
15230                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15231                    app.cached = false;
15232                    app.empty = false;
15233                    foregroundActivities = true;
15234                } else if (r.state == ActivityState.STOPPING) {
15235                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15236                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15237                        app.adjType = "stopping";
15238                    }
15239                    // For the process state, we will at this point consider the
15240                    // process to be cached.  It will be cached either as an activity
15241                    // or empty depending on whether the activity is finishing.  We do
15242                    // this so that we can treat the process as cached for purposes of
15243                    // memory trimming (determing current memory level, trim command to
15244                    // send to process) since there can be an arbitrary number of stopping
15245                    // processes and they should soon all go into the cached state.
15246                    if (!r.finishing) {
15247                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15248                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15249                        }
15250                    }
15251                    app.cached = false;
15252                    app.empty = false;
15253                    foregroundActivities = true;
15254                } else {
15255                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15256                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15257                        app.adjType = "cch-act";
15258                    }
15259                }
15260            }
15261        }
15262
15263        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15264            if (app.foregroundServices) {
15265                // The user is aware of this app, so make it visible.
15266                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15267                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15268                app.cached = false;
15269                app.adjType = "fg-service";
15270                schedGroup = Process.THREAD_GROUP_DEFAULT;
15271            } else if (app.forcingToForeground != null) {
15272                // The user is aware of this app, so make it visible.
15273                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15274                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15275                app.cached = false;
15276                app.adjType = "force-fg";
15277                app.adjSource = app.forcingToForeground;
15278                schedGroup = Process.THREAD_GROUP_DEFAULT;
15279            }
15280        }
15281
15282        if (app == mHeavyWeightProcess) {
15283            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15284                // We don't want to kill the current heavy-weight process.
15285                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15286                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15287                app.cached = false;
15288                app.adjType = "heavy";
15289            }
15290            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15291                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15292            }
15293        }
15294
15295        if (app == mHomeProcess) {
15296            if (adj > ProcessList.HOME_APP_ADJ) {
15297                // This process is hosting what we currently consider to be the
15298                // home app, so we don't want to let it go into the background.
15299                adj = ProcessList.HOME_APP_ADJ;
15300                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15301                app.cached = false;
15302                app.adjType = "home";
15303            }
15304            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15305                procState = ActivityManager.PROCESS_STATE_HOME;
15306            }
15307        }
15308
15309        if (app == mPreviousProcess && app.activities.size() > 0) {
15310            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15311                // This was the previous process that showed UI to the user.
15312                // We want to try to keep it around more aggressively, to give
15313                // a good experience around switching between two apps.
15314                adj = ProcessList.PREVIOUS_APP_ADJ;
15315                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15316                app.cached = false;
15317                app.adjType = "previous";
15318            }
15319            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15320                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15321            }
15322        }
15323
15324        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15325                + " reason=" + app.adjType);
15326
15327        // By default, we use the computed adjustment.  It may be changed if
15328        // there are applications dependent on our services or providers, but
15329        // this gives us a baseline and makes sure we don't get into an
15330        // infinite recursion.
15331        app.adjSeq = mAdjSeq;
15332        app.curRawAdj = adj;
15333        app.hasStartedServices = false;
15334
15335        if (mBackupTarget != null && app == mBackupTarget.app) {
15336            // If possible we want to avoid killing apps while they're being backed up
15337            if (adj > ProcessList.BACKUP_APP_ADJ) {
15338                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15339                adj = ProcessList.BACKUP_APP_ADJ;
15340                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15341                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15342                }
15343                app.adjType = "backup";
15344                app.cached = false;
15345            }
15346            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15347                procState = ActivityManager.PROCESS_STATE_BACKUP;
15348            }
15349        }
15350
15351        boolean mayBeTop = false;
15352
15353        for (int is = app.services.size()-1;
15354                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15355                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15356                        || procState > ActivityManager.PROCESS_STATE_TOP);
15357                is--) {
15358            ServiceRecord s = app.services.valueAt(is);
15359            if (s.startRequested) {
15360                app.hasStartedServices = true;
15361                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15362                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15363                }
15364                if (app.hasShownUi && app != mHomeProcess) {
15365                    // If this process has shown some UI, let it immediately
15366                    // go to the LRU list because it may be pretty heavy with
15367                    // UI stuff.  We'll tag it with a label just to help
15368                    // debug and understand what is going on.
15369                    if (adj > ProcessList.SERVICE_ADJ) {
15370                        app.adjType = "cch-started-ui-services";
15371                    }
15372                } else {
15373                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15374                        // This service has seen some activity within
15375                        // recent memory, so we will keep its process ahead
15376                        // of the background processes.
15377                        if (adj > ProcessList.SERVICE_ADJ) {
15378                            adj = ProcessList.SERVICE_ADJ;
15379                            app.adjType = "started-services";
15380                            app.cached = false;
15381                        }
15382                    }
15383                    // If we have let the service slide into the background
15384                    // state, still have some text describing what it is doing
15385                    // even though the service no longer has an impact.
15386                    if (adj > ProcessList.SERVICE_ADJ) {
15387                        app.adjType = "cch-started-services";
15388                    }
15389                }
15390                // Don't kill this process because it is doing work; it
15391                // has said it is doing work.
15392                app.keeping = true;
15393            }
15394            for (int conni = s.connections.size()-1;
15395                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15396                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15397                            || procState > ActivityManager.PROCESS_STATE_TOP);
15398                    conni--) {
15399                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15400                for (int i = 0;
15401                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15402                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15403                                || procState > ActivityManager.PROCESS_STATE_TOP);
15404                        i++) {
15405                    // XXX should compute this based on the max of
15406                    // all connected clients.
15407                    ConnectionRecord cr = clist.get(i);
15408                    if (cr.binding.client == app) {
15409                        // Binding to ourself is not interesting.
15410                        continue;
15411                    }
15412                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15413                        ProcessRecord client = cr.binding.client;
15414                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15415                                TOP_APP, doingAll, now);
15416                        int clientProcState = client.curProcState;
15417                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15418                            // If the other app is cached for any reason, for purposes here
15419                            // we are going to consider it empty.  The specific cached state
15420                            // doesn't propagate except under certain conditions.
15421                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15422                        }
15423                        String adjType = null;
15424                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15425                            // Not doing bind OOM management, so treat
15426                            // this guy more like a started service.
15427                            if (app.hasShownUi && app != mHomeProcess) {
15428                                // If this process has shown some UI, let it immediately
15429                                // go to the LRU list because it may be pretty heavy with
15430                                // UI stuff.  We'll tag it with a label just to help
15431                                // debug and understand what is going on.
15432                                if (adj > clientAdj) {
15433                                    adjType = "cch-bound-ui-services";
15434                                }
15435                                app.cached = false;
15436                                clientAdj = adj;
15437                                clientProcState = procState;
15438                            } else {
15439                                if (now >= (s.lastActivity
15440                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15441                                    // This service has not seen activity within
15442                                    // recent memory, so allow it to drop to the
15443                                    // LRU list if there is no other reason to keep
15444                                    // it around.  We'll also tag it with a label just
15445                                    // to help debug and undertand what is going on.
15446                                    if (adj > clientAdj) {
15447                                        adjType = "cch-bound-services";
15448                                    }
15449                                    clientAdj = adj;
15450                                }
15451                            }
15452                        }
15453                        if (adj > clientAdj) {
15454                            // If this process has recently shown UI, and
15455                            // the process that is binding to it is less
15456                            // important than being visible, then we don't
15457                            // care about the binding as much as we care
15458                            // about letting this process get into the LRU
15459                            // list to be killed and restarted if needed for
15460                            // memory.
15461                            if (app.hasShownUi && app != mHomeProcess
15462                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15463                                adjType = "cch-bound-ui-services";
15464                            } else {
15465                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15466                                        |Context.BIND_IMPORTANT)) != 0) {
15467                                    adj = clientAdj;
15468                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15469                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15470                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15471                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15472                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15473                                    adj = clientAdj;
15474                                } else {
15475                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15476                                        adj = ProcessList.VISIBLE_APP_ADJ;
15477                                    }
15478                                }
15479                                if (!client.cached) {
15480                                    app.cached = false;
15481                                }
15482                                if (client.keeping) {
15483                                    app.keeping = true;
15484                                }
15485                                adjType = "service";
15486                            }
15487                        }
15488                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15489                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15490                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15491                            }
15492                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15493                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15494                                    // Special handling of clients who are in the top state.
15495                                    // We *may* want to consider this process to be in the
15496                                    // top state as well, but only if there is not another
15497                                    // reason for it to be running.  Being on the top is a
15498                                    // special state, meaning you are specifically running
15499                                    // for the current top app.  If the process is already
15500                                    // running in the background for some other reason, it
15501                                    // is more important to continue considering it to be
15502                                    // in the background state.
15503                                    mayBeTop = true;
15504                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15505                                } else {
15506                                    // Special handling for above-top states (persistent
15507                                    // processes).  These should not bring the current process
15508                                    // into the top state, since they are not on top.  Instead
15509                                    // give them the best state after that.
15510                                    clientProcState =
15511                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15512                                }
15513                            }
15514                        } else {
15515                            if (clientProcState <
15516                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15517                                clientProcState =
15518                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15519                            }
15520                        }
15521                        if (procState > clientProcState) {
15522                            procState = clientProcState;
15523                        }
15524                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15525                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15526                            app.pendingUiClean = true;
15527                        }
15528                        if (adjType != null) {
15529                            app.adjType = adjType;
15530                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15531                                    .REASON_SERVICE_IN_USE;
15532                            app.adjSource = cr.binding.client;
15533                            app.adjSourceOom = clientAdj;
15534                            app.adjTarget = s.name;
15535                        }
15536                    }
15537                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15538                        app.treatLikeActivity = true;
15539                    }
15540                    final ActivityRecord a = cr.activity;
15541                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15542                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15543                                (a.visible || a.state == ActivityState.RESUMED
15544                                 || a.state == ActivityState.PAUSING)) {
15545                            adj = ProcessList.FOREGROUND_APP_ADJ;
15546                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15547                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15548                            }
15549                            app.cached = false;
15550                            app.adjType = "service";
15551                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15552                                    .REASON_SERVICE_IN_USE;
15553                            app.adjSource = a;
15554                            app.adjSourceOom = adj;
15555                            app.adjTarget = s.name;
15556                        }
15557                    }
15558                }
15559            }
15560        }
15561
15562        for (int provi = app.pubProviders.size()-1;
15563                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15564                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15565                        || procState > ActivityManager.PROCESS_STATE_TOP);
15566                provi--) {
15567            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15568            for (int i = cpr.connections.size()-1;
15569                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15570                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15571                            || procState > ActivityManager.PROCESS_STATE_TOP);
15572                    i--) {
15573                ContentProviderConnection conn = cpr.connections.get(i);
15574                ProcessRecord client = conn.client;
15575                if (client == app) {
15576                    // Being our own client is not interesting.
15577                    continue;
15578                }
15579                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15580                int clientProcState = client.curProcState;
15581                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15582                    // If the other app is cached for any reason, for purposes here
15583                    // we are going to consider it empty.
15584                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15585                }
15586                if (adj > clientAdj) {
15587                    if (app.hasShownUi && app != mHomeProcess
15588                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15589                        app.adjType = "cch-ui-provider";
15590                    } else {
15591                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15592                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15593                        app.adjType = "provider";
15594                    }
15595                    app.cached &= client.cached;
15596                    app.keeping |= client.keeping;
15597                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15598                            .REASON_PROVIDER_IN_USE;
15599                    app.adjSource = client;
15600                    app.adjSourceOom = clientAdj;
15601                    app.adjTarget = cpr.name;
15602                }
15603                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15604                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15605                        // Special handling of clients who are in the top state.
15606                        // We *may* want to consider this process to be in the
15607                        // top state as well, but only if there is not another
15608                        // reason for it to be running.  Being on the top is a
15609                        // special state, meaning you are specifically running
15610                        // for the current top app.  If the process is already
15611                        // running in the background for some other reason, it
15612                        // is more important to continue considering it to be
15613                        // in the background state.
15614                        mayBeTop = true;
15615                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15616                    } else {
15617                        // Special handling for above-top states (persistent
15618                        // processes).  These should not bring the current process
15619                        // into the top state, since they are not on top.  Instead
15620                        // give them the best state after that.
15621                        clientProcState =
15622                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15623                    }
15624                }
15625                if (procState > clientProcState) {
15626                    procState = clientProcState;
15627                }
15628                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15629                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15630                }
15631            }
15632            // If the provider has external (non-framework) process
15633            // dependencies, ensure that its adjustment is at least
15634            // FOREGROUND_APP_ADJ.
15635            if (cpr.hasExternalProcessHandles()) {
15636                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15637                    adj = ProcessList.FOREGROUND_APP_ADJ;
15638                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15639                    app.cached = false;
15640                    app.keeping = true;
15641                    app.adjType = "provider";
15642                    app.adjTarget = cpr.name;
15643                }
15644                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15645                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15646                }
15647            }
15648        }
15649
15650        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15651            // A client of one of our services or providers is in the top state.  We
15652            // *may* want to be in the top state, but not if we are already running in
15653            // the background for some other reason.  For the decision here, we are going
15654            // to pick out a few specific states that we want to remain in when a client
15655            // is top (states that tend to be longer-term) and otherwise allow it to go
15656            // to the top state.
15657            switch (procState) {
15658                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15659                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15660                case ActivityManager.PROCESS_STATE_SERVICE:
15661                    // These all are longer-term states, so pull them up to the top
15662                    // of the background states, but not all the way to the top state.
15663                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15664                    break;
15665                default:
15666                    // Otherwise, top is a better choice, so take it.
15667                    procState = ActivityManager.PROCESS_STATE_TOP;
15668                    break;
15669            }
15670        }
15671
15672        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15673            if (app.hasClientActivities) {
15674                // This is a cached process, but with client activities.  Mark it so.
15675                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15676                app.adjType = "cch-client-act";
15677            } else if (app.treatLikeActivity) {
15678                // This is a cached process, but somebody wants us to treat it like it has
15679                // an activity, okay!
15680                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15681                app.adjType = "cch-as-act";
15682            }
15683        }
15684
15685        if (adj == ProcessList.SERVICE_ADJ) {
15686            if (doingAll) {
15687                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15688                mNewNumServiceProcs++;
15689                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15690                if (!app.serviceb) {
15691                    // This service isn't far enough down on the LRU list to
15692                    // normally be a B service, but if we are low on RAM and it
15693                    // is large we want to force it down since we would prefer to
15694                    // keep launcher over it.
15695                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15696                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15697                        app.serviceHighRam = true;
15698                        app.serviceb = true;
15699                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15700                    } else {
15701                        mNewNumAServiceProcs++;
15702                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15703                    }
15704                } else {
15705                    app.serviceHighRam = false;
15706                }
15707            }
15708            if (app.serviceb) {
15709                adj = ProcessList.SERVICE_B_ADJ;
15710            }
15711        }
15712
15713        app.curRawAdj = adj;
15714
15715        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15716        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15717        if (adj > app.maxAdj) {
15718            adj = app.maxAdj;
15719            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15720                schedGroup = Process.THREAD_GROUP_DEFAULT;
15721            }
15722        }
15723        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15724            app.keeping = true;
15725        }
15726
15727        // Do final modification to adj.  Everything we do between here and applying
15728        // the final setAdj must be done in this function, because we will also use
15729        // it when computing the final cached adj later.  Note that we don't need to
15730        // worry about this for max adj above, since max adj will always be used to
15731        // keep it out of the cached vaues.
15732        app.curAdj = app.modifyRawOomAdj(adj);
15733        app.curSchedGroup = schedGroup;
15734        app.curProcState = procState;
15735        app.foregroundActivities = foregroundActivities;
15736
15737        return app.curRawAdj;
15738    }
15739
15740    /**
15741     * Schedule PSS collection of a process.
15742     */
15743    void requestPssLocked(ProcessRecord proc, int procState) {
15744        if (mPendingPssProcesses.contains(proc)) {
15745            return;
15746        }
15747        if (mPendingPssProcesses.size() == 0) {
15748            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15749        }
15750        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15751        proc.pssProcState = procState;
15752        mPendingPssProcesses.add(proc);
15753    }
15754
15755    /**
15756     * Schedule PSS collection of all processes.
15757     */
15758    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15759        if (!always) {
15760            if (now < (mLastFullPssTime +
15761                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15762                return;
15763            }
15764        }
15765        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15766        mLastFullPssTime = now;
15767        mFullPssPending = true;
15768        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15769        mPendingPssProcesses.clear();
15770        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15771            ProcessRecord app = mLruProcesses.get(i);
15772            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15773                app.pssProcState = app.setProcState;
15774                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15775                        isSleeping(), now);
15776                mPendingPssProcesses.add(app);
15777            }
15778        }
15779        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15780    }
15781
15782    /**
15783     * Ask a given process to GC right now.
15784     */
15785    final void performAppGcLocked(ProcessRecord app) {
15786        try {
15787            app.lastRequestedGc = SystemClock.uptimeMillis();
15788            if (app.thread != null) {
15789                if (app.reportLowMemory) {
15790                    app.reportLowMemory = false;
15791                    app.thread.scheduleLowMemory();
15792                } else {
15793                    app.thread.processInBackground();
15794                }
15795            }
15796        } catch (Exception e) {
15797            // whatever.
15798        }
15799    }
15800
15801    /**
15802     * Returns true if things are idle enough to perform GCs.
15803     */
15804    private final boolean canGcNowLocked() {
15805        boolean processingBroadcasts = false;
15806        for (BroadcastQueue q : mBroadcastQueues) {
15807            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15808                processingBroadcasts = true;
15809            }
15810        }
15811        return !processingBroadcasts
15812                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15813    }
15814
15815    /**
15816     * Perform GCs on all processes that are waiting for it, but only
15817     * if things are idle.
15818     */
15819    final void performAppGcsLocked() {
15820        final int N = mProcessesToGc.size();
15821        if (N <= 0) {
15822            return;
15823        }
15824        if (canGcNowLocked()) {
15825            while (mProcessesToGc.size() > 0) {
15826                ProcessRecord proc = mProcessesToGc.remove(0);
15827                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15828                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15829                            <= SystemClock.uptimeMillis()) {
15830                        // To avoid spamming the system, we will GC processes one
15831                        // at a time, waiting a few seconds between each.
15832                        performAppGcLocked(proc);
15833                        scheduleAppGcsLocked();
15834                        return;
15835                    } else {
15836                        // It hasn't been long enough since we last GCed this
15837                        // process...  put it in the list to wait for its time.
15838                        addProcessToGcListLocked(proc);
15839                        break;
15840                    }
15841                }
15842            }
15843
15844            scheduleAppGcsLocked();
15845        }
15846    }
15847
15848    /**
15849     * If all looks good, perform GCs on all processes waiting for them.
15850     */
15851    final void performAppGcsIfAppropriateLocked() {
15852        if (canGcNowLocked()) {
15853            performAppGcsLocked();
15854            return;
15855        }
15856        // Still not idle, wait some more.
15857        scheduleAppGcsLocked();
15858    }
15859
15860    /**
15861     * Schedule the execution of all pending app GCs.
15862     */
15863    final void scheduleAppGcsLocked() {
15864        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15865
15866        if (mProcessesToGc.size() > 0) {
15867            // Schedule a GC for the time to the next process.
15868            ProcessRecord proc = mProcessesToGc.get(0);
15869            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15870
15871            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15872            long now = SystemClock.uptimeMillis();
15873            if (when < (now+GC_TIMEOUT)) {
15874                when = now + GC_TIMEOUT;
15875            }
15876            mHandler.sendMessageAtTime(msg, when);
15877        }
15878    }
15879
15880    /**
15881     * Add a process to the array of processes waiting to be GCed.  Keeps the
15882     * list in sorted order by the last GC time.  The process can't already be
15883     * on the list.
15884     */
15885    final void addProcessToGcListLocked(ProcessRecord proc) {
15886        boolean added = false;
15887        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15888            if (mProcessesToGc.get(i).lastRequestedGc <
15889                    proc.lastRequestedGc) {
15890                added = true;
15891                mProcessesToGc.add(i+1, proc);
15892                break;
15893            }
15894        }
15895        if (!added) {
15896            mProcessesToGc.add(0, proc);
15897        }
15898    }
15899
15900    /**
15901     * Set up to ask a process to GC itself.  This will either do it
15902     * immediately, or put it on the list of processes to gc the next
15903     * time things are idle.
15904     */
15905    final void scheduleAppGcLocked(ProcessRecord app) {
15906        long now = SystemClock.uptimeMillis();
15907        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15908            return;
15909        }
15910        if (!mProcessesToGc.contains(app)) {
15911            addProcessToGcListLocked(app);
15912            scheduleAppGcsLocked();
15913        }
15914    }
15915
15916    final void checkExcessivePowerUsageLocked(boolean doKills) {
15917        updateCpuStatsNow();
15918
15919        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15920        boolean doWakeKills = doKills;
15921        boolean doCpuKills = doKills;
15922        if (mLastPowerCheckRealtime == 0) {
15923            doWakeKills = false;
15924        }
15925        if (mLastPowerCheckUptime == 0) {
15926            doCpuKills = false;
15927        }
15928        if (stats.isScreenOn()) {
15929            doWakeKills = false;
15930        }
15931        final long curRealtime = SystemClock.elapsedRealtime();
15932        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15933        final long curUptime = SystemClock.uptimeMillis();
15934        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15935        mLastPowerCheckRealtime = curRealtime;
15936        mLastPowerCheckUptime = curUptime;
15937        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15938            doWakeKills = false;
15939        }
15940        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15941            doCpuKills = false;
15942        }
15943        int i = mLruProcesses.size();
15944        while (i > 0) {
15945            i--;
15946            ProcessRecord app = mLruProcesses.get(i);
15947            if (!app.keeping) {
15948                long wtime;
15949                synchronized (stats) {
15950                    wtime = stats.getProcessWakeTime(app.info.uid,
15951                            app.pid, curRealtime);
15952                }
15953                long wtimeUsed = wtime - app.lastWakeTime;
15954                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15955                if (DEBUG_POWER) {
15956                    StringBuilder sb = new StringBuilder(128);
15957                    sb.append("Wake for ");
15958                    app.toShortString(sb);
15959                    sb.append(": over ");
15960                    TimeUtils.formatDuration(realtimeSince, sb);
15961                    sb.append(" used ");
15962                    TimeUtils.formatDuration(wtimeUsed, sb);
15963                    sb.append(" (");
15964                    sb.append((wtimeUsed*100)/realtimeSince);
15965                    sb.append("%)");
15966                    Slog.i(TAG, sb.toString());
15967                    sb.setLength(0);
15968                    sb.append("CPU for ");
15969                    app.toShortString(sb);
15970                    sb.append(": over ");
15971                    TimeUtils.formatDuration(uptimeSince, sb);
15972                    sb.append(" used ");
15973                    TimeUtils.formatDuration(cputimeUsed, sb);
15974                    sb.append(" (");
15975                    sb.append((cputimeUsed*100)/uptimeSince);
15976                    sb.append("%)");
15977                    Slog.i(TAG, sb.toString());
15978                }
15979                // If a process has held a wake lock for more
15980                // than 50% of the time during this period,
15981                // that sounds bad.  Kill!
15982                if (doWakeKills && realtimeSince > 0
15983                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15984                    synchronized (stats) {
15985                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15986                                realtimeSince, wtimeUsed);
15987                    }
15988                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15989                            + " during " + realtimeSince);
15990                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15991                } else if (doCpuKills && uptimeSince > 0
15992                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15993                    synchronized (stats) {
15994                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15995                                uptimeSince, cputimeUsed);
15996                    }
15997                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15998                            + " during " + uptimeSince);
15999                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16000                } else {
16001                    app.lastWakeTime = wtime;
16002                    app.lastCpuTime = app.curCpuTime;
16003                }
16004            }
16005        }
16006    }
16007
16008    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
16009            ProcessRecord TOP_APP, boolean doingAll, long now) {
16010        boolean success = true;
16011
16012        if (app.curRawAdj != app.setRawAdj) {
16013            if (wasKeeping && !app.keeping) {
16014                // This app is no longer something we want to keep.  Note
16015                // its current wake lock time to later know to kill it if
16016                // it is not behaving well.
16017                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16018                synchronized (stats) {
16019                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16020                            app.pid, SystemClock.elapsedRealtime());
16021                }
16022                app.lastCpuTime = app.curCpuTime;
16023            }
16024
16025            app.setRawAdj = app.curRawAdj;
16026        }
16027
16028        int changes = 0;
16029
16030        if (app.curAdj != app.setAdj) {
16031            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16032            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16033                TAG, "Set " + app.pid + " " + app.processName +
16034                " adj " + app.curAdj + ": " + app.adjType);
16035            app.setAdj = app.curAdj;
16036        }
16037
16038        if (app.setSchedGroup != app.curSchedGroup) {
16039            app.setSchedGroup = app.curSchedGroup;
16040            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16041                    "Setting process group of " + app.processName
16042                    + " to " + app.curSchedGroup);
16043            if (app.waitingToKill != null &&
16044                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16045                killUnneededProcessLocked(app, app.waitingToKill);
16046                success = false;
16047            } else {
16048                if (true) {
16049                    long oldId = Binder.clearCallingIdentity();
16050                    try {
16051                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16052                    } catch (Exception e) {
16053                        Slog.w(TAG, "Failed setting process group of " + app.pid
16054                                + " to " + app.curSchedGroup);
16055                        e.printStackTrace();
16056                    } finally {
16057                        Binder.restoreCallingIdentity(oldId);
16058                    }
16059                } else {
16060                    if (app.thread != null) {
16061                        try {
16062                            app.thread.setSchedulingGroup(app.curSchedGroup);
16063                        } catch (RemoteException e) {
16064                        }
16065                    }
16066                }
16067                Process.setSwappiness(app.pid,
16068                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16069            }
16070        }
16071        if (app.repForegroundActivities != app.foregroundActivities) {
16072            app.repForegroundActivities = app.foregroundActivities;
16073            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16074        }
16075        if (app.repProcState != app.curProcState) {
16076            app.repProcState = app.curProcState;
16077            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16078            if (app.thread != null) {
16079                try {
16080                    if (false) {
16081                        //RuntimeException h = new RuntimeException("here");
16082                        Slog.i(TAG, "Sending new process state " + app.repProcState
16083                                + " to " + app /*, h*/);
16084                    }
16085                    app.thread.setProcessState(app.repProcState);
16086                } catch (RemoteException e) {
16087                }
16088            }
16089        }
16090        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16091                app.setProcState)) {
16092            app.lastStateTime = now;
16093            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16094                    isSleeping(), now);
16095            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16096                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16097                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16098                    + (app.nextPssTime-now) + ": " + app);
16099        } else {
16100            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16101                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16102                requestPssLocked(app, app.setProcState);
16103                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16104                        isSleeping(), now);
16105            } else if (false && DEBUG_PSS) {
16106                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16107            }
16108        }
16109        if (app.setProcState != app.curProcState) {
16110            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16111                    "Proc state change of " + app.processName
16112                    + " to " + app.curProcState);
16113            app.setProcState = app.curProcState;
16114            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16115                app.notCachedSinceIdle = false;
16116            }
16117            if (!doingAll) {
16118                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16119            } else {
16120                app.procStateChanged = true;
16121            }
16122        }
16123
16124        if (changes != 0) {
16125            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16126            int i = mPendingProcessChanges.size()-1;
16127            ProcessChangeItem item = null;
16128            while (i >= 0) {
16129                item = mPendingProcessChanges.get(i);
16130                if (item.pid == app.pid) {
16131                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16132                    break;
16133                }
16134                i--;
16135            }
16136            if (i < 0) {
16137                // No existing item in pending changes; need a new one.
16138                final int NA = mAvailProcessChanges.size();
16139                if (NA > 0) {
16140                    item = mAvailProcessChanges.remove(NA-1);
16141                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16142                } else {
16143                    item = new ProcessChangeItem();
16144                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16145                }
16146                item.changes = 0;
16147                item.pid = app.pid;
16148                item.uid = app.info.uid;
16149                if (mPendingProcessChanges.size() == 0) {
16150                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16151                            "*** Enqueueing dispatch processes changed!");
16152                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16153                }
16154                mPendingProcessChanges.add(item);
16155            }
16156            item.changes |= changes;
16157            item.processState = app.repProcState;
16158            item.foregroundActivities = app.repForegroundActivities;
16159            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16160                    + Integer.toHexString(System.identityHashCode(item))
16161                    + " " + app.toShortString() + ": changes=" + item.changes
16162                    + " procState=" + item.processState
16163                    + " foreground=" + item.foregroundActivities
16164                    + " type=" + app.adjType + " source=" + app.adjSource
16165                    + " target=" + app.adjTarget);
16166        }
16167
16168        return success;
16169    }
16170
16171    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16172        if (proc.thread != null) {
16173            if (proc.baseProcessTracker != null) {
16174                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16175            }
16176            if (proc.repProcState >= 0) {
16177                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16178                        proc.repProcState);
16179            }
16180        }
16181    }
16182
16183    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16184            ProcessRecord TOP_APP, boolean doingAll, long now) {
16185        if (app.thread == null) {
16186            return false;
16187        }
16188
16189        final boolean wasKeeping = app.keeping;
16190
16191        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16192
16193        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16194    }
16195
16196    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16197            boolean oomAdj) {
16198        if (isForeground != proc.foregroundServices) {
16199            proc.foregroundServices = isForeground;
16200            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16201                    proc.info.uid);
16202            if (isForeground) {
16203                if (curProcs == null) {
16204                    curProcs = new ArrayList<ProcessRecord>();
16205                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16206                }
16207                if (!curProcs.contains(proc)) {
16208                    curProcs.add(proc);
16209                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16210                            proc.info.packageName, proc.info.uid);
16211                }
16212            } else {
16213                if (curProcs != null) {
16214                    if (curProcs.remove(proc)) {
16215                        mBatteryStatsService.noteEvent(
16216                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16217                                proc.info.packageName, proc.info.uid);
16218                        if (curProcs.size() <= 0) {
16219                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16220                        }
16221                    }
16222                }
16223            }
16224            if (oomAdj) {
16225                updateOomAdjLocked();
16226            }
16227        }
16228    }
16229
16230    private final ActivityRecord resumedAppLocked() {
16231        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16232        String pkg;
16233        int uid;
16234        if (act != null) {
16235            pkg = act.packageName;
16236            uid = act.info.applicationInfo.uid;
16237        } else {
16238            pkg = null;
16239            uid = -1;
16240        }
16241        // Has the UID or resumed package name changed?
16242        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16243                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16244            if (mCurResumedPackage != null) {
16245                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16246                        mCurResumedPackage, mCurResumedUid);
16247            }
16248            mCurResumedPackage = pkg;
16249            mCurResumedUid = uid;
16250            if (mCurResumedPackage != null) {
16251                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16252                        mCurResumedPackage, mCurResumedUid);
16253            }
16254        }
16255        return act;
16256    }
16257
16258    final boolean updateOomAdjLocked(ProcessRecord app) {
16259        final ActivityRecord TOP_ACT = resumedAppLocked();
16260        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16261        final boolean wasCached = app.cached;
16262
16263        mAdjSeq++;
16264
16265        // This is the desired cached adjusment we want to tell it to use.
16266        // If our app is currently cached, we know it, and that is it.  Otherwise,
16267        // we don't know it yet, and it needs to now be cached we will then
16268        // need to do a complete oom adj.
16269        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16270                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16271        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16272                SystemClock.uptimeMillis());
16273        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16274            // Changed to/from cached state, so apps after it in the LRU
16275            // list may also be changed.
16276            updateOomAdjLocked();
16277        }
16278        return success;
16279    }
16280
16281    final void updateOomAdjLocked() {
16282        final ActivityRecord TOP_ACT = resumedAppLocked();
16283        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16284        final long now = SystemClock.uptimeMillis();
16285        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16286        final int N = mLruProcesses.size();
16287
16288        if (false) {
16289            RuntimeException e = new RuntimeException();
16290            e.fillInStackTrace();
16291            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16292        }
16293
16294        mAdjSeq++;
16295        mNewNumServiceProcs = 0;
16296        mNewNumAServiceProcs = 0;
16297
16298        final int emptyProcessLimit;
16299        final int cachedProcessLimit;
16300        if (mProcessLimit <= 0) {
16301            emptyProcessLimit = cachedProcessLimit = 0;
16302        } else if (mProcessLimit == 1) {
16303            emptyProcessLimit = 1;
16304            cachedProcessLimit = 0;
16305        } else {
16306            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16307            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16308        }
16309
16310        // Let's determine how many processes we have running vs.
16311        // how many slots we have for background processes; we may want
16312        // to put multiple processes in a slot of there are enough of
16313        // them.
16314        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16315                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16316        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16317        if (numEmptyProcs > cachedProcessLimit) {
16318            // If there are more empty processes than our limit on cached
16319            // processes, then use the cached process limit for the factor.
16320            // This ensures that the really old empty processes get pushed
16321            // down to the bottom, so if we are running low on memory we will
16322            // have a better chance at keeping around more cached processes
16323            // instead of a gazillion empty processes.
16324            numEmptyProcs = cachedProcessLimit;
16325        }
16326        int emptyFactor = numEmptyProcs/numSlots;
16327        if (emptyFactor < 1) emptyFactor = 1;
16328        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16329        if (cachedFactor < 1) cachedFactor = 1;
16330        int stepCached = 0;
16331        int stepEmpty = 0;
16332        int numCached = 0;
16333        int numEmpty = 0;
16334        int numTrimming = 0;
16335
16336        mNumNonCachedProcs = 0;
16337        mNumCachedHiddenProcs = 0;
16338
16339        // First update the OOM adjustment for each of the
16340        // application processes based on their current state.
16341        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16342        int nextCachedAdj = curCachedAdj+1;
16343        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16344        int nextEmptyAdj = curEmptyAdj+2;
16345        for (int i=N-1; i>=0; i--) {
16346            ProcessRecord app = mLruProcesses.get(i);
16347            if (!app.killedByAm && app.thread != null) {
16348                app.procStateChanged = false;
16349                final boolean wasKeeping = app.keeping;
16350                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16351
16352                // If we haven't yet assigned the final cached adj
16353                // to the process, do that now.
16354                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16355                    switch (app.curProcState) {
16356                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16357                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16358                            // This process is a cached process holding activities...
16359                            // assign it the next cached value for that type, and then
16360                            // step that cached level.
16361                            app.curRawAdj = curCachedAdj;
16362                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16363                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16364                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16365                                    + ")");
16366                            if (curCachedAdj != nextCachedAdj) {
16367                                stepCached++;
16368                                if (stepCached >= cachedFactor) {
16369                                    stepCached = 0;
16370                                    curCachedAdj = nextCachedAdj;
16371                                    nextCachedAdj += 2;
16372                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16373                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16374                                    }
16375                                }
16376                            }
16377                            break;
16378                        default:
16379                            // For everything else, assign next empty cached process
16380                            // level and bump that up.  Note that this means that
16381                            // long-running services that have dropped down to the
16382                            // cached level will be treated as empty (since their process
16383                            // state is still as a service), which is what we want.
16384                            app.curRawAdj = curEmptyAdj;
16385                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16386                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16387                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16388                                    + ")");
16389                            if (curEmptyAdj != nextEmptyAdj) {
16390                                stepEmpty++;
16391                                if (stepEmpty >= emptyFactor) {
16392                                    stepEmpty = 0;
16393                                    curEmptyAdj = nextEmptyAdj;
16394                                    nextEmptyAdj += 2;
16395                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16396                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16397                                    }
16398                                }
16399                            }
16400                            break;
16401                    }
16402                }
16403
16404                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16405
16406                // Count the number of process types.
16407                switch (app.curProcState) {
16408                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16409                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16410                        mNumCachedHiddenProcs++;
16411                        numCached++;
16412                        if (numCached > cachedProcessLimit) {
16413                            killUnneededProcessLocked(app, "cached #" + numCached);
16414                        }
16415                        break;
16416                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16417                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16418                                && app.lastActivityTime < oldTime) {
16419                            killUnneededProcessLocked(app, "empty for "
16420                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16421                                    / 1000) + "s");
16422                        } else {
16423                            numEmpty++;
16424                            if (numEmpty > emptyProcessLimit) {
16425                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16426                            }
16427                        }
16428                        break;
16429                    default:
16430                        mNumNonCachedProcs++;
16431                        break;
16432                }
16433
16434                if (app.isolated && app.services.size() <= 0) {
16435                    // If this is an isolated process, and there are no
16436                    // services running in it, then the process is no longer
16437                    // needed.  We agressively kill these because we can by
16438                    // definition not re-use the same process again, and it is
16439                    // good to avoid having whatever code was running in them
16440                    // left sitting around after no longer needed.
16441                    killUnneededProcessLocked(app, "isolated not needed");
16442                }
16443
16444                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16445                        && !app.killedByAm) {
16446                    numTrimming++;
16447                }
16448            }
16449        }
16450
16451        mNumServiceProcs = mNewNumServiceProcs;
16452
16453        // Now determine the memory trimming level of background processes.
16454        // Unfortunately we need to start at the back of the list to do this
16455        // properly.  We only do this if the number of background apps we
16456        // are managing to keep around is less than half the maximum we desire;
16457        // if we are keeping a good number around, we'll let them use whatever
16458        // memory they want.
16459        final int numCachedAndEmpty = numCached + numEmpty;
16460        int memFactor;
16461        if (numCached <= ProcessList.TRIM_CACHED_APPS
16462                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16463            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16464                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16465            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16466                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16467            } else {
16468                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16469            }
16470        } else {
16471            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16472        }
16473        // We always allow the memory level to go up (better).  We only allow it to go
16474        // down if we are in a state where that is allowed, *and* the total number of processes
16475        // has gone down since last time.
16476        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16477                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16478                + " last=" + mLastNumProcesses);
16479        if (memFactor > mLastMemoryLevel) {
16480            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16481                memFactor = mLastMemoryLevel;
16482                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16483            }
16484        }
16485        mLastMemoryLevel = memFactor;
16486        mLastNumProcesses = mLruProcesses.size();
16487        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16488        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16489        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16490            if (mLowRamStartTime == 0) {
16491                mLowRamStartTime = now;
16492            }
16493            int step = 0;
16494            int fgTrimLevel;
16495            switch (memFactor) {
16496                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16497                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16498                    break;
16499                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16500                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16501                    break;
16502                default:
16503                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16504                    break;
16505            }
16506            int factor = numTrimming/3;
16507            int minFactor = 2;
16508            if (mHomeProcess != null) minFactor++;
16509            if (mPreviousProcess != null) minFactor++;
16510            if (factor < minFactor) factor = minFactor;
16511            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16512            for (int i=N-1; i>=0; i--) {
16513                ProcessRecord app = mLruProcesses.get(i);
16514                if (allChanged || app.procStateChanged) {
16515                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16516                    app.procStateChanged = false;
16517                }
16518                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16519                        && !app.killedByAm) {
16520                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16521                        try {
16522                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16523                                    "Trimming memory of " + app.processName
16524                                    + " to " + curLevel);
16525                            app.thread.scheduleTrimMemory(curLevel);
16526                        } catch (RemoteException e) {
16527                        }
16528                        if (false) {
16529                            // For now we won't do this; our memory trimming seems
16530                            // to be good enough at this point that destroying
16531                            // activities causes more harm than good.
16532                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16533                                    && app != mHomeProcess && app != mPreviousProcess) {
16534                                // Need to do this on its own message because the stack may not
16535                                // be in a consistent state at this point.
16536                                // For these apps we will also finish their activities
16537                                // to help them free memory.
16538                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16539                            }
16540                        }
16541                    }
16542                    app.trimMemoryLevel = curLevel;
16543                    step++;
16544                    if (step >= factor) {
16545                        step = 0;
16546                        switch (curLevel) {
16547                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16548                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16549                                break;
16550                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16551                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16552                                break;
16553                        }
16554                    }
16555                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16556                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16557                            && app.thread != null) {
16558                        try {
16559                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16560                                    "Trimming memory of heavy-weight " + app.processName
16561                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16562                            app.thread.scheduleTrimMemory(
16563                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16564                        } catch (RemoteException e) {
16565                        }
16566                    }
16567                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16568                } else {
16569                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16570                            || app.systemNoUi) && app.pendingUiClean) {
16571                        // If this application is now in the background and it
16572                        // had done UI, then give it the special trim level to
16573                        // have it free UI resources.
16574                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16575                        if (app.trimMemoryLevel < level && app.thread != null) {
16576                            try {
16577                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16578                                        "Trimming memory of bg-ui " + app.processName
16579                                        + " to " + level);
16580                                app.thread.scheduleTrimMemory(level);
16581                            } catch (RemoteException e) {
16582                            }
16583                        }
16584                        app.pendingUiClean = false;
16585                    }
16586                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16587                        try {
16588                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16589                                    "Trimming memory of fg " + app.processName
16590                                    + " to " + fgTrimLevel);
16591                            app.thread.scheduleTrimMemory(fgTrimLevel);
16592                        } catch (RemoteException e) {
16593                        }
16594                    }
16595                    app.trimMemoryLevel = fgTrimLevel;
16596                }
16597            }
16598        } else {
16599            if (mLowRamStartTime != 0) {
16600                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16601                mLowRamStartTime = 0;
16602            }
16603            for (int i=N-1; i>=0; i--) {
16604                ProcessRecord app = mLruProcesses.get(i);
16605                if (allChanged || app.procStateChanged) {
16606                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16607                    app.procStateChanged = false;
16608                }
16609                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16610                        || app.systemNoUi) && app.pendingUiClean) {
16611                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16612                            && app.thread != null) {
16613                        try {
16614                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16615                                    "Trimming memory of ui hidden " + app.processName
16616                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16617                            app.thread.scheduleTrimMemory(
16618                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16619                        } catch (RemoteException e) {
16620                        }
16621                    }
16622                    app.pendingUiClean = false;
16623                }
16624                app.trimMemoryLevel = 0;
16625            }
16626        }
16627
16628        if (mAlwaysFinishActivities) {
16629            // Need to do this on its own message because the stack may not
16630            // be in a consistent state at this point.
16631            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16632        }
16633
16634        if (allChanged) {
16635            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16636        }
16637
16638        if (mProcessStats.shouldWriteNowLocked(now)) {
16639            mHandler.post(new Runnable() {
16640                @Override public void run() {
16641                    synchronized (ActivityManagerService.this) {
16642                        mProcessStats.writeStateAsyncLocked();
16643                    }
16644                }
16645            });
16646        }
16647
16648        if (DEBUG_OOM_ADJ) {
16649            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16650        }
16651    }
16652
16653    final void trimApplications() {
16654        synchronized (this) {
16655            int i;
16656
16657            // First remove any unused application processes whose package
16658            // has been removed.
16659            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16660                final ProcessRecord app = mRemovedProcesses.get(i);
16661                if (app.activities.size() == 0
16662                        && app.curReceiver == null && app.services.size() == 0) {
16663                    Slog.i(
16664                        TAG, "Exiting empty application process "
16665                        + app.processName + " ("
16666                        + (app.thread != null ? app.thread.asBinder() : null)
16667                        + ")\n");
16668                    if (app.pid > 0 && app.pid != MY_PID) {
16669                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16670                                app.processName, app.setAdj, "empty");
16671                        app.killedByAm = true;
16672                        Process.killProcessQuiet(app.pid);
16673                    } else {
16674                        try {
16675                            app.thread.scheduleExit();
16676                        } catch (Exception e) {
16677                            // Ignore exceptions.
16678                        }
16679                    }
16680                    cleanUpApplicationRecordLocked(app, false, true, -1);
16681                    mRemovedProcesses.remove(i);
16682
16683                    if (app.persistent) {
16684                        addAppLocked(app.info, false, null /* ABI override */);
16685                    }
16686                }
16687            }
16688
16689            // Now update the oom adj for all processes.
16690            updateOomAdjLocked();
16691        }
16692    }
16693
16694    /** This method sends the specified signal to each of the persistent apps */
16695    public void signalPersistentProcesses(int sig) throws RemoteException {
16696        if (sig != Process.SIGNAL_USR1) {
16697            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16698        }
16699
16700        synchronized (this) {
16701            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16702                    != PackageManager.PERMISSION_GRANTED) {
16703                throw new SecurityException("Requires permission "
16704                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16705            }
16706
16707            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16708                ProcessRecord r = mLruProcesses.get(i);
16709                if (r.thread != null && r.persistent) {
16710                    Process.sendSignal(r.pid, sig);
16711                }
16712            }
16713        }
16714    }
16715
16716    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16717        if (proc == null || proc == mProfileProc) {
16718            proc = mProfileProc;
16719            path = mProfileFile;
16720            profileType = mProfileType;
16721            clearProfilerLocked();
16722        }
16723        if (proc == null) {
16724            return;
16725        }
16726        try {
16727            proc.thread.profilerControl(false, path, null, profileType);
16728        } catch (RemoteException e) {
16729            throw new IllegalStateException("Process disappeared");
16730        }
16731    }
16732
16733    private void clearProfilerLocked() {
16734        if (mProfileFd != null) {
16735            try {
16736                mProfileFd.close();
16737            } catch (IOException e) {
16738            }
16739        }
16740        mProfileApp = null;
16741        mProfileProc = null;
16742        mProfileFile = null;
16743        mProfileType = 0;
16744        mAutoStopProfiler = false;
16745    }
16746
16747    public boolean profileControl(String process, int userId, boolean start,
16748            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16749
16750        try {
16751            synchronized (this) {
16752                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16753                // its own permission.
16754                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16755                        != PackageManager.PERMISSION_GRANTED) {
16756                    throw new SecurityException("Requires permission "
16757                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16758                }
16759
16760                if (start && fd == null) {
16761                    throw new IllegalArgumentException("null fd");
16762                }
16763
16764                ProcessRecord proc = null;
16765                if (process != null) {
16766                    proc = findProcessLocked(process, userId, "profileControl");
16767                }
16768
16769                if (start && (proc == null || proc.thread == null)) {
16770                    throw new IllegalArgumentException("Unknown process: " + process);
16771                }
16772
16773                if (start) {
16774                    stopProfilerLocked(null, null, 0);
16775                    setProfileApp(proc.info, proc.processName, path, fd, false);
16776                    mProfileProc = proc;
16777                    mProfileType = profileType;
16778                    try {
16779                        fd = fd.dup();
16780                    } catch (IOException e) {
16781                        fd = null;
16782                    }
16783                    proc.thread.profilerControl(start, path, fd, profileType);
16784                    fd = null;
16785                    mProfileFd = null;
16786                } else {
16787                    stopProfilerLocked(proc, path, profileType);
16788                    if (fd != null) {
16789                        try {
16790                            fd.close();
16791                        } catch (IOException e) {
16792                        }
16793                    }
16794                }
16795
16796                return true;
16797            }
16798        } catch (RemoteException e) {
16799            throw new IllegalStateException("Process disappeared");
16800        } finally {
16801            if (fd != null) {
16802                try {
16803                    fd.close();
16804                } catch (IOException e) {
16805                }
16806            }
16807        }
16808    }
16809
16810    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16811        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16812                userId, true, ALLOW_FULL_ONLY, callName, null);
16813        ProcessRecord proc = null;
16814        try {
16815            int pid = Integer.parseInt(process);
16816            synchronized (mPidsSelfLocked) {
16817                proc = mPidsSelfLocked.get(pid);
16818            }
16819        } catch (NumberFormatException e) {
16820        }
16821
16822        if (proc == null) {
16823            ArrayMap<String, SparseArray<ProcessRecord>> all
16824                    = mProcessNames.getMap();
16825            SparseArray<ProcessRecord> procs = all.get(process);
16826            if (procs != null && procs.size() > 0) {
16827                proc = procs.valueAt(0);
16828                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16829                    for (int i=1; i<procs.size(); i++) {
16830                        ProcessRecord thisProc = procs.valueAt(i);
16831                        if (thisProc.userId == userId) {
16832                            proc = thisProc;
16833                            break;
16834                        }
16835                    }
16836                }
16837            }
16838        }
16839
16840        return proc;
16841    }
16842
16843    public boolean dumpHeap(String process, int userId, boolean managed,
16844            String path, ParcelFileDescriptor fd) throws RemoteException {
16845
16846        try {
16847            synchronized (this) {
16848                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16849                // its own permission (same as profileControl).
16850                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16851                        != PackageManager.PERMISSION_GRANTED) {
16852                    throw new SecurityException("Requires permission "
16853                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16854                }
16855
16856                if (fd == null) {
16857                    throw new IllegalArgumentException("null fd");
16858                }
16859
16860                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16861                if (proc == null || proc.thread == null) {
16862                    throw new IllegalArgumentException("Unknown process: " + process);
16863                }
16864
16865                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16866                if (!isDebuggable) {
16867                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16868                        throw new SecurityException("Process not debuggable: " + proc);
16869                    }
16870                }
16871
16872                proc.thread.dumpHeap(managed, path, fd);
16873                fd = null;
16874                return true;
16875            }
16876        } catch (RemoteException e) {
16877            throw new IllegalStateException("Process disappeared");
16878        } finally {
16879            if (fd != null) {
16880                try {
16881                    fd.close();
16882                } catch (IOException e) {
16883                }
16884            }
16885        }
16886    }
16887
16888    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16889    public void monitor() {
16890        synchronized (this) { }
16891    }
16892
16893    void onCoreSettingsChange(Bundle settings) {
16894        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16895            ProcessRecord processRecord = mLruProcesses.get(i);
16896            try {
16897                if (processRecord.thread != null) {
16898                    processRecord.thread.setCoreSettings(settings);
16899                }
16900            } catch (RemoteException re) {
16901                /* ignore */
16902            }
16903        }
16904    }
16905
16906    // Multi-user methods
16907
16908    /**
16909     * Start user, if its not already running, but don't bring it to foreground.
16910     */
16911    @Override
16912    public boolean startUserInBackground(final int userId) {
16913        return startUser(userId, /* foreground */ false);
16914    }
16915
16916    /**
16917     * Refreshes the list of users related to the current user when either a
16918     * user switch happens or when a new related user is started in the
16919     * background.
16920     */
16921    private void updateCurrentProfileIdsLocked() {
16922        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16923                mCurrentUserId, false /* enabledOnly */);
16924        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16925        for (int i = 0; i < currentProfileIds.length; i++) {
16926            currentProfileIds[i] = profiles.get(i).id;
16927        }
16928        mCurrentProfileIds = currentProfileIds;
16929
16930        synchronized (mUserProfileGroupIdsSelfLocked) {
16931            mUserProfileGroupIdsSelfLocked.clear();
16932            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
16933            for (int i = 0; i < users.size(); i++) {
16934                UserInfo user = users.get(i);
16935                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
16936                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
16937                }
16938            }
16939        }
16940    }
16941
16942    private Set getProfileIdsLocked(int userId) {
16943        Set userIds = new HashSet<Integer>();
16944        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16945                userId, false /* enabledOnly */);
16946        for (UserInfo user : profiles) {
16947            userIds.add(Integer.valueOf(user.id));
16948        }
16949        return userIds;
16950    }
16951
16952    @Override
16953    public boolean switchUser(final int userId) {
16954        return startUser(userId, /* foregound */ true);
16955    }
16956
16957    private boolean startUser(final int userId, boolean foreground) {
16958        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16959                != PackageManager.PERMISSION_GRANTED) {
16960            String msg = "Permission Denial: switchUser() from pid="
16961                    + Binder.getCallingPid()
16962                    + ", uid=" + Binder.getCallingUid()
16963                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16964            Slog.w(TAG, msg);
16965            throw new SecurityException(msg);
16966        }
16967
16968        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16969
16970        final long ident = Binder.clearCallingIdentity();
16971        try {
16972            synchronized (this) {
16973                final int oldUserId = mCurrentUserId;
16974                if (oldUserId == userId) {
16975                    return true;
16976                }
16977
16978                mStackSupervisor.setLockTaskModeLocked(null, false);
16979
16980                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16981                if (userInfo == null) {
16982                    Slog.w(TAG, "No user info for user #" + userId);
16983                    return false;
16984                }
16985
16986                if (foreground) {
16987                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16988                            R.anim.screen_user_enter);
16989                }
16990
16991                boolean needStart = false;
16992
16993                // If the user we are switching to is not currently started, then
16994                // we need to start it now.
16995                if (mStartedUsers.get(userId) == null) {
16996                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16997                    updateStartedUserArrayLocked();
16998                    needStart = true;
16999                }
17000
17001                final Integer userIdInt = Integer.valueOf(userId);
17002                mUserLru.remove(userIdInt);
17003                mUserLru.add(userIdInt);
17004
17005                if (foreground) {
17006                    mCurrentUserId = userId;
17007                    updateCurrentProfileIdsLocked();
17008                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17009                    // Once the internal notion of the active user has switched, we lock the device
17010                    // with the option to show the user switcher on the keyguard.
17011                    mWindowManager.lockNow(null);
17012                } else {
17013                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17014                    updateCurrentProfileIdsLocked();
17015                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17016                    mUserLru.remove(currentUserIdInt);
17017                    mUserLru.add(currentUserIdInt);
17018                }
17019
17020                final UserStartedState uss = mStartedUsers.get(userId);
17021
17022                // Make sure user is in the started state.  If it is currently
17023                // stopping, we need to knock that off.
17024                if (uss.mState == UserStartedState.STATE_STOPPING) {
17025                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17026                    // so we can just fairly silently bring the user back from
17027                    // the almost-dead.
17028                    uss.mState = UserStartedState.STATE_RUNNING;
17029                    updateStartedUserArrayLocked();
17030                    needStart = true;
17031                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17032                    // This means ACTION_SHUTDOWN has been sent, so we will
17033                    // need to treat this as a new boot of the user.
17034                    uss.mState = UserStartedState.STATE_BOOTING;
17035                    updateStartedUserArrayLocked();
17036                    needStart = true;
17037                }
17038
17039                if (uss.mState == UserStartedState.STATE_BOOTING) {
17040                    // Booting up a new user, need to tell system services about it.
17041                    // Note that this is on the same handler as scheduling of broadcasts,
17042                    // which is important because it needs to go first.
17043                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17044                }
17045
17046                if (foreground) {
17047                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
17048                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17049                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17050                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17051                            oldUserId, userId, uss));
17052                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17053                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17054                }
17055
17056                if (needStart) {
17057                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17058                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17059                            | Intent.FLAG_RECEIVER_FOREGROUND);
17060                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17061                    broadcastIntentLocked(null, null, intent,
17062                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17063                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17064                }
17065
17066                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17067                    if (userId != UserHandle.USER_OWNER) {
17068                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17069                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17070                        broadcastIntentLocked(null, null, intent, null,
17071                                new IIntentReceiver.Stub() {
17072                                    public void performReceive(Intent intent, int resultCode,
17073                                            String data, Bundle extras, boolean ordered,
17074                                            boolean sticky, int sendingUser) {
17075                                        userInitialized(uss, userId);
17076                                    }
17077                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17078                                true, false, MY_PID, Process.SYSTEM_UID,
17079                                userId);
17080                        uss.initializing = true;
17081                    } else {
17082                        getUserManagerLocked().makeInitialized(userInfo.id);
17083                    }
17084                }
17085
17086                if (foreground) {
17087                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17088                    if (homeInFront) {
17089                        startHomeActivityLocked(userId);
17090                    } else {
17091                        mStackSupervisor.resumeTopActivitiesLocked();
17092                    }
17093                    EventLogTags.writeAmSwitchUser(userId);
17094                    getUserManagerLocked().userForeground(userId);
17095                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17096                } else {
17097                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17098                }
17099
17100                if (needStart) {
17101                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17102                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17103                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17104                    broadcastIntentLocked(null, null, intent,
17105                            null, new IIntentReceiver.Stub() {
17106                                @Override
17107                                public void performReceive(Intent intent, int resultCode, String data,
17108                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17109                                        throws RemoteException {
17110                                }
17111                            }, 0, null, null,
17112                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17113                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17114                }
17115            }
17116        } finally {
17117            Binder.restoreCallingIdentity(ident);
17118        }
17119
17120        return true;
17121    }
17122
17123    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17124        long ident = Binder.clearCallingIdentity();
17125        try {
17126            Intent intent;
17127            if (oldUserId >= 0) {
17128                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17129                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17130                        | Intent.FLAG_RECEIVER_FOREGROUND);
17131                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
17132                broadcastIntentLocked(null, null, intent,
17133                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17134                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
17135            }
17136            if (newUserId >= 0) {
17137                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17138                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17139                        | Intent.FLAG_RECEIVER_FOREGROUND);
17140                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17141                broadcastIntentLocked(null, null, intent,
17142                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17143                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
17144                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17145                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17146                        | Intent.FLAG_RECEIVER_FOREGROUND);
17147                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17148                broadcastIntentLocked(null, null, intent,
17149                        null, null, 0, null, null,
17150                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17151                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17152            }
17153        } finally {
17154            Binder.restoreCallingIdentity(ident);
17155        }
17156    }
17157
17158    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17159            final int newUserId) {
17160        final int N = mUserSwitchObservers.beginBroadcast();
17161        if (N > 0) {
17162            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17163                int mCount = 0;
17164                @Override
17165                public void sendResult(Bundle data) throws RemoteException {
17166                    synchronized (ActivityManagerService.this) {
17167                        if (mCurUserSwitchCallback == this) {
17168                            mCount++;
17169                            if (mCount == N) {
17170                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17171                            }
17172                        }
17173                    }
17174                }
17175            };
17176            synchronized (this) {
17177                uss.switching = true;
17178                mCurUserSwitchCallback = callback;
17179            }
17180            for (int i=0; i<N; i++) {
17181                try {
17182                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17183                            newUserId, callback);
17184                } catch (RemoteException e) {
17185                }
17186            }
17187        } else {
17188            synchronized (this) {
17189                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17190            }
17191        }
17192        mUserSwitchObservers.finishBroadcast();
17193    }
17194
17195    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17196        synchronized (this) {
17197            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17198            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17199        }
17200    }
17201
17202    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17203        mCurUserSwitchCallback = null;
17204        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17205        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17206                oldUserId, newUserId, uss));
17207    }
17208
17209    void userInitialized(UserStartedState uss, int newUserId) {
17210        completeSwitchAndInitalize(uss, newUserId, true, false);
17211    }
17212
17213    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17214        completeSwitchAndInitalize(uss, newUserId, false, true);
17215    }
17216
17217    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17218            boolean clearInitializing, boolean clearSwitching) {
17219        boolean unfrozen = false;
17220        synchronized (this) {
17221            if (clearInitializing) {
17222                uss.initializing = false;
17223                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17224            }
17225            if (clearSwitching) {
17226                uss.switching = false;
17227            }
17228            if (!uss.switching && !uss.initializing) {
17229                mWindowManager.stopFreezingScreen();
17230                unfrozen = true;
17231            }
17232        }
17233        if (unfrozen) {
17234            final int N = mUserSwitchObservers.beginBroadcast();
17235            for (int i=0; i<N; i++) {
17236                try {
17237                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17238                } catch (RemoteException e) {
17239                }
17240            }
17241            mUserSwitchObservers.finishBroadcast();
17242        }
17243    }
17244
17245    void scheduleStartProfilesLocked() {
17246        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17247            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17248                    DateUtils.SECOND_IN_MILLIS);
17249        }
17250    }
17251
17252    void startProfilesLocked() {
17253        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17254        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17255                mCurrentUserId, false /* enabledOnly */);
17256        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17257        for (UserInfo user : profiles) {
17258            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17259                    && user.id != mCurrentUserId) {
17260                toStart.add(user);
17261            }
17262        }
17263        final int n = toStart.size();
17264        int i = 0;
17265        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17266            startUserInBackground(toStart.get(i).id);
17267        }
17268        if (i < n) {
17269            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17270        }
17271    }
17272
17273    void finishUserBoot(UserStartedState uss) {
17274        synchronized (this) {
17275            if (uss.mState == UserStartedState.STATE_BOOTING
17276                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17277                uss.mState = UserStartedState.STATE_RUNNING;
17278                final int userId = uss.mHandle.getIdentifier();
17279                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17280                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17281                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17282                broadcastIntentLocked(null, null, intent,
17283                        null, null, 0, null, null,
17284                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17285                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17286            }
17287        }
17288    }
17289
17290    void finishUserSwitch(UserStartedState uss) {
17291        synchronized (this) {
17292            finishUserBoot(uss);
17293
17294            startProfilesLocked();
17295
17296            int num = mUserLru.size();
17297            int i = 0;
17298            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17299                Integer oldUserId = mUserLru.get(i);
17300                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17301                if (oldUss == null) {
17302                    // Shouldn't happen, but be sane if it does.
17303                    mUserLru.remove(i);
17304                    num--;
17305                    continue;
17306                }
17307                if (oldUss.mState == UserStartedState.STATE_STOPPING
17308                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17309                    // This user is already stopping, doesn't count.
17310                    num--;
17311                    i++;
17312                    continue;
17313                }
17314                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17315                    // Owner and current can't be stopped, but count as running.
17316                    i++;
17317                    continue;
17318                }
17319                // This is a user to be stopped.
17320                stopUserLocked(oldUserId, null);
17321                num--;
17322                i++;
17323            }
17324        }
17325    }
17326
17327    @Override
17328    public int stopUser(final int userId, final IStopUserCallback callback) {
17329        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17330                != PackageManager.PERMISSION_GRANTED) {
17331            String msg = "Permission Denial: switchUser() from pid="
17332                    + Binder.getCallingPid()
17333                    + ", uid=" + Binder.getCallingUid()
17334                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17335            Slog.w(TAG, msg);
17336            throw new SecurityException(msg);
17337        }
17338        if (userId <= 0) {
17339            throw new IllegalArgumentException("Can't stop primary user " + userId);
17340        }
17341        synchronized (this) {
17342            return stopUserLocked(userId, callback);
17343        }
17344    }
17345
17346    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17347        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17348        if (mCurrentUserId == userId) {
17349            return ActivityManager.USER_OP_IS_CURRENT;
17350        }
17351
17352        final UserStartedState uss = mStartedUsers.get(userId);
17353        if (uss == null) {
17354            // User is not started, nothing to do...  but we do need to
17355            // callback if requested.
17356            if (callback != null) {
17357                mHandler.post(new Runnable() {
17358                    @Override
17359                    public void run() {
17360                        try {
17361                            callback.userStopped(userId);
17362                        } catch (RemoteException e) {
17363                        }
17364                    }
17365                });
17366            }
17367            return ActivityManager.USER_OP_SUCCESS;
17368        }
17369
17370        if (callback != null) {
17371            uss.mStopCallbacks.add(callback);
17372        }
17373
17374        if (uss.mState != UserStartedState.STATE_STOPPING
17375                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17376            uss.mState = UserStartedState.STATE_STOPPING;
17377            updateStartedUserArrayLocked();
17378
17379            long ident = Binder.clearCallingIdentity();
17380            try {
17381                // We are going to broadcast ACTION_USER_STOPPING and then
17382                // once that is done send a final ACTION_SHUTDOWN and then
17383                // stop the user.
17384                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17385                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17386                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17387                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17388                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17389                // This is the result receiver for the final shutdown broadcast.
17390                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17391                    @Override
17392                    public void performReceive(Intent intent, int resultCode, String data,
17393                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17394                        finishUserStop(uss);
17395                    }
17396                };
17397                // This is the result receiver for the initial stopping broadcast.
17398                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17399                    @Override
17400                    public void performReceive(Intent intent, int resultCode, String data,
17401                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17402                        // On to the next.
17403                        synchronized (ActivityManagerService.this) {
17404                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17405                                // Whoops, we are being started back up.  Abort, abort!
17406                                return;
17407                            }
17408                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17409                        }
17410                        mSystemServiceManager.stopUser(userId);
17411                        broadcastIntentLocked(null, null, shutdownIntent,
17412                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17413                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17414                    }
17415                };
17416                // Kick things off.
17417                broadcastIntentLocked(null, null, stoppingIntent,
17418                        null, stoppingReceiver, 0, null, null,
17419                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17420                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17421            } finally {
17422                Binder.restoreCallingIdentity(ident);
17423            }
17424        }
17425
17426        return ActivityManager.USER_OP_SUCCESS;
17427    }
17428
17429    void finishUserStop(UserStartedState uss) {
17430        final int userId = uss.mHandle.getIdentifier();
17431        boolean stopped;
17432        ArrayList<IStopUserCallback> callbacks;
17433        synchronized (this) {
17434            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17435            if (mStartedUsers.get(userId) != uss) {
17436                stopped = false;
17437            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17438                stopped = false;
17439            } else {
17440                stopped = true;
17441                // User can no longer run.
17442                mStartedUsers.remove(userId);
17443                mUserLru.remove(Integer.valueOf(userId));
17444                updateStartedUserArrayLocked();
17445
17446                // Clean up all state and processes associated with the user.
17447                // Kill all the processes for the user.
17448                forceStopUserLocked(userId, "finish user");
17449            }
17450        }
17451
17452        for (int i=0; i<callbacks.size(); i++) {
17453            try {
17454                if (stopped) callbacks.get(i).userStopped(userId);
17455                else callbacks.get(i).userStopAborted(userId);
17456            } catch (RemoteException e) {
17457            }
17458        }
17459
17460        if (stopped) {
17461            mSystemServiceManager.cleanupUser(userId);
17462            synchronized (this) {
17463                mStackSupervisor.removeUserLocked(userId);
17464            }
17465        }
17466    }
17467
17468    @Override
17469    public UserInfo getCurrentUser() {
17470        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17471                != PackageManager.PERMISSION_GRANTED) && (
17472                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17473                != PackageManager.PERMISSION_GRANTED)) {
17474            String msg = "Permission Denial: getCurrentUser() from pid="
17475                    + Binder.getCallingPid()
17476                    + ", uid=" + Binder.getCallingUid()
17477                    + " requires " + INTERACT_ACROSS_USERS;
17478            Slog.w(TAG, msg);
17479            throw new SecurityException(msg);
17480        }
17481        synchronized (this) {
17482            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17483        }
17484    }
17485
17486    int getCurrentUserIdLocked() {
17487        return mCurrentUserId;
17488    }
17489
17490    @Override
17491    public boolean isUserRunning(int userId, boolean orStopped) {
17492        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17493                != PackageManager.PERMISSION_GRANTED) {
17494            String msg = "Permission Denial: isUserRunning() from pid="
17495                    + Binder.getCallingPid()
17496                    + ", uid=" + Binder.getCallingUid()
17497                    + " requires " + INTERACT_ACROSS_USERS;
17498            Slog.w(TAG, msg);
17499            throw new SecurityException(msg);
17500        }
17501        synchronized (this) {
17502            return isUserRunningLocked(userId, orStopped);
17503        }
17504    }
17505
17506    boolean isUserRunningLocked(int userId, boolean orStopped) {
17507        UserStartedState state = mStartedUsers.get(userId);
17508        if (state == null) {
17509            return false;
17510        }
17511        if (orStopped) {
17512            return true;
17513        }
17514        return state.mState != UserStartedState.STATE_STOPPING
17515                && state.mState != UserStartedState.STATE_SHUTDOWN;
17516    }
17517
17518    @Override
17519    public int[] getRunningUserIds() {
17520        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17521                != PackageManager.PERMISSION_GRANTED) {
17522            String msg = "Permission Denial: isUserRunning() from pid="
17523                    + Binder.getCallingPid()
17524                    + ", uid=" + Binder.getCallingUid()
17525                    + " requires " + INTERACT_ACROSS_USERS;
17526            Slog.w(TAG, msg);
17527            throw new SecurityException(msg);
17528        }
17529        synchronized (this) {
17530            return mStartedUserArray;
17531        }
17532    }
17533
17534    private void updateStartedUserArrayLocked() {
17535        int num = 0;
17536        for (int i=0; i<mStartedUsers.size();  i++) {
17537            UserStartedState uss = mStartedUsers.valueAt(i);
17538            // This list does not include stopping users.
17539            if (uss.mState != UserStartedState.STATE_STOPPING
17540                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17541                num++;
17542            }
17543        }
17544        mStartedUserArray = new int[num];
17545        num = 0;
17546        for (int i=0; i<mStartedUsers.size();  i++) {
17547            UserStartedState uss = mStartedUsers.valueAt(i);
17548            if (uss.mState != UserStartedState.STATE_STOPPING
17549                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17550                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17551                num++;
17552            }
17553        }
17554    }
17555
17556    @Override
17557    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17558        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17559                != PackageManager.PERMISSION_GRANTED) {
17560            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17561                    + Binder.getCallingPid()
17562                    + ", uid=" + Binder.getCallingUid()
17563                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17564            Slog.w(TAG, msg);
17565            throw new SecurityException(msg);
17566        }
17567
17568        mUserSwitchObservers.register(observer);
17569    }
17570
17571    @Override
17572    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17573        mUserSwitchObservers.unregister(observer);
17574    }
17575
17576    private boolean userExists(int userId) {
17577        if (userId == 0) {
17578            return true;
17579        }
17580        UserManagerService ums = getUserManagerLocked();
17581        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17582    }
17583
17584    int[] getUsersLocked() {
17585        UserManagerService ums = getUserManagerLocked();
17586        return ums != null ? ums.getUserIds() : new int[] { 0 };
17587    }
17588
17589    UserManagerService getUserManagerLocked() {
17590        if (mUserManager == null) {
17591            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17592            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17593        }
17594        return mUserManager;
17595    }
17596
17597    private int applyUserId(int uid, int userId) {
17598        return UserHandle.getUid(userId, uid);
17599    }
17600
17601    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17602        if (info == null) return null;
17603        ApplicationInfo newInfo = new ApplicationInfo(info);
17604        newInfo.uid = applyUserId(info.uid, userId);
17605        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17606                + info.packageName;
17607        return newInfo;
17608    }
17609
17610    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17611        if (aInfo == null
17612                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17613            return aInfo;
17614        }
17615
17616        ActivityInfo info = new ActivityInfo(aInfo);
17617        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17618        return info;
17619    }
17620
17621    private final class LocalService extends ActivityManagerInternal {
17622        @Override
17623        public void goingToSleep() {
17624            ActivityManagerService.this.goingToSleep();
17625        }
17626
17627        @Override
17628        public void wakingUp() {
17629            ActivityManagerService.this.wakingUp();
17630        }
17631    }
17632
17633    /**
17634     * An implementation of IAppTask, that allows an app to manage its own tasks via
17635     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17636     * only the process that calls getAppTasks() can call the AppTask methods.
17637     */
17638    class AppTaskImpl extends IAppTask.Stub {
17639        private int mTaskId;
17640        private int mCallingUid;
17641
17642        public AppTaskImpl(int taskId, int callingUid) {
17643            mTaskId = taskId;
17644            mCallingUid = callingUid;
17645        }
17646
17647        @Override
17648        public void finishAndRemoveTask() {
17649            // Ensure that we are called from the same process that created this AppTask
17650            if (mCallingUid != Binder.getCallingUid()) {
17651                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17652                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17653                return;
17654            }
17655
17656            synchronized (ActivityManagerService.this) {
17657                long origId = Binder.clearCallingIdentity();
17658                try {
17659                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17660                    if (tr != null) {
17661                        // Only kill the process if we are not a new document
17662                        int flags = tr.getBaseIntent().getFlags();
17663                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17664                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17665                        removeTaskByIdLocked(mTaskId,
17666                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17667                    }
17668                } finally {
17669                    Binder.restoreCallingIdentity(origId);
17670                }
17671            }
17672        }
17673
17674        @Override
17675        public ActivityManager.RecentTaskInfo getTaskInfo() {
17676            // Ensure that we are called from the same process that created this AppTask
17677            if (mCallingUid != Binder.getCallingUid()) {
17678                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17679                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17680                return null;
17681            }
17682
17683            synchronized (ActivityManagerService.this) {
17684                long origId = Binder.clearCallingIdentity();
17685                try {
17686                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17687                    if (tr != null) {
17688                        return createRecentTaskInfoFromTaskRecord(tr);
17689                    }
17690                } finally {
17691                    Binder.restoreCallingIdentity(origId);
17692                }
17693                return null;
17694            }
17695        }
17696    }
17697}
17698